WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] dom0 state dump, Xen patchbot-unstable <=