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-devel

[Xen-devel] [PATCH,RFC] dom0 state dump

To: <xen-devel@xxxxxxxxxxxxxxxxxxx>
Subject: [Xen-devel] [PATCH,RFC] dom0 state dump
From: "Jan Beulich" <jbeulich@xxxxxxxxxx>
Date: Thu, 12 Jun 2008 16:06:02 +0100
Delivery-date: Thu, 12 Jun 2008 08:06:18 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
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>

Index: 2008-06-12/xen/arch/x86/traps.c
===================================================================
--- 2008-06-12.orig/xen/arch/x86/traps.c        2008-06-12 10:58:48.000000000 
+0200
+++ 2008-06-12/xen/arch/x86/traps.c     2008-06-12 09:09:03.000000000 +0200
@@ -331,6 +331,15 @@ void show_execution_state(struct cpu_use
     show_stack(regs);
 }
 
+void vcpu_show_execution_state(struct vcpu *v)
+{
+    vcpu_show_registers(v);
+    /* XXX Should rather map the guest's top 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);
+}
+
 char *trapstr(int trapnr)
 {
     static char *strings[] = { 
Index: 2008-06-12/xen/arch/x86/x86_32/traps.c
===================================================================
--- 2008-06-12.orig/xen/arch/x86/x86_32/traps.c 2008-06-12 10:58:48.000000000 
+0200
+++ 2008-06-12/xen/arch/x86/x86_32/traps.c      2008-06-12 09:09:03.000000000 
+0200
@@ -32,6 +32,26 @@ static void print_xen_info(void)
            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)
 {
     struct cpu_user_regs fault_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) )
     {
@@ -110,6 +117,22 @@ void show_registers(struct cpu_user_regs
     }
 }
 
+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)
 {
     unsigned long pfn, mfn, cr3 = read_cr3();
Index: 2008-06-12/xen/arch/x86/x86_64/traps.c
===================================================================
--- 2008-06-12.orig/xen/arch/x86/x86_64/traps.c 2008-06-12 10:58:48.000000000 
+0200
+++ 2008-06-12/xen/arch/x86/x86_64/traps.c      2008-06-12 09:09:03.000000000 
+0200
@@ -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) )
     {
@@ -123,6 +130,25 @@ void show_registers(struct cpu_user_regs
     }
 }
 
+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)
 {
     unsigned long pfn, mfn = read_cr3() >> PAGE_SHIFT;
Index: 2008-06-12/xen/common/keyhandler.c
===================================================================
--- 2008-06-12.orig/xen/common/keyhandler.c     2008-06-12 10:58:48.000000000 
+0200
+++ 2008-06-12/xen/common/keyhandler.c  2008-06-12 11:00:00.000000000 +0200
@@ -130,6 +130,29 @@ static void dump_registers(unsigned char
     printk("\n");
 }
 
+static void dump_dom0_registers(unsigned char key)
+{
+    struct vcpu *v;
+
+    if ( !dom0 )
+        return;
+
+    printk("'%c' pressed -> dumping Dom0's registers\n", key);
+
+    for_each_vcpu ( dom0, v )
+    {
+        printk("*** Dumping Dom0 vcpu#%d state: ***\n", v->vcpu_id);
+        if ( v == current )
+            show_execution_state(guest_cpu_user_regs());
+        else
+        {
+            vcpu_pause(v);
+            vcpu_show_execution_state(v);
+            vcpu_unpause(v);
+        }
+    }
+}
+
 static void halt_machine(unsigned char key, struct cpu_user_regs *regs)
 {
     printk("'%c' pressed -> rebooting machine\n", key);
@@ -315,6 +338,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");
 }
 
Index: 2008-06-12/xen/include/asm-ia64/xenprocessor.h
===================================================================
--- 2008-06-12.orig/xen/include/asm-ia64/xenprocessor.h 2008-06-12 
10:58:48.000000000 +0200
+++ 2008-06-12/xen/include/asm-ia64/xenprocessor.h      2008-06-12 
09:09:03.000000000 +0200
@@ -250,6 +250,7 @@ typedef union {
        };
 } ia64_pkr_t;
 
-#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 // _ASM_IA64_XENPROCESSOR_H
Index: 2008-06-12/xen/include/asm-x86/domain.h
===================================================================
--- 2008-06-12.orig/xen/include/asm-x86/domain.h        2008-06-12 
10:58:48.000000000 +0200
+++ 2008-06-12/xen/include/asm-x86/domain.h     2008-06-12 09:09:03.000000000 
+0200
@@ -352,6 +352,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-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-devel] [PATCH,RFC] dom0 state dump, Jan Beulich <=