[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH] x86: add option to display last exception records during register dumps



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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.