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

[Xen-changelog] [xen-unstable] dom0 state dump



# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1213286109 -3600
# Node ID 6b1795ee1b19d85183e0fd19f70b09340ba41e03
# Parent  ec56331c056aea79b267ae5383a5ae09f4a37941
dom0 state dump

Since xenctx cannot (for obvious reasons) display the context of
dom0's vCPU-s, here are the beginnings of a console based mechanism to
achieve the same (useful if dom0 hangs with one or more de-scheduled
vCPU-s). The stack handling obviously needs improvement, but the
register context should come out fine in all cases.

Signed-off-by: Jan Beulich <jbeulich@xxxxxxxxxx>
---
 xen/arch/x86/traps.c         |   22 +++++++++++++
 xen/arch/x86/x86_32/traps.c  |   53 +++++++++++++++++++++++---------
 xen/arch/x86/x86_64/traps.c  |   70 +++++++++++++++++++++++++++++--------------
 xen/common/keyhandler.c      |   16 +++++++++
 xen/include/asm-ia64/bug.h   |    3 +
 xen/include/asm-x86/domain.h |    3 +
 6 files changed, 129 insertions(+), 38 deletions(-)

diff -r ec56331c056a -r 6b1795ee1b19 xen/arch/x86/traps.c
--- a/xen/arch/x86/traps.c      Thu Jun 12 16:34:25 2008 +0100
+++ b/xen/arch/x86/traps.c      Thu Jun 12 16:55:09 2008 +0100
@@ -329,6 +329,28 @@ void show_execution_state(struct cpu_use
 {
     show_registers(regs);
     show_stack(regs);
+}
+
+void vcpu_show_execution_state(struct vcpu *v)
+{
+    printk("*** Dumping Dom%d vcpu#%d state: ***\n",
+           v->domain->domain_id, v->vcpu_id);
+
+    if ( v == current )
+    {
+        show_execution_state(guest_cpu_user_regs());
+        return;
+    }
+
+    vcpu_pause(v); /* acceptably dangerous */
+
+    vcpu_show_registers(v);
+    /* Todo: map arbitrary vcpu's top guest stack page here. */
+    if ( (v->domain == current->domain) &&
+         guest_kernel_mode(v, &v->arch.guest_context.user_regs) )
+        show_guest_stack(&v->arch.guest_context.user_regs);
+
+    vcpu_unpause(v);
 }
 
 char *trapstr(int trapnr)
diff -r ec56331c056a -r 6b1795ee1b19 xen/arch/x86/x86_32/traps.c
--- a/xen/arch/x86/x86_32/traps.c       Thu Jun 12 16:34:25 2008 +0100
+++ b/xen/arch/x86/x86_32/traps.c       Thu Jun 12 16:55:09 2008 +0100
@@ -30,6 +30,26 @@ static void print_xen_info(void)
     printk("----[ Xen-%d.%d%s  %s  debug=%c  %s ]----\n",
            xen_major_version(), xen_minor_version(), xen_extra_version(),
            arch, debug, print_tainted(taint_str));
+}
+
+static void _show_registers(const struct cpu_user_regs *regs,
+                            unsigned long crs[8], int guest_mode,
+                            const char *context)
+{
+    printk("EIP:    %04x:[<%08x>]", regs->cs, regs->eip);
+    if ( !guest_mode )
+        print_symbol(" %s", regs->eip);
+    printk("\nEFLAGS: %08x   CONTEXT: %s\n", regs->eflags, context);
+    printk("eax: %08x   ebx: %08x   ecx: %08x   edx: %08x\n",
+           regs->eax, regs->ebx, regs->ecx, regs->edx);
+    printk("esi: %08x   edi: %08x   ebp: %08x   esp: %08x\n",
+           regs->esi, regs->edi, regs->ebp, regs->esp);
+    printk("cr0: %08lx   cr4: %08lx   cr3: %08lx   cr2: %08lx\n",
+           crs[0], crs[4], crs[3], crs[2]);
+    printk("ds: %04x   es: %04x   fs: %04x   gs: %04x   "
+           "ss: %04x   cs: %04x\n",
+           regs->ds, regs->es, regs->fs,
+           regs->gs, regs->ss, regs->cs);
 }
 
 void show_registers(struct cpu_user_regs *regs)
@@ -85,21 +105,8 @@ void show_registers(struct cpu_user_regs
     }
 
     print_xen_info();
