diff options
author | jhb <jhb@FreeBSD.org> | 2011-06-02 13:49:19 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2011-06-02 13:49:19 +0000 |
commit | 63af589b2ca587eebab8b8b1c05cc910d72a6a56 (patch) | |
tree | 448ce41dd1b6787fa97591eb100bfb67bfc60c95 /sys | |
parent | 31bc5dbbffce22454d760ecdba41585aaed6281b (diff) | |
download | FreeBSD-src-63af589b2ca587eebab8b8b1c05cc910d72a6a56.zip FreeBSD-src-63af589b2ca587eebab8b8b1c05cc910d72a6a56.tar.gz |
Add a 'show vmcs' DDB command to dump state about the current CPU's
current VMCS.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/amd64/vmm/intel/vmcs.c | 96 | ||||
-rw-r--r-- | sys/amd64/vmm/intel/vmcs.h | 2 | ||||
-rw-r--r-- | sys/amd64/vmm/intel/vmx.c | 2 |
3 files changed, 99 insertions, 1 deletions
diff --git a/sys/amd64/vmm/intel/vmcs.c b/sys/amd64/vmm/intel/vmcs.c index 80d45cc..8c53465 100644 --- a/sys/amd64/vmm/intel/vmcs.c +++ b/sys/amd64/vmm/intel/vmcs.c @@ -26,6 +26,8 @@ * $FreeBSD$ */ +#include "opt_ddb.h" + #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); @@ -45,6 +47,10 @@ __FBSDID("$FreeBSD$"); #include "ept.h" #include "vmx.h" +#ifdef DDB +#include <ddb/ddb.h> +#endif + static uint64_t vmcs_fix_regval(uint32_t encoding, uint64_t val) { @@ -449,3 +455,93 @@ vmcs_read(uint32_t encoding) return (val); } + +#ifdef DDB +extern int vmxon_enabled[]; + +DB_SHOW_COMMAND(vmcs, db_show_vmcs) +{ + uint64_t cur_vmcs, val; + uint32_t exit; + + if (!vmxon_enabled[curcpu]) { + db_printf("VMX not enabled\n"); + return; + } + + if (have_addr) { + db_printf("Only current VMCS supported\n"); + return; + } + + vmptrst(&cur_vmcs); + if (cur_vmcs == VMCS_INITIAL) { + db_printf("No current VM context\n"); + return; + } + db_printf("VMCS: %jx\n", cur_vmcs); + db_printf("VPID: %lu\n", vmcs_read(VMCS_VPID)); + db_printf("Activity: "); + val = vmcs_read(VMCS_GUEST_ACTIVITY); + switch (val) { + case 0: + db_printf("Active"); + break; + case 1: + db_printf("HLT"); + break; + case 2: + db_printf("Shutdown"); + break; + case 3: + db_printf("Wait for SIPI"); + break; + default: + db_printf("Unknown: %#lx", val); + } + db_printf("\n"); + exit = vmcs_read(VMCS_EXIT_REASON); + if (exit & 0x80000000) + db_printf("Entry Failure Reason: %u\n", exit & 0xffff); + else + db_printf("Exit Reason: %u\n", exit & 0xffff); + db_printf("Qualification: %#lx\n", vmcs_exit_qualification()); + db_printf("Guest Linear Address: %#lx\n", + vmcs_read(VMCS_GUEST_LINEAR_ADDRESS)); + switch (exit & 0x8000ffff) { + case EXIT_REASON_EXCEPTION: + case EXIT_REASON_EXT_INTR: + val = vmcs_read(VMCS_EXIT_INTERRUPTION_INFO); + db_printf("Interrupt Type: "); + switch (val >> 8 & 0x7) { + case 0: + db_printf("external"); + break; + case 2: + db_printf("NMI"); + break; + case 3: + db_printf("HW exception"); + break; + case 4: + db_printf("SW exception"); + break; + default: + db_printf("?? %lu", val >> 8 & 0x7); + break; + } + db_printf(" Vector: %lu", val & 0xff); + if (val & 0x800) + db_printf(" Error Code: %lx", + vmcs_read(VMCS_EXIT_INTERRUPTION_ERROR)); + db_printf("\n"); + break; + case EXIT_REASON_EPT_FAULT: + case EXIT_REASON_EPT_MISCONFIG: + db_printf("Guest Physical Address: %#lx\n", + vmcs_read(VMCS_GUEST_PHYSICAL_ADDRESS)); + break; + } + db_printf("VM-instruction error: %#lx\n", vmcs_instruction_error()); +} +#endif diff --git a/sys/amd64/vmm/intel/vmcs.h b/sys/amd64/vmm/intel/vmcs.h index 853c9c6..be2f29c 100644 --- a/sys/amd64/vmm/intel/vmcs.h +++ b/sys/amd64/vmm/intel/vmcs.h @@ -68,6 +68,8 @@ uint64_t vmcs_read(uint32_t encoding); #endif /* _KERNEL */ +#define VMCS_INITIAL 0xffffffffffffffff + #define VMCS_IDENT(encoding) ((encoding) | 0x80000000) /* * VMCS field encodings from Appendix H, Intel Architecture Manual Vol3B. diff --git a/sys/amd64/vmm/intel/vmx.c b/sys/amd64/vmm/intel/vmx.c index 44eae67..805d035 100644 --- a/sys/amd64/vmm/intel/vmx.c +++ b/sys/amd64/vmm/intel/vmx.c @@ -110,7 +110,7 @@ MALLOC_DEFINE(M_VMX, "vmx", "vmx"); extern struct pcpu __pcpu[]; -static int vmxon_enabled[MAXCPU]; +int vmxon_enabled[MAXCPU]; static char vmxon_region[MAXCPU][PAGE_SIZE] __aligned(PAGE_SIZE); static uint32_t pinbased_ctls, procbased_ctls, procbased_ctls2; |