ia64/xen-unstable

changeset 10079:81ab21f76a6f

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@virtualiron.com>
author kaf24@firebug.cl.cam.ac.uk
date Wed May 17 23:47:19 2006 +0100 (2006-05-17)
parents 345464c2fd47
children 632ad28f2fd7
files xen/arch/x86/hvm/vmx/vmcs.c xen/arch/x86/hvm/vmx/vmx.c xen/include/asm-x86/hvm/vmx/vmcs.h
line diff
     1.1 --- a/xen/arch/x86/hvm/vmx/vmcs.c	Wed May 17 23:43:32 2006 +0100
     1.2 +++ b/xen/arch/x86/hvm/vmx/vmcs.c	Wed May 17 23:47:19 2006 +0100
     1.3 @@ -35,6 +35,7 @@
     1.4  #include <xen/event.h>
     1.5  #include <xen/kernel.h>
     1.6  #include <asm/shadow.h>
     1.7 +#include <xen/keyhandler.h>
     1.8  #if CONFIG_PAGING_LEVELS >= 3
     1.9  #include <asm/shadow_64.h>
    1.10  #endif
    1.11 @@ -542,6 +543,101 @@ void arch_vmx_do_launch(struct vcpu *v)
    1.12      reset_stack_and_jump(vmx_asm_do_launch);
    1.13  }
    1.14  
    1.15 +
    1.16 +/* Dump a section of VMCS */
    1.17 +static void print_section(char *header, uint32_t start, 
    1.18 +                          uint32_t end, int incr)
    1.19 +{
    1.20 +    uint32_t addr, j;
    1.21 +    unsigned long val;
    1.22 +    int code;
    1.23 +    char *fmt[4] = {"0x%04lx ", "0x%016lx ", "0x%08lx ", "0x%016lx "};
    1.24 +    char *err[4] = {"------ ", "------------------ ", 
    1.25 +                    "---------- ", "------------------ "};
    1.26 +
    1.27 +    /* Find width of the field (encoded in bits 14:13 of address) */
    1.28 +    code = (start>>13)&3;
    1.29 +
    1.30 +    if (header)
    1.31 +        printk("\t %s", header);
    1.32 +
    1.33 +    for (addr=start, j=0; addr<=end; addr+=incr, j++) {
    1.34 +
    1.35 +        if (!(j&3))
    1.36 +            printk("\n\t\t0x%08x: ", addr);
    1.37 +
    1.38 +        if (!__vmread(addr, &val))
    1.39 +            printk(fmt[code], val);
    1.40 +        else
    1.41 +            printk("%s", err[code]);
    1.42 +    }
    1.43 +
    1.44 +    printk("\n");
    1.45 +}
    1.46 +
    1.47 +/* Dump current VMCS */
    1.48 +void vmcs_dump_vcpu(void)
    1.49 +{
    1.50 +    print_section("16-bit Guest-State Fields", 0x800, 0x80e, 2);
    1.51 +    print_section("16-bit Host-State Fields", 0xc00, 0xc0c, 2);
    1.52 +    print_section("64-bit Control Fields", 0x2000, 0x2013, 1);
    1.53 +    print_section("64-bit Guest-State Fields", 0x2800, 0x2803, 1);
    1.54 +    print_section("32-bit Control Fields", 0x4000, 0x401c, 2);
    1.55 +    print_section("32-bit RO Data Fields", 0x4400, 0x440e, 2);
    1.56 +    print_section("32-bit Guest-State Fields", 0x4800, 0x482a, 2);
    1.57 +    print_section("32-bit Host-State Fields", 0x4c00, 0x4c00, 2);
    1.58 +    print_section("Natural 64-bit Control Fields", 0x6000, 0x600e, 2);
    1.59 +    print_section("64-bit RO Data Fields", 0x6400, 0x640A, 2);
    1.60 +    print_section("Natural 64-bit Guest-State Fields", 0x6800, 0x6826, 2);
    1.61 +    print_section("Natural 64-bit Host-State Fields", 0x6c00, 0x6c16, 2);
    1.62 +}
    1.63 +
    1.64 +
    1.65 +static void vmcs_dump(unsigned char ch)
    1.66 +{
    1.67 +    struct domain *d;
    1.68 +    struct vcpu *v;
    1.69 +    
    1.70 +    printk("*********** VMCS Areas **************\n");
    1.71 +    for_each_domain(d) {
    1.72 +        printk("\n>>> Domain %d <<<\n", d->domain_id);
    1.73 +        for_each_vcpu(d, v) {
    1.74 +
    1.75 +            /* 
    1.76 +             * Presumably, if a domain is not an HVM guest,
    1.77 +             * the very first CPU will not pass this test
    1.78 +             */
    1.79 +            if (!hvm_guest(v)) {
    1.80 +                printk("\t\tNot HVM guest\n");
    1.81 +                break;
    1.82 +            }
    1.83 +            printk("\tVCPU %d\n", v->vcpu_id);
    1.84 +
    1.85 +            if (v != current) {
    1.86 +                vcpu_pause(v);
    1.87 +                __vmptrld(virt_to_maddr(v->arch.hvm_vmx.vmcs));
    1.88 +            }
    1.89 +
    1.90 +            vmcs_dump_vcpu();
    1.91 +
    1.92 +            if (v != current) {
    1.93 +                __vmptrld(virt_to_maddr(current->arch.hvm_vmx.vmcs));
    1.94 +                vcpu_unpause(v);
    1.95 +            }
    1.96 +        }
    1.97 +    }
    1.98 +
    1.99 +    printk("**************************************\n");
   1.100 +}
   1.101 +
   1.102 +static int __init setup_vmcs_dump(void)
   1.103 +{
   1.104 +    register_keyhandler('v', vmcs_dump, "dump Intel's VMCS");
   1.105 +    return 0;
   1.106 +}
   1.107 +
   1.108 +__initcall(setup_vmcs_dump);
   1.109 +
   1.110  /*
   1.111   * Local variables:
   1.112   * mode: C
     2.1 --- a/xen/arch/x86/hvm/vmx/vmx.c	Wed May 17 23:43:32 2006 +0100
     2.2 +++ b/xen/arch/x86/hvm/vmx/vmx.c	Wed May 17 23:47:19 2006 +0100
     2.3 @@ -2082,7 +2082,10 @@ asmlinkage void vmx_vmexit_handler(struc
     2.4          HVM_DBG_LOG(DBG_LEVEL_0, "exit reason = %x", exit_reason);
     2.5  
     2.6      if (exit_reason & VMX_EXIT_REASONS_FAILED_VMENTRY) {
     2.7 -        printk("Failed vm entry\n");
     2.8 +        printk("Failed vm entry (reason 0x%x)\n", exit_reason);
     2.9 +        printk("*********** VMCS Area **************\n");
    2.10 +        vmcs_dump_vcpu();
    2.11 +        printk("**************************************\n");
    2.12          domain_crash_synchronous();
    2.13          return;
    2.14      }
     3.1 --- a/xen/include/asm-x86/hvm/vmx/vmcs.h	Wed May 17 23:43:32 2006 +0100
     3.2 +++ b/xen/include/asm-x86/hvm/vmx/vmcs.h	Wed May 17 23:47:19 2006 +0100
     3.3 @@ -26,7 +26,7 @@
     3.4  
     3.5  extern int start_vmx(void);
     3.6  extern void stop_vmx(void);
     3.7 -
     3.8 +extern void vmcs_dump_vcpu(void);
     3.9  void vmx_final_setup_guest(struct vcpu *v);
    3.10  
    3.11  void vmx_enter_scheduler(void);