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

[Xen-devel] [PATCH] VMCS dump



Attached is patch for HVM guests (VMX only) that prints VMCS areas for
all vcpus. A new hotkey ('v') triggers the dump.

We also print VMCS for current processor when vmenter fails.


-boris
# Add hotkey 'v' to hypervisor monitor to print VMCS areas.
# When crashing domain due failed vmenter print processor's VMCS.

Signed-off-by: Boris Ostrovsky bostrovsky@xxxxxxxxxxxxxxx

diff -r dc213d745642 xen/arch/x86/hvm/vmx/vmcs.c
--- a/xen/arch/x86/hvm/vmx/vmcs.c       Mon May 15 16:32:09 2006 +0100
+++ b/xen/arch/x86/hvm/vmx/vmcs.c       Tue May 16 14:55:51 2006 -0400
@@ -35,6 +35,7 @@
 #include <xen/event.h>
 #include <xen/kernel.h>
 #include <asm/shadow.h>
+#include <xen/keyhandler.h>
 #if CONFIG_PAGING_LEVELS >= 3
 #include <asm/shadow_64.h>
 #endif
@@ -542,6 +543,101 @@ void arch_vmx_do_launch(struct vcpu *v)
     reset_stack_and_jump(vmx_asm_do_launch);
 }
 
+
+/* Dump a section of VMCS */
+static void print_section(char *header, uint32_t start, 
+                          uint32_t end, int incr)
+{
+    uint32_t addr, j;
+    unsigned long val;
+    int code;
+    char *fmt[4] = {"0x%04lx ", "0x%016lx ", "0x%08lx ", "0x%016lx "};
+    char *err[4] = {"------ ", "------------------ ", 
+                    "---------- ", "------------------ "};
+
+    /* Find width of the field (encoded in bits 14:13 of address) */
+    code = (start>>13)&3;
+
+    if (header)
+        printk("\t %s", header);
+
+    for (addr=start, j=0; addr<=end; addr+=incr, j++) {
+
+        if (!(j&3))
+            printk("\n\t\t0x%08x: ", addr);
+
+        if (!__vmread(addr, &val))
+            printk(fmt[code], val);
+        else
+            printk("%s", err[code]);
+    }
+
+    printk("\n");
+}
+
+/* Dump current VMCS */
+void vmcs_dump_vcpu(void)
+{
+    print_section("16-bit Guest-State Fields", 0x800, 0x80e, 2);
+    print_section("16-bit Host-State Fields", 0xc00, 0xc0c, 2);
+    print_section("64-bit Control Fields", 0x2000, 0x2013, 1);
+    print_section("64-bit Guest-State Fields", 0x2800, 0x2803, 1);
+    print_section("32-bit Control Fields", 0x4000, 0x401c, 2);
+    print_section("32-bit RO Data Fields", 0x4400, 0x440e, 2);
+    print_section("32-bit Guest-State Fields", 0x4800, 0x482a, 2);
+    print_section("32-bit Host-State Fields", 0x4c00, 0x4c00, 2);
+    print_section("Natural 64-bit Control Fields", 0x6000, 0x600e, 2);
+    print_section("64-bit RO Data Fields", 0x6400, 0x640A, 2);
+    print_section("Natural 64-bit Guest-State Fields", 0x6800, 0x6826, 2);
+    print_section("Natural 64-bit Host-State Fields", 0x6c00, 0x6c16, 2);
+}
+
+
+static void vmcs_dump(unsigned char ch)
+{
+    struct domain *d;
+    struct vcpu *v;
+    
+    printk("*********** VMCS Areas **************\n");
+    for_each_domain(d) {
+        printk("\n>>> Domain %d <<<\n", d->domain_id);
+        for_each_vcpu(d, v) {
+
+            /* 
+             * Presumably, if a domain is not an HVM guest,
+             * the very first CPU will not pass this test
+             */
+            if (!hvm_guest(v)) {
+                printk("\t\tNot HVM guest\n");
+                break;
+            }
+            printk("\tVCPU %d\n", v->vcpu_id);
+
+            if (v != current) {
+                vcpu_pause(v);
+                __vmptrld(virt_to_maddr(v->arch.hvm_vmx.vmcs));
+            }
+
+            vmcs_dump_vcpu();
+
+            if (v != current) {
+                __vmptrld(virt_to_maddr(current->arch.hvm_vmx.vmcs));
+                vcpu_unpause(v);
+            }
+        }
+    }
+
+    printk("**************************************\n");
+}
+
+static int __init setup_vmcs_dump(void)
+{
+    register_keyhandler('v', vmcs_dump, "dump Intel's VMCS");
+    return 0;
+}
+
+__initcall(setup_vmcs_dump);
+
 /*
  * Local variables:
  * mode: C
diff -r dc213d745642 xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c        Mon May 15 16:32:09 2006 +0100
+++ b/xen/arch/x86/hvm/vmx/vmx.c        Tue May 16 14:55:51 2006 -0400
@@ -2082,7 +2082,10 @@ asmlinkage void vmx_vmexit_handler(struc
         HVM_DBG_LOG(DBG_LEVEL_0, "exit reason = %x", exit_reason);
 
     if (exit_reason & VMX_EXIT_REASONS_FAILED_VMENTRY) {
-        printk("Failed vm entry\n");
+        printk("Failed vm entry (reason 0x%x)\n", exit_reason);
+        printk("*********** VMCS Area **************\n");
+        vmcs_dump_vcpu();
+        printk("**************************************\n");
         domain_crash_synchronous();
         return;
     }
diff -r dc213d745642 xen/include/asm-x86/hvm/vmx/vmcs.h
--- a/xen/include/asm-x86/hvm/vmx/vmcs.h        Mon May 15 16:32:09 2006 +0100
+++ b/xen/include/asm-x86/hvm/vmx/vmcs.h        Tue May 16 14:55:51 2006 -0400
@@ -26,7 +26,7 @@
 
 extern int start_vmx(void);
 extern void stop_vmx(void);
-
+extern void vmcs_dump_vcpu(void);
 void vmx_final_setup_guest(struct vcpu *v);
 
 void vmx_enter_scheduler(void);
_______________________________________________
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®.