-    printk("CPU:    %d\nEIP:    %04x:[<%08x>]",
-           smp_processor_id(), fault_regs.cs, fault_regs.eip);
-    if ( !guest_mode(regs) )
-        print_symbol(" %s", fault_regs.eip);
-    printk("\nEFLAGS: %08x   CONTEXT: %s\n", fault_regs.eflags, context);
-    printk("eax: %08x   ebx: %08x   ecx: %08x   edx: %08x\n",
-           fault_regs.eax, fault_regs.ebx, fault_regs.ecx, fault_regs.edx);
-    printk("esi: %08x   edi: %08x   ebp: %08x   esp: %08x\n",
-           fault_regs.esi, fault_regs.edi, fault_regs.ebp, fault_regs.esp);
-    printk("cr0: %08lx   cr4: %08lx   cr3: %08lx   cr2: %08lx\n",
-           fault_crs[0], fault_crs[4], fault_crs[3], fault_crs[2]);
-    printk("ds: %04x   es: %04x   fs: %04x   gs: %04x   "
-           "ss: %04x   cs: %04x\n",
-           fault_regs.ds, fault_regs.es, fault_regs.fs,
-           fault_regs.gs, fault_regs.ss, fault_regs.cs);
+    printk("CPU:    %d\n", smp_processor_id());
+    _show_registers(&fault_regs, fault_crs, guest_mode(regs), context);
 
     if ( this_cpu(ler_msr) && !guest_mode(regs) )
     {
@@ -108,6 +115,22 @@ void show_registers(struct cpu_user_regs
         rdmsr(this_cpu(ler_msr) + 1, to, hi);
         printk("ler: %08x -> %08x\n", from, to);
     }
+}
+
+void vcpu_show_registers(const struct vcpu *v)
+{
+    unsigned long crs[8];
+
+    /* No need to handle HVM for now. */
+    if ( is_hvm_vcpu(v) )
+        return;
+
+    crs[0] = v->arch.guest_context.ctrlreg[0];
+    crs[2] = v->vcpu_info->arch.cr2;
+    crs[3] = pagetable_get_paddr(v->arch.guest_table);
+    crs[4] = v->arch.guest_context.ctrlreg[4];
+
+    _show_registers(&v->arch.guest_context.user_regs, crs, 1, "guest");
 }
 
 void show_page_walk(unsigned long addr)
diff -r ec56331c056a -r 6b1795ee1b19 xen/arch/x86/x86_64/traps.c
--- a/xen/arch/x86/x86_64/traps.c       Thu Jun 12 16:34:25 2008 +0100
+++ b/xen/arch/x86/x86_64/traps.c       Thu Jun 12 16:55:09 2008 +0100
@@ -40,6 +40,33 @@ static void print_xen_info(void)
            debug, print_tainted(taint_str));
 }
 
