A functionally similar patch will shortly be sent out for Linux.
(Applies cleanly only on top of the previously sent SYSCALL/SYSENTER
patch.)
Signed-off-by: Jan Beulich <jbeulich@xxxxxxxxxx>
Index: 2007-08-08/xen/arch/x86/traps.c
===================================================================
--- 2007-08-08.orig/xen/arch/x86/traps.c 2007-08-08 11:40:02.000000000
+0200
+++ 2007-08-08/xen/arch/x86/traps.c 2007-08-08 11:57:04.000000000 +0200
@@ -75,6 +75,8 @@ char opt_nmi[10] = "fatal";
#endif
string_param("nmi", opt_nmi);
+DEFINE_PER_CPU(u32, ler_msr);
+
/* Master table, used by CPU0. */
idt_entry_t idt_table[IDT_ENTRIES];
@@ -2051,9 +2053,12 @@ asmlinkage int do_debug(struct cpu_user_
/* Save debug status register where guest OS can peek at it */
v->arch.guest_context.debugreg[6] = condition;
+ ler_enable();
+
return do_guest_trap(TRAP_debug, regs, 0);
out:
+ ler_enable();
return EXCRET_not_a_fault;
}
Index: 2007-08-08/xen/arch/x86/x86_32/traps.c
===================================================================
--- 2007-08-08.orig/xen/arch/x86/x86_32/traps.c 2007-08-08 11:37:08.000000000
+0200
+++ 2007-08-08/xen/arch/x86/x86_32/traps.c 2007-08-08 11:57:04.000000000
+0200
@@ -18,6 +18,9 @@
#include <public/callback.h>
+static int opt_ler;
+boolean_param("ler", opt_ler);
+
static void print_xen_info(void)
{
char taint_str[TAINT_STRING_MAX_LEN];
@@ -87,6 +90,14 @@ void show_registers(struct cpu_user_regs
"ss: %04x cs: %04x\n",
fault_regs.ds, fault_regs.es, fault_regs.fs,
fault_regs.gs, fault_regs.ss, fault_regs.cs);
+ if ( this_cpu(ler_msr) && !guest_mode(regs) )
+ {
+ u32 from, to, hi;
+
+ rdmsr(this_cpu(ler_msr), from, hi);
+ rdmsr(this_cpu(ler_msr) + 1, to, hi);
+ printk("ler: %08x -> %08x\n", from, to);
+ }
}
void show_page_walk(unsigned long addr)
@@ -262,6 +273,32 @@ void __devinit percpu_traps_init(void)
(unsigned long)tss, 235, 9);
set_task_gate(TRAP_double_fault, __DOUBLEFAULT_TSS_ENTRY<<3);
+
+ if ( opt_ler ) switch ( boot_cpu_data.x86_vendor )
+ {
+ case X86_VENDOR_INTEL:
+ switch ( boot_cpu_data.x86 )
+ {
+ case 6:
+ this_cpu(ler_msr) = MSR_IA32_LASTINTFROMIP;
+ break;
+ case 15:
+ this_cpu(ler_msr) = MSR_P4_LER_FROM_LIP;
+ break;
+ }
+ break;
+ case X86_VENDOR_AMD:
+ switch ( boot_cpu_data.x86 )
+ {
+ case 6:
+ case 15:
+ case 16:
+ this_cpu(ler_msr) = MSR_IA32_LASTINTFROMIP;
+ break;
+ }
+ break;
+ }
+ ler_enable();
}
void init_int80_direct_trap(struct vcpu *v)
Index: 2007-08-08/xen/arch/x86/x86_64/traps.c
===================================================================
--- 2007-08-08.orig/xen/arch/x86/x86_64/traps.c 2007-08-08 11:37:08.000000000
+0200
+++ 2007-08-08/xen/arch/x86/x86_64/traps.c 2007-08-08 11:57:04.000000000
+0200
@@ -26,6 +26,9 @@ asmlinkage void sysenter_entry(void);
asmlinkage void compat_hypercall(void);
asmlinkage void int80_direct_trap(void);
+static int opt_ler;
+boolean_param("ler", opt_ler);
+
static void print_xen_info(void)
{
char taint_str[TAINT_STRING_MAX_LEN];
@@ -96,6 +99,14 @@ void show_registers(struct cpu_user_regs
"ss: %04x cs: %04x\n",
fault_regs.ds, fault_regs.es, fault_regs.fs,
fault_regs.gs, fault_regs.ss, fault_regs.cs);
+ if ( this_cpu(ler_msr) && !guest_mode(regs) )
+ {
+ u64 from, to;
+
+ rdmsrl(this_cpu(ler_msr), from);
+ rdmsrl(this_cpu(ler_msr) + 1, to);
+ printk("ler: %016lx -> %016lx\n", from, to);
+ }
}
void show_page_walk(unsigned long addr)
@@ -336,12 +347,23 @@ void __devinit percpu_traps_init(void)
wrmsrl(MSR_IA32_SYSENTER_ESP, (unsigned long)stack_bottom);
wrmsrl(MSR_IA32_SYSENTER_EIP, (unsigned long)sysenter_entry);
wrmsr(MSR_IA32_SYSENTER_CS, __HYPERVISOR_CS, 0);
+ if ( opt_ler ) switch ( boot_cpu_data.x86 )
+ {
+ case 6:
+ this_cpu(ler_msr) = MSR_IA32_LASTINTFROMIP;
+ break;
+ case 15:
+ this_cpu(ler_msr) = MSR_P4_LER_FROM_LIP;
+ break;
+ }
break;
case X86_VENDOR_AMD:
/* Trampoline for SYSCALL entry from compatibility mode. */
stack = (char *)L1_CACHE_ALIGN((unsigned long)stack);
wrmsrl(MSR_CSTAR, (unsigned long)stack);
stack += write_stack_trampoline(stack, stack_bottom, FLAT_USER_CS32);
+ if ( opt_ler && boot_cpu_data.x86 <= 16 )
+ this_cpu(ler_msr) = MSR_IA32_LASTINTFROMIP;
break;
default:
BUG();
@@ -350,6 +372,8 @@ void __devinit percpu_traps_init(void)
/* Common SYSCALL parameters. */
wrmsr(MSR_STAR, 0, (FLAT_RING3_CS32<<16) | __HYPERVISOR_CS);
wrmsr(MSR_SYSCALL_MASK, EF_VM|EF_RF|EF_NT|EF_DF|EF_IE|EF_TF, 0U);
+
+ ler_enable();
}
void init_int80_direct_trap(struct vcpu *v)
Index: 2007-08-08/xen/include/asm-x86/msr.h
===================================================================
--- 2007-08-08.orig/xen/include/asm-x86/msr.h 2007-08-08 11:45:33.000000000
+0200
+++ 2007-08-08/xen/include/asm-x86/msr.h 2007-08-08 11:57:04.000000000
+0200
@@ -225,6 +225,23 @@ static inline void write_efer(__u64 val)
#define MSR_IA32_LASTINTFROMIP 0x1dd
#define MSR_IA32_LASTINTTOIP 0x1de
+#ifndef __ASSEMBLY__
+
+DECLARE_PER_CPU(u32, ler_msr);
+
+static inline void ler_enable(void)
+{
+ if ( this_cpu(ler_msr) )
+ {
+ u64 debugctl;
+
+ rdmsrl(MSR_IA32_DEBUGCTLMSR, debugctl);
+ wrmsrl(MSR_IA32_DEBUGCTLMSR, debugctl | 1);
+ }
+}
+
+#endif
+
#define MSR_IA32_MC0_CTL 0x400
#define MSR_IA32_MC0_STATUS 0x401
#define MSR_IA32_MC0_ADDR 0x402
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|