[XEN] New function dump_execution_state() displays
authorkfraser@dhcp93.uk.xensource.com <kfraser@dhcp93.uk.xensource.com>
Mon, 19 Jun 2006 12:06:10 +0000 (13:06 +0100)
committerkfraser@dhcp93.uk.xensource.com <kfraser@dhcp93.uk.xensource.com>
Mon, 19 Jun 2006 12:06:10 +0000 (13:06 +0100)
current register and stack state of local CPU.
Use this to extend the 'd' debug key to be more useful.
Signed-off-by: Keir Fraser <keir@xensource.com>
xen/arch/x86/traps.c
xen/common/keyhandler.c
xen/include/asm-x86/processor.h

index 199ad50b726d2e3dbfa709f223a91fa145610b9a..6d442ed4cade626621e9b09c02c9ed1d5f858754 100644 (file)
@@ -487,6 +487,21 @@ asmlinkage int do_invalid_op(struct cpu_user_regs *regs)
 
     if ( unlikely(!guest_mode(regs)) )
     {
+        char sig[5];
+        /* Signature (ud2; .ascii "dbg") indicates dump state and continue. */
+        if ( (__copy_from_user(sig, (char *)regs->eip, sizeof(sig)) == 0) &&
+             (memcmp(sig, "\xf\xb""dbg", sizeof(sig)) == 0) )
+        {
+            show_execution_state(regs);
+            regs->eip += sizeof(sig);
+            return EXCRET_fault_fixed;
+        }
+        printk("%02x %02x %02x %02x %02x\n",
+               (unsigned char)sig[0],
+               (unsigned char)sig[1],
+               (unsigned char)sig[2],
+               (unsigned char)sig[3],
+               (unsigned char)sig[4]);
         DEBUGGER_trap_fatal(TRAP_invalid_op, regs);
         show_execution_state(regs);
         panic("CPU%d FATAL TRAP: vector = %d (invalid opcode)\n",
index aea0f1a78715e399c66f1ea3df11beebf3d0edf8..3f286e3ae690da11b95cbe086ef3231ffea458bd 100644 (file)
@@ -87,10 +87,28 @@ static void show_handlers(unsigned char key)
                    key_table[i].desc);
 }
 
+static void __dump_execstate(void *unused)
+{
+    dump_execution_state();
+}
+
 static void dump_registers(unsigned char key, struct cpu_user_regs *regs)
 {
+    unsigned int cpu;
+
     printk("'%c' pressed -> dumping registers\n", key); 
-    show_execution_state(regs); 
+
+    /* Get local execution state out immediately, in case we get stuck. */
+    printk("\n*** Dumping CPU%d state: ***\n", smp_processor_id());
+    show_execution_state(regs);
+
+    for_each_online_cpu ( cpu )
+    {
+        if ( cpu == smp_processor_id() )
+            continue;
+        printk("\n*** Dumping CPU%d state: ***\n", cpu);
+        on_selected_cpus(cpumask_of_cpu(cpu), __dump_execstate, NULL, 1, 1);
+    }
 }
 
 static void halt_machine(unsigned char key, struct cpu_user_regs *regs)
index 75d0772fef8446c685ec4e800917abf48237317a..c6b3247763b0ffb774a87f13003ec2c8f3fb139d 100644 (file)
@@ -535,6 +535,11 @@ void show_execution_state(struct cpu_user_regs *regs);
 void show_page_walk(unsigned long addr);
 asmlinkage void fatal_trap(int trapnr, struct cpu_user_regs *regs);
 
+/* Dumps current register and stack state. */
+#define dump_execution_state()                                              \
+    /* NB. Needs interrupts enabled else we end up in fatal_trap(). */      \
+    __asm__ __volatile__ ( "pushf ; sti ; ud2 ; .ascii \"dbg\" ; popf" )
+
 extern void mtrr_ap_init(void);
 extern void mtrr_bp_init(void);