+static void _show_registers(const struct cpu_user_regs *regs,
+                            unsigned long crs[8], int guest_mode,
+                            const char *context)
+{
+    printk("RIP:    %04x:[<%016lx>]", regs->cs, regs->rip);
+    if ( !guest_mode )
+        print_symbol(" %s", regs->rip);
+    printk("\nRFLAGS: %016lx   CONTEXT: %s\n", regs->rflags, context);
+    printk("rax: %016lx   rbx: %016lx   rcx: %016lx\n",
+           regs->rax, regs->rbx, regs->rcx);
+    printk("rdx: %016lx   rsi: %016lx   rdi: %016lx\n",
+           regs->rdx, regs->rsi, regs->rdi);
+    printk("rbp: %016lx   rsp: %016lx   r8:  %016lx\n",
+           regs->rbp, regs->rsp, regs->r8);
+    printk("r9:  %016lx   r10: %016lx   r11: %016lx\n",
+           regs->r9,  regs->r10, regs->r11);
+    printk("r12: %016lx   r13: %016lx   r14: %016lx\n",
+           regs->r12, regs->r13, regs->r14);
+    printk("r15: %016lx   cr0: %016lx   cr4: %016lx\n",
+           regs->r15, crs[0], crs[4]);
+    printk("cr3: %016lx   cr2: %016lx\n", crs[3], crs[2]);
+    printk("ds: %04x   es: %04x   fs: %04x   gs: %04x   "
+           "ss: %04x   cs: %04x\n",
+           regs->ds, regs->es, regs->fs,
+           regs->gs, regs->ss, regs->cs);
+}
+
 void show_registers(struct cpu_user_regs *regs)
 {
     struct cpu_user_regs fault_regs = *regs;
@@ -91,28 +118,8 @@ void show_registers(struct cpu_user_regs
     }
 
     print_xen_info();
-    printk("CPU:    %d\nRIP:    %04x:[<%016lx>]",
-           smp_processor_id(), fault_regs.cs, fault_regs.rip);
-    if ( !guest_mode(regs) )
-        print_symbol(" %s", fault_regs.rip);
-    printk("\nRFLAGS: %016lx   CONTEXT: %s\n", fault_regs.rflags, context);
-    printk("rax: %016lx   rbx: %016lx   rcx: %016lx\n",
-           fault_regs.rax, fault_regs.rbx, fault_regs.rcx);
-    printk("rdx: %016lx   rsi: %016lx   rdi: %016lx\n",
-           fault_regs.rdx, fault_regs.rsi, fault_regs.rdi);
-    printk("rbp: %016lx   rsp: %016lx   r8:  %016lx\n",
-           fault_regs.rbp, fault_regs.rsp, fault_regs.r8);
-    printk("r9:  %016lx   r10: %016lx   r11: %016lx\n",
-           fault_regs.r9,  fault_regs.r10, fault_regs.r11);
-    printk("r12: %016lx   r13: %016lx   r14: %016lx\n",
-           fault_regs.r12, fault_regs.r13, fault_regs.r14);
-    printk("r15: %016lx   cr0: %016lx   cr4: %016lx\n",
-           fault_regs.r15, fault_crs[0], fault_crs[4]);
-    printk("cr3: %016lx   cr2: %016lx\n", fault_crs[3], fault_crs[2]);
-    printk("ds: %04x   es: %04x   fs: %04x   gs: %04x   "
-           "ss: %04x   cs: %04x\n",
-           fault_regs.ds, fault_regs.es, fault_regs.fs,
-           fault_regs.gs, fault_regs.ss, fault_regs.cs);
+    printk("CPU:    %d\n", smp_processor_id());
+    _show_registers(&fault_regs, fault_crs, guest_mode(regs), context);
 
     if ( this_cpu(ler_msr) && !guest_mode(regs) )
     {
@@ -121,6 +128,25 @@ void show_registers(struct cpu_user_regs
         rdmsrl(this_cpu(ler_msr) + 1, to);
         printk("ler: %016lx -> %016lx\n", from, to);
     }
+}
+
+void vcpu_show_registers(const struct vcpu *v)
+{
+    const struct cpu_user_regs *regs = &v->arch.guest_context.user_regs;
+    unsigned long crs[8];
+
+    /* No need to handle HVM for now. */
+    if ( is_hvm_vcpu(v) )
+        return;
+
+    crs[0] = v->arch.guest_context.ctrlreg[0];
+    crs[2] = arch_get_cr2(v);
+    crs[3] = pagetable_get_paddr(guest_kernel_mode(v, regs) ?
+                                 v->arch.guest_table :
+                                 v->arch.guest_table_user);
+    crs[4] = v->arch.guest_context.ctrlreg[4];
+
+    _show_registers(regs, crs, 1, "guest");
 }
 
 void show_page_walk(unsigned long addr)
diff -r ec56331c056a -r 6b1795ee1b19 xen/common/keyhandler.c
--- a/xen/common/keyhandler.c   Thu Jun 12 16:34:25 2008 +0100
+++ b/xen/common/keyhandler.c   Thu Jun 12 16:55:09 2008 +0100
@@ -125,6 +125,19 @@ static void dump_registers(unsigned char
     printk("\n");
 
     console_end_sync();
+}
+
+static void dump_dom0_registers(unsigned char key)
+{
+    struct vcpu *v;
+
+    if ( dom0 == NULL )
+        return;
+
+    printk("'%c' pressed -> dumping Dom0's registers\n", key);
+
+    for_each_vcpu ( dom0, v )
+        vcpu_show_execution_state(v);
 }
 
 static void halt_machine(unsigned char key, struct cpu_user_regs *regs)
@@ -312,6 +325,9 @@ void __init initialize_keytable(void)
         'P', perfc_reset,    "reset performance counters");
 #endif
 
+    register_keyhandler(
+        '0', dump_dom0_registers, "dump Dom0 registers");
+
     register_irq_keyhandler('%', do_debug_key,   "Trap to xendbg");
 }
 
diff -r ec56331c056a -r 6b1795ee1b19 xen/include/asm-ia64/bug.h
--- a/xen/include/asm-ia64/bug.h        Thu Jun 12 16:34:25 2008 +0100
+++ b/xen/include/asm-ia64/bug.h        Thu Jun 12 16:55:09 2008 +0100
@@ -4,6 +4,7 @@
 #define BUG() __bug(__FILE__, __LINE__)
 #define WARN() __warn(__FILE__, __LINE__)
 
-#define dump_execution_state() printk("FIXME: implement ia64 
dump_execution_state()\n");
+#define dump_execution_state() printk("FIXME: implement ia64 
dump_execution_state()\n")
+#define vcpu_show_execution_state(v) printk("FIXME: implement ia64 
vcpu_show_execution_state()\n")
 
 #endif /* __IA64_BUG_H__ */
diff -r ec56331c056a -r 6b1795ee1b19 xen/include/asm-x86/domain.h
--- a/xen/include/asm-x86/domain.h      Thu Jun 12 16:34:25 2008 +0100
+++ b/xen/include/asm-x86/domain.h      Thu Jun 12 16:55:09 2008 +0100
@@ -351,6 +351,9 @@ struct arch_vcpu
 /* Continue the current hypercall via func(data) on specified cpu. */
 int continue_hypercall_on_cpu(int cpu, long (*func)(void *data), void *data);
 
+void vcpu_show_execution_state(struct vcpu *);
+void vcpu_show_registers(const struct vcpu *);
+
 /* Clean up CR4 bits that are not under guest control. */
 unsigned long pv_guest_cr4_fixup(unsigned long guest_cr4);
 

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

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