From 0ff17367418267ae0ff0c474e063f2d01a63b325 Mon Sep 17 00:00:00 2001 From: Alexander Sadovskiy Date: Tue, 11 Oct 2011 19:28:07 +0400 Subject: [PATCH 23/32] Fixes for UG and for building w/o SVM support. fixes in vmx.c, vmx_ctrl_regs.c: + now Unrestricted Guest mode works. See comments for details fixes in vmx_hw_info.c: + added some messages that helped me while debugging on different hardware fixes in Kconfig: + QUIX86 as a default instruction decoder + DEBUG_SVM depends on DEBUG_ON && SVM fixes in svm_handler.{c,h} and vmx_handler.{c,h}: + changed names of VMEXIT_* codes - some of VMX and SVM ones were conflicting (before this fix you couldn't include both vmx_handler.h and svm_handler.h) + redefined SVM exit codes as enum (it's a better way of defining constants, because #define can lead to errors that are very difficult to understand) fixes in vmm_telemetry.c: + modified v3_print_telemetry - now it uses proper function (according to cpu type) for converting exit codes to string. Also you can now build palacios w/o SVM support --- Kconfig | 7 +- palacios/include/palacios/svm_handler.h | 322 +++++++++++++++-------------- palacios/include/palacios/vmx_handler.h | 100 +++++----- palacios/src/palacios/svm_handler.c | 340 +++++++++++++++--------------- palacios/src/palacios/vmm_telemetry.c | 69 ++++--- palacios/src/palacios/vmx.c | 33 +++- palacios/src/palacios/vmx_ctrl_regs.c | 57 ++++-- palacios/src/palacios/vmx_handler.c | 132 ++++++------ palacios/src/palacios/vmx_hw_info.c | 12 +- 9 files changed, 571 insertions(+), 501 deletions(-) diff --git a/Kconfig b/Kconfig index 097a1a1..96ffa69 100644 --- a/Kconfig +++ b/Kconfig @@ -96,7 +96,7 @@ config DEBUG_INFO choice prompt "X86 decoder" - default XED + default QUIX86_DECODER config XED bool "XED decoder library" @@ -112,7 +112,8 @@ config V3_DECODER config QUIX86_DECODER bool "QUIX86 decoder" help - This selects QUIX86 decoder + This selects QUIX86 decoder. Note that other decoders make mistakes that lead to very strange + crashes of a guest (for example, unhandled EPT fault while accessing to APIC) endchoice @@ -325,7 +326,7 @@ config DEBUG_ON config DEBUG_SVM bool "AMD SVM" default n - depends on DEBUG_ON + depends on DEBUG_ON && SVM help This turns on debugging for the AMD SVM-specific code diff --git a/palacios/include/palacios/svm_handler.h b/palacios/include/palacios/svm_handler.h index 0cca1b1..c1b23cc 100644 --- a/palacios/include/palacios/svm_handler.h +++ b/palacios/include/palacios/svm_handler.h @@ -30,171 +30,177 @@ /******************************************/ /* SVM Intercept Exit Codes */ -/* AMD Arch Vol 3, Appendix C, pg 477-478 */ +/* AMD64 Architecture Programmer's */ +/* Manual Volume 2: System Programming, */ +/* Appendix C, pg 487-488 */ /******************************************/ -#define VMEXIT_CR_READ_MASK 0xfffffff0 -#define VMEXIT_CR0_READ 0x00000000 -#define VMEXIT_CR1_READ 0x00000001 -#define VMEXIT_CR2_READ 0x00000002 -#define VMEXIT_CR3_READ 0x00000003 -#define VMEXIT_CR4_READ 0x00000004 -#define VMEXIT_CR5_READ 0x00000005 -#define VMEXIT_CR6_READ 0x00000006 -#define VMEXIT_CR7_READ 0x00000007 -#define VMEXIT_CR8_READ 0x00000008 -#define VMEXIT_CR9_READ 0x00000009 -#define VMEXIT_CR10_READ 0x0000000a -#define VMEXIT_CR11_READ 0x0000000b -#define VMEXIT_CR12_READ 0x0000000c -#define VMEXIT_CR13_READ 0x0000000d -#define VMEXIT_CR14_READ 0x0000000e -#define VMEXIT_CR15_READ 0x0000000f - -#define VMEXIT_CR_WRITE_MASK 0xffffffe0 -#define VMEXIT_CR0_WRITE 0x00000010 -#define VMEXIT_CR1_WRITE 0x00000011 -#define VMEXIT_CR2_WRITE 0x00000012 -#define VMEXIT_CR3_WRITE 0x00000013 -#define VMEXIT_CR4_WRITE 0x00000014 -#define VMEXIT_CR5_WRITE 0x00000015 -#define VMEXIT_CR6_WRITE 0x00000016 -#define VMEXIT_CR7_WRITE 0x00000017 -#define VMEXIT_CR8_WRITE 0x00000018 -#define VMEXIT_CR9_WRITE 0x00000019 -#define VMEXIT_CR10_WRITE 0x0000001a -#define VMEXIT_CR11_WRITE 0x0000001b -#define VMEXIT_CR12_WRITE 0x0000001c -#define VMEXIT_CR13_WRITE 0x0000001d -#define VMEXIT_CR14_WRITE 0x0000001e -#define VMEXIT_CR15_WRITE 0x0000001f - -#define VMEXIT_DR_READ_MASK 0xffffffd0 -#define VMEXIT_DR0_READ 0x00000020 -#define VMEXIT_DR1_READ 0x00000021 -#define VMEXIT_DR2_READ 0x00000022 -#define VMEXIT_DR3_READ 0x00000023 -#define VMEXIT_DR4_READ 0x00000024 -#define VMEXIT_DR5_READ 0x00000025 -#define VMEXIT_DR6_READ 0x00000026 -#define VMEXIT_DR7_READ 0x00000027 -#define VMEXIT_DR8_READ 0x00000028 -#define VMEXIT_DR9_READ 0x00000029 -#define VMEXIT_DR10_READ 0x0000002a -#define VMEXIT_DR11_READ 0x0000002b -#define VMEXIT_DR12_READ 0x0000002c -#define VMEXIT_DR13_READ 0x0000002d -#define VMEXIT_DR14_READ 0x0000002e -#define VMEXIT_DR15_READ 0x0000002f - -#define VMEXIT_DR_WRITE_MASK 0xffffffc0 -#define VMEXIT_DR0_WRITE 0x00000030 // ? this was previously 3f -#define VMEXIT_DR1_WRITE 0x00000031 -#define VMEXIT_DR2_WRITE 0x00000032 -#define VMEXIT_DR3_WRITE 0x00000033 -#define VMEXIT_DR4_WRITE 0x00000034 -#define VMEXIT_DR5_WRITE 0x00000035 -#define VMEXIT_DR6_WRITE 0x00000036 -#define VMEXIT_DR7_WRITE 0x00000037 -#define VMEXIT_DR8_WRITE 0x00000038 -#define VMEXIT_DR9_WRITE 0x00000039 -#define VMEXIT_DR10_WRITE 0x0000003a -#define VMEXIT_DR11_WRITE 0x0000003b -#define VMEXIT_DR12_WRITE 0x0000003c -#define VMEXIT_DR13_WRITE 0x0000003d -#define VMEXIT_DR14_WRITE 0x0000003e -#define VMEXIT_DR15_WRITE 0x0000003f - -#define VMEXIT_EXCP_MASK 0xffffffa0 -#define VMEXIT_EXCP0 0x00000040 -#define VMEXIT_EXCP1 0x00000041 -#define VMEXIT_EXCP2 0x00000042 -#define VMEXIT_EXCP3 0x00000043 -#define VMEXIT_EXCP4 0x00000044 -#define VMEXIT_EXCP5 0x00000045 -#define VMEXIT_EXCP6 0x00000046 -#define VMEXIT_EXCP7 0x00000047 -#define VMEXIT_EXCP8 0x00000048 -#define VMEXIT_EXCP9 0x00000049 -#define VMEXIT_EXCP10 0x0000004a -#define VMEXIT_EXCP11 0x0000004b -#define VMEXIT_EXCP12 0x0000004c -#define VMEXIT_EXCP13 0x0000004d -#define VMEXIT_EXCP14 0x0000004e -#define VMEXIT_EXCP15 0x0000004f -#define VMEXIT_EXCP16 0x00000050 -#define VMEXIT_EXCP17 0x00000051 -#define VMEXIT_EXCP18 0x00000052 -#define VMEXIT_EXCP19 0x00000053 -#define VMEXIT_EXCP20 0x00000054 -#define VMEXIT_EXCP21 0x00000055 -#define VMEXIT_EXCP22 0x00000056 -#define VMEXIT_EXCP23 0x00000057 -#define VMEXIT_EXCP24 0x00000058 -#define VMEXIT_EXCP25 0x00000059 -#define VMEXIT_EXCP26 0x0000005a -#define VMEXIT_EXCP27 0x0000005b -#define VMEXIT_EXCP28 0x0000005c -#define VMEXIT_EXCP29 0x0000005d -#define VMEXIT_EXCP30 0x0000005e -#define VMEXIT_EXCP31 0x0000005f - - -#define VMEXIT_INTR 0x00000060 -#define VMEXIT_NMI 0x00000061 -#define VMEXIT_SMI 0x00000062 -#define VMEXIT_INIT 0x00000063 -#define VMEXIT_VINITR 0x00000064 -#define VMEXIT_CR0_SEL_WRITE 0x00000065 -#define VMEXIT_IDTR_READ 0x00000066 -#define VMEXIT_GDTR_READ 0x00000067 -#define VMEXIT_LDTR_READ 0x00000068 -#define VMEXIT_TR_READ 0x00000069 -#define VMEXIT_IDTR_WRITE 0x0000006a -#define VMEXIT_GDTR_WRITE 0x0000006b -#define VMEXIT_LDTR_WRITE 0x0000006c -#define VMEXIT_TR_WRITE 0x0000006d -#define VMEXIT_RDTSC 0x0000006e -#define VMEXIT_RDPMC 0x0000006f -#define VMEXIT_PUSHF 0x00000070 -#define VMEXIT_POPF 0x00000071 -#define VMEXIT_CPUID 0x00000072 -#define VMEXIT_RSM 0x00000073 -#define VMEXIT_IRET 0x00000074 -#define VMEXIT_SWINT 0x00000075 -#define VMEXIT_INVD 0x00000076 -#define VMEXIT_PAUSE 0x00000077 -#define VMEXIT_HLT 0x00000078 -#define VMEXIT_INVLPG 0x00000079 -#define VMEXIT_INVLPGA 0x0000007a -#define VMEXIT_IOIO 0x0000007b -#define VMEXIT_MSR 0x0000007c -#define VMEXIT_TASK_SWITCH 0x0000007d -#define VMEXIT_FERR_FREEZE 0x0000007e -#define VMEXIT_SHUTDOWN 0x0000007f -#define VMEXIT_VMRUN 0x00000080 -#define VMEXIT_VMMCALL 0x00000081 -#define VMEXIT_VMLOAD 0x00000082 -#define VMEXIT_VMSAVE 0x00000083 -#define VMEXIT_STGI 0x00000084 -#define VMEXIT_CLGI 0x00000085 -#define VMEXIT_SKINIT 0x00000086 -#define VMEXIT_RDTSCP 0x00000087 -#define VMEXIT_ICEBP 0x00000088 -#define VMEXIT_WBINVD 0x00000089 -#define VMEXIT_MONITOR 0x0000008a -#define VMEXIT_MWAIT 0x0000008b -#define VMEXIT_MWAIT_CONDITIONAL 0x0000008c - -#define VMEXIT_NPF 0x00000400 - -#define VMEXIT_INVALID_VMCB -1 +typedef enum { + SVM_VMEXIT_CR_READ_MASK = 0xfffffff0, + SVM_VMEXIT_CR_WRITE_MASK = 0xffffffe0, + SVM_VMEXIT_DR_READ_MASK = 0xffffffd0, + SVM_VMEXIT_DR_WRITE_MASK = 0xffffffc0, + SVM_VMEXIT_EXCP_MASK = 0xffffffa0 +} svm_exit_mask_t; +typedef enum { + SVM_VMEXIT_CR0_READ = 0x00000000, + SVM_VMEXIT_CR1_READ = 0x00000001, + SVM_VMEXIT_CR2_READ = 0x00000002, + SVM_VMEXIT_CR3_READ = 0x00000003, + SVM_VMEXIT_CR4_READ = 0x00000004, + SVM_VMEXIT_CR5_READ = 0x00000005, + SVM_VMEXIT_CR6_READ = 0x00000006, + SVM_VMEXIT_CR7_READ = 0x00000007, + SVM_VMEXIT_CR8_READ = 0x00000008, + SVM_VMEXIT_CR9_READ = 0x00000009, + SVM_VMEXIT_CR10_READ = 0x0000000a, + SVM_VMEXIT_CR11_READ = 0x0000000b, + SVM_VMEXIT_CR12_READ = 0x0000000c, + SVM_VMEXIT_CR13_READ = 0x0000000d, + SVM_VMEXIT_CR14_READ = 0x0000000e, + SVM_VMEXIT_CR15_READ = 0x0000000f, + + SVM_VMEXIT_CR0_WRITE = 0x00000010, + SVM_VMEXIT_CR1_WRITE = 0x00000011, + SVM_VMEXIT_CR2_WRITE = 0x00000012, + SVM_VMEXIT_CR3_WRITE = 0x00000013, + SVM_VMEXIT_CR4_WRITE = 0x00000014, + SVM_VMEXIT_CR5_WRITE = 0x00000015, + SVM_VMEXIT_CR6_WRITE = 0x00000016, + SVM_VMEXIT_CR7_WRITE = 0x00000017, + SVM_VMEXIT_CR8_WRITE = 0x00000018, + SVM_VMEXIT_CR9_WRITE = 0x00000019, + SVM_VMEXIT_CR10_WRITE = 0x0000001a, + SVM_VMEXIT_CR11_WRITE = 0x0000001b, + SVM_VMEXIT_CR12_WRITE = 0x0000001c, + SVM_VMEXIT_CR13_WRITE = 0x0000001d, + SVM_VMEXIT_CR14_WRITE = 0x0000001e, + SVM_VMEXIT_CR15_WRITE = 0x0000001f, + + SVM_VMEXIT_DR0_READ = 0x00000020, + SVM_VMEXIT_DR1_READ = 0x00000021, + SVM_VMEXIT_DR2_READ = 0x00000022, + SVM_VMEXIT_DR3_READ = 0x00000023, + SVM_VMEXIT_DR4_READ = 0x00000024, + SVM_VMEXIT_DR5_READ = 0x00000025, + SVM_VMEXIT_DR6_READ = 0x00000026, + SVM_VMEXIT_DR7_READ = 0x00000027, + SVM_VMEXIT_DR8_READ = 0x00000028, + SVM_VMEXIT_DR9_READ = 0x00000029, + SVM_VMEXIT_DR10_READ = 0x0000002a, + SVM_VMEXIT_DR11_READ = 0x0000002b, + SVM_VMEXIT_DR12_READ = 0x0000002c, + SVM_VMEXIT_DR13_READ = 0x0000002d, + SVM_VMEXIT_DR14_READ = 0x0000002e, + SVM_VMEXIT_DR15_READ = 0x0000002f, + + SVM_VMEXIT_DR0_WRITE = 0x00000030, // ? this was previously 3f + SVM_VMEXIT_DR1_WRITE = 0x00000031, + SVM_VMEXIT_DR2_WRITE = 0x00000032, + SVM_VMEXIT_DR3_WRITE = 0x00000033, + SVM_VMEXIT_DR4_WRITE = 0x00000034, + SVM_VMEXIT_DR5_WRITE = 0x00000035, + SVM_VMEXIT_DR6_WRITE = 0x00000036, + SVM_VMEXIT_DR7_WRITE = 0x00000037, + SVM_VMEXIT_DR8_WRITE = 0x00000038, + SVM_VMEXIT_DR9_WRITE = 0x00000039, + SVM_VMEXIT_DR10_WRITE = 0x0000003a, + SVM_VMEXIT_DR11_WRITE = 0x0000003b, + SVM_VMEXIT_DR12_WRITE = 0x0000003c, + SVM_VMEXIT_DR13_WRITE = 0x0000003d, + SVM_VMEXIT_DR14_WRITE = 0x0000003e, + SVM_VMEXIT_DR15_WRITE = 0x0000003f, + + SVM_VMEXIT_EXCP0 = 0x00000040, + SVM_VMEXIT_EXCP1 = 0x00000041, + SVM_VMEXIT_EXCP2 = 0x00000042, + SVM_VMEXIT_EXCP3 = 0x00000043, + SVM_VMEXIT_EXCP4 = 0x00000044, + SVM_VMEXIT_EXCP5 = 0x00000045, + SVM_VMEXIT_EXCP6 = 0x00000046, + SVM_VMEXIT_EXCP7 = 0x00000047, + SVM_VMEXIT_EXCP8 = 0x00000048, + SVM_VMEXIT_EXCP9 = 0x00000049, + SVM_VMEXIT_EXCP10 = 0x0000004a, + SVM_VMEXIT_EXCP11 = 0x0000004b, + SVM_VMEXIT_EXCP12 = 0x0000004c, + SVM_VMEXIT_EXCP13 = 0x0000004d, + SVM_VMEXIT_EXCP14 = 0x0000004e, + SVM_VMEXIT_EXCP15 = 0x0000004f, + SVM_VMEXIT_EXCP16 = 0x00000050, + SVM_VMEXIT_EXCP17 = 0x00000051, + SVM_VMEXIT_EXCP18 = 0x00000052, + SVM_VMEXIT_EXCP19 = 0x00000053, + SVM_VMEXIT_EXCP20 = 0x00000054, + SVM_VMEXIT_EXCP21 = 0x00000055, + SVM_VMEXIT_EXCP22 = 0x00000056, + SVM_VMEXIT_EXCP23 = 0x00000057, + SVM_VMEXIT_EXCP24 = 0x00000058, + SVM_VMEXIT_EXCP25 = 0x00000059, + SVM_VMEXIT_EXCP26 = 0x0000005a, + SVM_VMEXIT_EXCP27 = 0x0000005b, + SVM_VMEXIT_EXCP28 = 0x0000005c, + SVM_VMEXIT_EXCP29 = 0x0000005d, + SVM_VMEXIT_EXCP30 = 0x0000005e, + SVM_VMEXIT_EXCP31 = 0x0000005f, + + + SVM_VMEXIT_INTR = 0x00000060, + SVM_VMEXIT_NMI = 0x00000061, + SVM_VMEXIT_SMI = 0x00000062, + SVM_VMEXIT_INIT = 0x00000063, + SVM_VMEXIT_VINITR = 0x00000064, + SVM_VMEXIT_CR0_SEL_WRITE = 0x00000065, + SVM_VMEXIT_IDTR_READ = 0x00000066, + SVM_VMEXIT_GDTR_READ = 0x00000067, + SVM_VMEXIT_LDTR_READ = 0x00000068, + SVM_VMEXIT_TR_READ = 0x00000069, + SVM_VMEXIT_IDTR_WRITE = 0x0000006a, + SVM_VMEXIT_GDTR_WRITE = 0x0000006b, + SVM_VMEXIT_LDTR_WRITE = 0x0000006c, + SVM_VMEXIT_TR_WRITE = 0x0000006d, + SVM_VMEXIT_RDTSC = 0x0000006e, + SVM_VMEXIT_RDPMC = 0x0000006f, + SVM_VMEXIT_PUSHF = 0x00000070, + SVM_VMEXIT_POPF = 0x00000071, + SVM_VMEXIT_CPUID = 0x00000072, + SVM_VMEXIT_RSM = 0x00000073, + SVM_VMEXIT_IRET = 0x00000074, + SVM_VMEXIT_SWINT = 0x00000075, + SVM_VMEXIT_INVD = 0x00000076, + SVM_VMEXIT_PAUSE = 0x00000077, + SVM_VMEXIT_HLT = 0x00000078, + SVM_VMEXIT_INVLPG = 0x00000079, + SVM_VMEXIT_INVLPGA = 0x0000007a, + SVM_VMEXIT_IOIO = 0x0000007b, + SVM_VMEXIT_MSR = 0x0000007c, + SVM_VMEXIT_TASK_SWITCH = 0x0000007d, + SVM_VMEXIT_FERR_FREEZE = 0x0000007e, + SVM_VMEXIT_SHUTDOWN = 0x0000007f, + SVM_VMEXIT_VMRUN = 0x00000080, + SVM_VMEXIT_VMMCALL = 0x00000081, + SVM_VMEXIT_VMLOAD = 0x00000082, + SVM_VMEXIT_VMSAVE = 0x00000083, + SVM_VMEXIT_STGI = 0x00000084, + SVM_VMEXIT_CLGI = 0x00000085, + SVM_VMEXIT_SKINIT = 0x00000086, + SVM_VMEXIT_RDTSCP = 0x00000087, + SVM_VMEXIT_ICEBP = 0x00000088, + SVM_VMEXIT_WBINVD = 0x00000089, + SVM_VMEXIT_MONITOR = 0x0000008a, + SVM_VMEXIT_MWAIT = 0x0000008b, + SVM_VMEXIT_MWAIT_CONDITIONAL = 0x0000008c, + + SVM_VMEXIT_NPF = 0x00000400, + + SVM_VMEXIT_INVALID_VMCB = -1 +} svm_exit_t; /******************************************/ int v3_handle_svm_exit(struct guest_info * info, addr_t exit_code, addr_t exit_info1, addr_t exit_info2); -const char * vmexit_code_to_str(uint_t exit_code); +const char * v3_svm_exit_code_to_str(svm_exit_t exit_code); #endif // ! __V3VEE__ diff --git a/palacios/include/palacios/vmx_handler.h b/palacios/include/palacios/vmx_handler.h index 20561f8..66a8744 100644 --- a/palacios/include/palacios/vmx_handler.h +++ b/palacios/include/palacios/vmx_handler.h @@ -29,56 +29,56 @@ /* VMX Intercept Exit Codes */ /******************************************/ typedef enum { - VMEXIT_INFO_EXCEPTION_OR_NMI = 0, - VMEXIT_EXTERNAL_INTR = 1, - VMEXIT_TRIPLE_FAULT = 2, - VMEXIT_INIT_SIGNAL = 3, - VMEXIT_STARTUP_IPI = 4, - VMEXIT_IO_SMI = 5, - VMEXIT_OTHER_SMI = 6, - VMEXIT_INTR_WINDOW = 7, - VMEXIT_NMI_WINDOW = 8, - VMEXIT_TASK_SWITCH = 9, - VMEXIT_CPUID = 10, - VMEXIT_HLT = 12, - VMEXIT_INVD = 13, - VMEXIT_INVLPG = 14, - VMEXIT_RDPMC = 15, - VMEXIT_RDTSC = 16, - VMEXIT_RSM = 17, - VMEXIT_VMCALL = 18, - VMEXIT_VMCLEAR = 19, - VMEXIT_VMLAUNCH = 20, - VMEXIT_VMPTRLD = 21, - VMEXIT_VMPTRST = 22, - VMEXIT_VMREAD = 23, - VMEXIT_VMRESUME = 24, - VMEXIT_VMWRITE = 25, - VMEXIT_VMXOFF = 26, - VMEXIT_VMXON = 27, - VMEXIT_CR_REG_ACCESSES = 28, - VMEXIT_MOV_DR = 29, - VMEXIT_IO_INSTR = 30, - VMEXIT_RDMSR = 31, - VMEXIT_WRMSR = 32, - VMEXIT_INVALID_GUEST_STATE = 33, - VMEXIT_INVALID_MSR_LOAD = 34, - VMEXIT_MWAIT = 36, - VMEXIT_MONITOR = 39, - VMEXIT_PAUSE = 40, - VMEXIT_INVALID_MACHINE_CHECK = 41, - VMEXIT_TPR_BELOW_THRESHOLD = 43, - VMEXIT_APIC = 44, - VMEXIT_GDTR_IDTR = 46, - VMEXIT_LDTR_TR = 47, - VMEXIT_EPT_VIOLATION = 48, - VMEXIT_EPT_CONFIG = 49, - VMEXIT_INVEPT = 50, - VMEXIT_RDTSCP = 51, - VMEXIT_EXPIRED_PREEMPT_TIMER = 52, - VMEXIT_INVVPID = 53, - VMEXIT_WBINVD = 54, - VMEXIT_XSETBV = 55 + VMX_VMEXIT_INFO_EXCEPTION_OR_NMI = 0, + VMX_VMEXIT_EXTERNAL_INTR = 1, + VMX_VMEXIT_TRIPLE_FAULT = 2, + VMX_VMEXIT_INIT_SIGNAL = 3, + VMX_VMEXIT_STARTUP_IPI = 4, + VMX_VMEXIT_IO_SMI = 5, + VMX_VMEXIT_OTHER_SMI = 6, + VMX_VMEXIT_INTR_WINDOW = 7, + VMX_VMEXIT_NMI_WINDOW = 8, + VMX_VMEXIT_TASK_SWITCH = 9, + VMX_VMEXIT_CPUID = 10, + VMX_VMEXIT_HLT = 12, + VMX_VMEXIT_INVD = 13, + VMX_VMEXIT_INVLPG = 14, + VMX_VMEXIT_RDPMC = 15, + VMX_VMEXIT_RDTSC = 16, + VMX_VMEXIT_RSM = 17, + VMX_VMEXIT_VMCALL = 18, + VMX_VMEXIT_VMCLEAR = 19, + VMX_VMEXIT_VMLAUNCH = 20, + VMX_VMEXIT_VMPTRLD = 21, + VMX_VMEXIT_VMPTRST = 22, + VMX_VMEXIT_VMREAD = 23, + VMX_VMEXIT_VMRESUME = 24, + VMX_VMEXIT_VMWRITE = 25, + VMX_VMEXIT_VMXOFF = 26, + VMX_VMEXIT_VMXON = 27, + VMX_VMEXIT_CR_REG_ACCESSES = 28, + VMX_VMEXIT_MOV_DR = 29, + VMX_VMEXIT_IO_INSTR = 30, + VMX_VMEXIT_RDMSR = 31, + VMX_VMEXIT_WRMSR = 32, + VMX_VMEXIT_INVALID_GUEST_STATE = 33, + VMX_VMEXIT_INVALID_MSR_LOAD = 34, + VMX_VMEXIT_MWAIT = 36, + VMX_VMEXIT_MONITOR = 39, + VMX_VMEXIT_PAUSE = 40, + VMX_VMEXIT_INVALID_MACHINE_CHECK = 41, + VMX_VMEXIT_TPR_BELOW_THRESHOLD = 43, + VMX_VMEXIT_APIC = 44, + VMX_VMEXIT_GDTR_IDTR = 46, + VMX_VMEXIT_LDTR_TR = 47, + VMX_VMEXIT_EPT_VIOLATION = 48, + VMX_VMEXIT_EPT_CONFIG = 49, + VMX_VMEXIT_INVEPT = 50, + VMX_VMEXIT_RDTSCP = 51, + VMX_VMEXIT_EXPIRED_PREEMPT_TIMER = 52, + VMX_VMEXIT_INVVPID = 53, + VMX_VMEXIT_WBINVD = 54, + VMX_VMEXIT_XSETBV = 55 } vmx_exit_t; /* VMCS Exit QUALIFICATIONs */ diff --git a/palacios/src/palacios/svm_handler.c b/palacios/src/palacios/svm_handler.c index 1854c53..2d4a17d 100644 --- a/palacios/src/palacios/svm_handler.c +++ b/palacios/src/palacios/svm_handler.c @@ -59,7 +59,7 @@ int v3_handle_svm_exit(struct guest_info * info, addr_t exit_code, addr_t exit_i //PrintDebug("SVM Returned: Exit Code: %x\n",exit_code); switch (exit_code) { - case VMEXIT_IOIO: { + case SVM_VMEXIT_IOIO: { struct svm_io_info * io_info = (struct svm_io_info *)&(exit_info1); if (io_info->type == 0) { @@ -91,7 +91,7 @@ int v3_handle_svm_exit(struct guest_info * info, addr_t exit_code, addr_t exit_i break; } - case VMEXIT_MSR: + case SVM_VMEXIT_MSR: if (exit_info1 == 0) { if (v3_handle_msr_read(info) == -1) { @@ -108,14 +108,14 @@ int v3_handle_svm_exit(struct guest_info * info, addr_t exit_code, addr_t exit_i break; - case VMEXIT_CPUID: + case SVM_VMEXIT_CPUID: if (v3_handle_cpuid(info) == -1) { PrintError("Error handling CPUID\n"); return -1; } break; - case VMEXIT_CR0_WRITE: + case SVM_VMEXIT_CR0_WRITE: #ifdef V3_CONFIG_DEBUG_CTRL_REGS PrintDebug("CR0 Write\n"); #endif @@ -123,7 +123,7 @@ int v3_handle_svm_exit(struct guest_info * info, addr_t exit_code, addr_t exit_i return -1; } break; - case VMEXIT_CR0_READ: + case SVM_VMEXIT_CR0_READ: #ifdef V3_CONFIG_DEBUG_CTRL_REGS PrintDebug("CR0 Read\n"); #endif @@ -131,7 +131,7 @@ int v3_handle_svm_exit(struct guest_info * info, addr_t exit_code, addr_t exit_i return -1; } break; - case VMEXIT_CR3_WRITE: + case SVM_VMEXIT_CR3_WRITE: #ifdef V3_CONFIG_DEBUG_CTRL_REGS PrintDebug("CR3 Write\n"); #endif @@ -140,7 +140,7 @@ int v3_handle_svm_exit(struct guest_info * info, addr_t exit_code, addr_t exit_i } break; - case VMEXIT_CR3_READ: + case SVM_VMEXIT_CR3_READ: #ifdef V3_CONFIG_DEBUG_CTRL_REGS PrintDebug("CR3 Read\n"); #endif @@ -148,7 +148,7 @@ int v3_handle_svm_exit(struct guest_info * info, addr_t exit_code, addr_t exit_i return -1; } break; - case VMEXIT_CR4_WRITE: + case SVM_VMEXIT_CR4_WRITE: #ifdef V3_CONFIG_DEBUG_CTRL_REGS PrintDebug("CR4 Write\n"); #endif @@ -156,7 +156,7 @@ int v3_handle_svm_exit(struct guest_info * info, addr_t exit_code, addr_t exit_i return -1; } break; - case VMEXIT_CR4_READ: + case SVM_VMEXIT_CR4_READ: #ifdef V3_CONFIG_DEBUG_CTRL_REGS PrintDebug("CR4 Read\n"); #endif @@ -164,7 +164,7 @@ int v3_handle_svm_exit(struct guest_info * info, addr_t exit_code, addr_t exit_i return -1; } break; - case VMEXIT_EXCP14: { + case SVM_VMEXIT_EXCP14: { addr_t fault_addr = exit_info2; pf_error_t * error_code = (pf_error_t *)&(exit_info1); #ifdef V3_CONFIG_DEBUG_SHADOW_PAGING @@ -181,7 +181,7 @@ int v3_handle_svm_exit(struct guest_info * info, addr_t exit_code, addr_t exit_i } break; } - case VMEXIT_NPF: { + case SVM_VMEXIT_NPF: { addr_t fault_addr = exit_info2; pf_error_t * error_code = (pf_error_t *)&(exit_info1); @@ -195,7 +195,7 @@ int v3_handle_svm_exit(struct guest_info * info, addr_t exit_code, addr_t exit_i } break; } - case VMEXIT_INVLPG: + case SVM_VMEXIT_INVLPG: if (info->shdw_pg_mode == SHADOW_PAGING) { #ifdef V3_CONFIG_DEBUG_SHADOW_PAGING PrintDebug("Invlpg\n"); @@ -205,7 +205,7 @@ int v3_handle_svm_exit(struct guest_info * info, addr_t exit_code, addr_t exit_i } } break; - case VMEXIT_VMMCALL: + case SVM_VMEXIT_VMMCALL: /* * Hypercall */ @@ -220,16 +220,16 @@ int v3_handle_svm_exit(struct guest_info * info, addr_t exit_code, addr_t exit_i } break; - case VMEXIT_NMI: + case SVM_VMEXIT_NMI: // handled by interrupt dispatcher break; - case VMEXIT_INTR: + case SVM_VMEXIT_INTR: // handled by interrupt dispatch earlier break; - case VMEXIT_SMI: + case SVM_VMEXIT_SMI: // handle_svm_smi(info); // ignored for now break; - case VMEXIT_HLT: + case SVM_VMEXIT_HLT: #ifdef V3_CONFIG_DEBUG_HALT PrintDebug("Guest halted\n"); #endif @@ -237,13 +237,13 @@ int v3_handle_svm_exit(struct guest_info * info, addr_t exit_code, addr_t exit_i return -1; } break; - case VMEXIT_PAUSE: + case SVM_VMEXIT_PAUSE: // PrintDebug("Guest paused\n"); if (v3_handle_svm_pause(info) == -1) { return -1; } break; - case VMEXIT_WBINVD: + case SVM_VMEXIT_WBINVD: #ifdef V3_CONFIG_DEBUG_EMULATOR PrintDebug("WBINVD\n"); #endif @@ -251,7 +251,7 @@ int v3_handle_svm_exit(struct guest_info * info, addr_t exit_code, addr_t exit_i return -1; } break; - case VMEXIT_RDTSC: + case SVM_VMEXIT_RDTSC: #ifdef V3_CONFIG_DEBUG_TIME PrintDebug("RDTSC/RDTSCP\n"); #endif @@ -260,7 +260,7 @@ int v3_handle_svm_exit(struct guest_info * info, addr_t exit_code, addr_t exit_i return -1; } break; - case VMEXIT_RDTSCP: + case SVM_VMEXIT_RDTSCP: #ifdef V3_CONFIG_DEBUG_TIME PrintDebug("RDTSCP\n"); #endif @@ -269,7 +269,7 @@ int v3_handle_svm_exit(struct guest_info * info, addr_t exit_code, addr_t exit_i return -1; } break; - case VMEXIT_SHUTDOWN: + case SVM_VMEXIT_SHUTDOWN: PrintDebug("Guest-initiated shutdown\n"); info->vm_info->run_state = VM_STOPPED; @@ -278,7 +278,7 @@ int v3_handle_svm_exit(struct guest_info * info, addr_t exit_code, addr_t exit_i break; #ifdef V3_CONFIG_EXT_SW_INTERRUPTS - case VMEXIT_SWINT: + case SVM_VMEXIT_SWINT: #ifdef V3_CONFIG_DEBUG_EXT_SW_INTERRUPTS PrintDebug("Intercepted a software interrupt\n"); #endif @@ -297,7 +297,7 @@ int v3_handle_svm_exit(struct guest_info * info, addr_t exit_code, addr_t exit_i addr_t rip_addr; - PrintError("Unhandled SVM Exit: %s\n", vmexit_code_to_str(exit_code)); + PrintError("Unhandled SVM Exit: %s\n", v3_svm_exit_code_to_str(exit_code)); rip_addr = get_addr_linear(info, info->rip, &(info->segments.cs)); @@ -327,12 +327,12 @@ int v3_handle_svm_exit(struct guest_info * info, addr_t exit_code, addr_t exit_i #ifdef V3_CONFIG_TELEMETRY if (info->vm_info->enable_telemetry) { - v3_telemetry_end_exit(info, exit_code); + v3_telemetry_end_exit(info, exit_code); } #endif - if (exit_code == VMEXIT_INTR) { + if (exit_code == SVM_VMEXIT_INTR) { //PrintDebug("INTR ret IP = %x\n", guest_state->rip); } @@ -486,293 +486,293 @@ static const char VMEXIT_INVALID_VMCB_STR[] = "VMEXIT_INVALID_VMCB"; -const char * vmexit_code_to_str(uint_t exit_code) { +const char * v3_svm_exit_code_to_str(svm_exit_t exit_code) { switch(exit_code) { - case VMEXIT_CR0_READ: + case SVM_VMEXIT_CR0_READ: return VMEXIT_CR0_READ_STR; - case VMEXIT_CR1_READ: + case SVM_VMEXIT_CR1_READ: return VMEXIT_CR1_READ_STR; - case VMEXIT_CR2_READ: + case SVM_VMEXIT_CR2_READ: return VMEXIT_CR2_READ_STR; - case VMEXIT_CR3_READ: + case SVM_VMEXIT_CR3_READ: return VMEXIT_CR3_READ_STR; - case VMEXIT_CR4_READ: + case SVM_VMEXIT_CR4_READ: return VMEXIT_CR4_READ_STR; - case VMEXIT_CR5_READ: + case SVM_VMEXIT_CR5_READ: return VMEXIT_CR5_READ_STR; - case VMEXIT_CR6_READ: + case SVM_VMEXIT_CR6_READ: return VMEXIT_CR6_READ_STR; - case VMEXIT_CR7_READ: + case SVM_VMEXIT_CR7_READ: return VMEXIT_CR7_READ_STR; - case VMEXIT_CR8_READ: + case SVM_VMEXIT_CR8_READ: return VMEXIT_CR8_READ_STR; - case VMEXIT_CR9_READ: + case SVM_VMEXIT_CR9_READ: return VMEXIT_CR9_READ_STR; - case VMEXIT_CR10_READ: + case SVM_VMEXIT_CR10_READ: return VMEXIT_CR10_READ_STR; - case VMEXIT_CR11_READ: + case SVM_VMEXIT_CR11_READ: return VMEXIT_CR11_READ_STR; - case VMEXIT_CR12_READ: + case SVM_VMEXIT_CR12_READ: return VMEXIT_CR12_READ_STR; - case VMEXIT_CR13_READ: + case SVM_VMEXIT_CR13_READ: return VMEXIT_CR13_READ_STR; - case VMEXIT_CR14_READ: + case SVM_VMEXIT_CR14_READ: return VMEXIT_CR14_READ_STR; - case VMEXIT_CR15_READ: + case SVM_VMEXIT_CR15_READ: return VMEXIT_CR15_READ_STR; - case VMEXIT_CR0_WRITE: + case SVM_VMEXIT_CR0_WRITE: return VMEXIT_CR0_WRITE_STR; - case VMEXIT_CR1_WRITE: + case SVM_VMEXIT_CR1_WRITE: return VMEXIT_CR1_WRITE_STR; - case VMEXIT_CR2_WRITE: + case SVM_VMEXIT_CR2_WRITE: return VMEXIT_CR2_WRITE_STR; - case VMEXIT_CR3_WRITE: + case SVM_VMEXIT_CR3_WRITE: return VMEXIT_CR3_WRITE_STR; - case VMEXIT_CR4_WRITE: + case SVM_VMEXIT_CR4_WRITE: return VMEXIT_CR4_WRITE_STR; - case VMEXIT_CR5_WRITE: + case SVM_VMEXIT_CR5_WRITE: return VMEXIT_CR5_WRITE_STR; - case VMEXIT_CR6_WRITE: + case SVM_VMEXIT_CR6_WRITE: return VMEXIT_CR6_WRITE_STR; - case VMEXIT_CR7_WRITE: + case SVM_VMEXIT_CR7_WRITE: return VMEXIT_CR7_WRITE_STR; - case VMEXIT_CR8_WRITE: + case SVM_VMEXIT_CR8_WRITE: return VMEXIT_CR8_WRITE_STR; - case VMEXIT_CR9_WRITE: + case SVM_VMEXIT_CR9_WRITE: return VMEXIT_CR9_WRITE_STR; - case VMEXIT_CR10_WRITE: + case SVM_VMEXIT_CR10_WRITE: return VMEXIT_CR10_WRITE_STR; - case VMEXIT_CR11_WRITE: + case SVM_VMEXIT_CR11_WRITE: return VMEXIT_CR11_WRITE_STR; - case VMEXIT_CR12_WRITE: + case SVM_VMEXIT_CR12_WRITE: return VMEXIT_CR12_WRITE_STR; - case VMEXIT_CR13_WRITE: + case SVM_VMEXIT_CR13_WRITE: return VMEXIT_CR13_WRITE_STR; - case VMEXIT_CR14_WRITE: + case SVM_VMEXIT_CR14_WRITE: return VMEXIT_CR14_WRITE_STR; - case VMEXIT_CR15_WRITE: + case SVM_VMEXIT_CR15_WRITE: return VMEXIT_CR15_WRITE_STR; - case VMEXIT_DR0_READ: + case SVM_VMEXIT_DR0_READ: return VMEXIT_DR0_READ_STR; - case VMEXIT_DR1_READ: + case SVM_VMEXIT_DR1_READ: return VMEXIT_DR1_READ_STR; - case VMEXIT_DR2_READ: + case SVM_VMEXIT_DR2_READ: return VMEXIT_DR2_READ_STR; - case VMEXIT_DR3_READ: + case SVM_VMEXIT_DR3_READ: return VMEXIT_DR3_READ_STR; - case VMEXIT_DR4_READ: + case SVM_VMEXIT_DR4_READ: return VMEXIT_DR4_READ_STR; - case VMEXIT_DR5_READ: + case SVM_VMEXIT_DR5_READ: return VMEXIT_DR5_READ_STR; - case VMEXIT_DR6_READ: + case SVM_VMEXIT_DR6_READ: return VMEXIT_DR6_READ_STR; - case VMEXIT_DR7_READ: + case SVM_VMEXIT_DR7_READ: return VMEXIT_DR7_READ_STR; - case VMEXIT_DR8_READ: + case SVM_VMEXIT_DR8_READ: return VMEXIT_DR8_READ_STR; - case VMEXIT_DR9_READ: + case SVM_VMEXIT_DR9_READ: return VMEXIT_DR9_READ_STR; - case VMEXIT_DR10_READ: + case SVM_VMEXIT_DR10_READ: return VMEXIT_DR10_READ_STR; - case VMEXIT_DR11_READ: + case SVM_VMEXIT_DR11_READ: return VMEXIT_DR11_READ_STR; - case VMEXIT_DR12_READ: + case SVM_VMEXIT_DR12_READ: return VMEXIT_DR12_READ_STR; - case VMEXIT_DR13_READ: + case SVM_VMEXIT_DR13_READ: return VMEXIT_DR13_READ_STR; - case VMEXIT_DR14_READ: + case SVM_VMEXIT_DR14_READ: return VMEXIT_DR14_READ_STR; - case VMEXIT_DR15_READ: + case SVM_VMEXIT_DR15_READ: return VMEXIT_DR15_READ_STR; - case VMEXIT_DR0_WRITE: + case SVM_VMEXIT_DR0_WRITE: return VMEXIT_DR0_WRITE_STR; - case VMEXIT_DR1_WRITE: + case SVM_VMEXIT_DR1_WRITE: return VMEXIT_DR1_WRITE_STR; - case VMEXIT_DR2_WRITE: + case SVM_VMEXIT_DR2_WRITE: return VMEXIT_DR2_WRITE_STR; - case VMEXIT_DR3_WRITE: + case SVM_VMEXIT_DR3_WRITE: return VMEXIT_DR3_WRITE_STR; - case VMEXIT_DR4_WRITE: + case SVM_VMEXIT_DR4_WRITE: return VMEXIT_DR4_WRITE_STR; - case VMEXIT_DR5_WRITE: + case SVM_VMEXIT_DR5_WRITE: return VMEXIT_DR5_WRITE_STR; - case VMEXIT_DR6_WRITE: + case SVM_VMEXIT_DR6_WRITE: return VMEXIT_DR6_WRITE_STR; - case VMEXIT_DR7_WRITE: + case SVM_VMEXIT_DR7_WRITE: return VMEXIT_DR7_WRITE_STR; - case VMEXIT_DR8_WRITE: + case SVM_VMEXIT_DR8_WRITE: return VMEXIT_DR8_WRITE_STR; - case VMEXIT_DR9_WRITE: + case SVM_VMEXIT_DR9_WRITE: return VMEXIT_DR9_WRITE_STR; - case VMEXIT_DR10_WRITE: + case SVM_VMEXIT_DR10_WRITE: return VMEXIT_DR10_WRITE_STR; - case VMEXIT_DR11_WRITE: + case SVM_VMEXIT_DR11_WRITE: return VMEXIT_DR11_WRITE_STR; - case VMEXIT_DR12_WRITE: + case SVM_VMEXIT_DR12_WRITE: return VMEXIT_DR12_WRITE_STR; - case VMEXIT_DR13_WRITE: + case SVM_VMEXIT_DR13_WRITE: return VMEXIT_DR13_WRITE_STR; - case VMEXIT_DR14_WRITE: + case SVM_VMEXIT_DR14_WRITE: return VMEXIT_DR14_WRITE_STR; - case VMEXIT_DR15_WRITE: + case SVM_VMEXIT_DR15_WRITE: return VMEXIT_DR15_WRITE_STR; - case VMEXIT_EXCP0: + case SVM_VMEXIT_EXCP0: return VMEXIT_EXCP0_STR; - case VMEXIT_EXCP1: + case SVM_VMEXIT_EXCP1: return VMEXIT_EXCP1_STR; - case VMEXIT_EXCP2: + case SVM_VMEXIT_EXCP2: return VMEXIT_EXCP2_STR; - case VMEXIT_EXCP3: + case SVM_VMEXIT_EXCP3: return VMEXIT_EXCP3_STR; - case VMEXIT_EXCP4: + case SVM_VMEXIT_EXCP4: return VMEXIT_EXCP4_STR; - case VMEXIT_EXCP5: + case SVM_VMEXIT_EXCP5: return VMEXIT_EXCP5_STR; - case VMEXIT_EXCP6: + case SVM_VMEXIT_EXCP6: return VMEXIT_EXCP6_STR; - case VMEXIT_EXCP7: + case SVM_VMEXIT_EXCP7: return VMEXIT_EXCP7_STR; - case VMEXIT_EXCP8: + case SVM_VMEXIT_EXCP8: return VMEXIT_EXCP8_STR; - case VMEXIT_EXCP9: + case SVM_VMEXIT_EXCP9: return VMEXIT_EXCP9_STR; - case VMEXIT_EXCP10: + case SVM_VMEXIT_EXCP10: return VMEXIT_EXCP10_STR; - case VMEXIT_EXCP11: + case SVM_VMEXIT_EXCP11: return VMEXIT_EXCP11_STR; - case VMEXIT_EXCP12: + case SVM_VMEXIT_EXCP12: return VMEXIT_EXCP12_STR; - case VMEXIT_EXCP13: + case SVM_VMEXIT_EXCP13: return VMEXIT_EXCP13_STR; - case VMEXIT_EXCP14: + case SVM_VMEXIT_EXCP14: return VMEXIT_EXCP14_STR; - case VMEXIT_EXCP15: + case SVM_VMEXIT_EXCP15: return VMEXIT_EXCP15_STR; - case VMEXIT_EXCP16: + case SVM_VMEXIT_EXCP16: return VMEXIT_EXCP16_STR; - case VMEXIT_EXCP17: + case SVM_VMEXIT_EXCP17: return VMEXIT_EXCP17_STR; - case VMEXIT_EXCP18: + case SVM_VMEXIT_EXCP18: return VMEXIT_EXCP18_STR; - case VMEXIT_EXCP19: + case SVM_VMEXIT_EXCP19: return VMEXIT_EXCP19_STR; - case VMEXIT_EXCP20: + case SVM_VMEXIT_EXCP20: return VMEXIT_EXCP20_STR; - case VMEXIT_EXCP21: + case SVM_VMEXIT_EXCP21: return VMEXIT_EXCP21_STR; - case VMEXIT_EXCP22: + case SVM_VMEXIT_EXCP22: return VMEXIT_EXCP22_STR; - case VMEXIT_EXCP23: + case SVM_VMEXIT_EXCP23: return VMEXIT_EXCP23_STR; - case VMEXIT_EXCP24: + case SVM_VMEXIT_EXCP24: return VMEXIT_EXCP24_STR; - case VMEXIT_EXCP25: + case SVM_VMEXIT_EXCP25: return VMEXIT_EXCP25_STR; - case VMEXIT_EXCP26: + case SVM_VMEXIT_EXCP26: return VMEXIT_EXCP26_STR; - case VMEXIT_EXCP27: + case SVM_VMEXIT_EXCP27: return VMEXIT_EXCP27_STR; - case VMEXIT_EXCP28: + case SVM_VMEXIT_EXCP28: return VMEXIT_EXCP28_STR; - case VMEXIT_EXCP29: + case SVM_VMEXIT_EXCP29: return VMEXIT_EXCP29_STR; - case VMEXIT_EXCP30: + case SVM_VMEXIT_EXCP30: return VMEXIT_EXCP30_STR; - case VMEXIT_EXCP31: + case SVM_VMEXIT_EXCP31: return VMEXIT_EXCP31_STR; - case VMEXIT_INTR: + case SVM_VMEXIT_INTR: return VMEXIT_INTR_STR; - case VMEXIT_NMI: + case SVM_VMEXIT_NMI: return VMEXIT_NMI_STR; - case VMEXIT_SMI: + case SVM_VMEXIT_SMI: return VMEXIT_SMI_STR; - case VMEXIT_INIT: + case SVM_VMEXIT_INIT: return VMEXIT_INIT_STR; - case VMEXIT_VINITR: + case SVM_VMEXIT_VINITR: return VMEXIT_VINITR_STR; - case VMEXIT_CR0_SEL_WRITE: + case SVM_VMEXIT_CR0_SEL_WRITE: return VMEXIT_CR0_SEL_WRITE_STR; - case VMEXIT_IDTR_READ: + case SVM_VMEXIT_IDTR_READ: return VMEXIT_IDTR_READ_STR; - case VMEXIT_GDTR_READ: + case SVM_VMEXIT_GDTR_READ: return VMEXIT_GDTR_READ_STR; - case VMEXIT_LDTR_READ: + case SVM_VMEXIT_LDTR_READ: return VMEXIT_LDTR_READ_STR; - case VMEXIT_TR_READ: + case SVM_VMEXIT_TR_READ: return VMEXIT_TR_READ_STR; - case VMEXIT_IDTR_WRITE: + case SVM_VMEXIT_IDTR_WRITE: return VMEXIT_IDTR_WRITE_STR; - case VMEXIT_GDTR_WRITE: + case SVM_VMEXIT_GDTR_WRITE: return VMEXIT_GDTR_WRITE_STR; - case VMEXIT_LDTR_WRITE: + case SVM_VMEXIT_LDTR_WRITE: return VMEXIT_LDTR_WRITE_STR; - case VMEXIT_TR_WRITE: + case SVM_VMEXIT_TR_WRITE: return VMEXIT_TR_WRITE_STR; - case VMEXIT_RDTSC: + case SVM_VMEXIT_RDTSC: return VMEXIT_RDTSC_STR; - case VMEXIT_RDPMC: + case SVM_VMEXIT_RDPMC: return VMEXIT_RDPMC_STR; - case VMEXIT_PUSHF: + case SVM_VMEXIT_PUSHF: return VMEXIT_PUSHF_STR; - case VMEXIT_POPF: + case SVM_VMEXIT_POPF: return VMEXIT_POPF_STR; - case VMEXIT_CPUID: + case SVM_VMEXIT_CPUID: return VMEXIT_CPUID_STR; - case VMEXIT_RSM: + case SVM_VMEXIT_RSM: return VMEXIT_RSM_STR; - case VMEXIT_IRET: + case SVM_VMEXIT_IRET: return VMEXIT_IRET_STR; - case VMEXIT_SWINT: + case SVM_VMEXIT_SWINT: return VMEXIT_SWINT_STR; - case VMEXIT_INVD: + case SVM_VMEXIT_INVD: return VMEXIT_INVD_STR; - case VMEXIT_PAUSE: + case SVM_VMEXIT_PAUSE: return VMEXIT_PAUSE_STR; - case VMEXIT_HLT: + case SVM_VMEXIT_HLT: return VMEXIT_HLT_STR; - case VMEXIT_INVLPG: + case SVM_VMEXIT_INVLPG: return VMEXIT_INVLPG_STR; - case VMEXIT_INVLPGA: + case SVM_VMEXIT_INVLPGA: return VMEXIT_INVLPGA_STR; - case VMEXIT_IOIO: + case SVM_VMEXIT_IOIO: return VMEXIT_IOIO_STR; - case VMEXIT_MSR: + case SVM_VMEXIT_MSR: return VMEXIT_MSR_STR; - case VMEXIT_TASK_SWITCH: + case SVM_VMEXIT_TASK_SWITCH: return VMEXIT_TASK_SWITCH_STR; - case VMEXIT_FERR_FREEZE: + case SVM_VMEXIT_FERR_FREEZE: return VMEXIT_FERR_FREEZE_STR; - case VMEXIT_SHUTDOWN: + case SVM_VMEXIT_SHUTDOWN: return VMEXIT_SHUTDOWN_STR; - case VMEXIT_VMRUN: + case SVM_VMEXIT_VMRUN: return VMEXIT_VMRUN_STR; - case VMEXIT_VMMCALL: + case SVM_VMEXIT_VMMCALL: return VMEXIT_VMMCALL_STR; - case VMEXIT_VMLOAD: + case SVM_VMEXIT_VMLOAD: return VMEXIT_VMLOAD_STR; - case VMEXIT_VMSAVE: + case SVM_VMEXIT_VMSAVE: return VMEXIT_VMSAVE_STR; - case VMEXIT_STGI: + case SVM_VMEXIT_STGI: return VMEXIT_STGI_STR; - case VMEXIT_CLGI: + case SVM_VMEXIT_CLGI: return VMEXIT_CLGI_STR; - case VMEXIT_SKINIT: + case SVM_VMEXIT_SKINIT: return VMEXIT_SKINIT_STR; - case VMEXIT_RDTSCP: + case SVM_VMEXIT_RDTSCP: return VMEXIT_RDTSCP_STR; - case VMEXIT_ICEBP: + case SVM_VMEXIT_ICEBP: return VMEXIT_ICEBP_STR; - case VMEXIT_WBINVD: + case SVM_VMEXIT_WBINVD: return VMEXIT_WBINVD_STR; - case VMEXIT_MONITOR: + case SVM_VMEXIT_MONITOR: return VMEXIT_MONITOR_STR; - case VMEXIT_MWAIT: + case SVM_VMEXIT_MWAIT: return VMEXIT_MWAIT_STR; - case VMEXIT_MWAIT_CONDITIONAL: + case SVM_VMEXIT_MWAIT_CONDITIONAL: return VMEXIT_MWAIT_CONDITIONAL_STR; - case VMEXIT_NPF: + case SVM_VMEXIT_NPF: return VMEXIT_NPF_STR; - case VMEXIT_INVALID_VMCB: + case SVM_VMEXIT_INVALID_VMCB: return VMEXIT_INVALID_VMCB_STR; } return NULL; diff --git a/palacios/src/palacios/vmm_telemetry.c b/palacios/src/palacios/vmm_telemetry.c index 42e7822..ad4a7d0 100644 --- a/palacios/src/palacios/vmm_telemetry.c +++ b/palacios/src/palacios/vmm_telemetry.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -30,7 +31,7 @@ #define DEFAULT_GRANULARITY 50000 #endif - +extern v3_cpu_arch_t v3_cpu_types[]; struct telemetry_cb { @@ -243,34 +244,52 @@ void v3_print_telemetry(struct v3_vm_info * vm) { snprintf(hdr_buf, 32, "telem.%d>", telemetry->invoke_cnt++); - V3_Print("%stelemetry window tsc cnt: %d\n", hdr_buf, (uint32_t)(invoke_tsc - telemetry->prev_tsc)); + V3_Print("%stelemetry window tsc cnt: %u\n", hdr_buf, (uint32_t)(invoke_tsc - telemetry->prev_tsc)); // Exit Telemetry for (i = 0; i < vm->num_cores; i++) { - struct guest_info * core = &(vm->cores[i]); - struct exit_event * evt = NULL; - struct rb_node * node = v3_rb_first(&(core->core_telem.exit_root)); - - V3_Print("Exit information for Core %d\n", core->vcpu_id); - - if (!node) { - V3_Print("No information yet for this core\n"); - continue; - } - - do { - evt = rb_entry(node, struct exit_event, tree_node); - const char * code_str = vmexit_code_to_str(evt->exit_code); - - V3_Print("%s%s:%sCnt=%u,%sAvg. Time=%u\n", - hdr_buf, - code_str, - (strlen(code_str) > 13) ? "\t" : "\t\t", - evt->cnt, - (evt->cnt >= 100) ? "\t" : "\t\t", - (uint32_t)(evt->handler_time / evt->cnt)); - } while ((node = v3_rb_next(node))); + struct guest_info * core = &(vm->cores[i]); + struct exit_event * evt = NULL; + struct rb_node * node = v3_rb_first(&(core->core_telem.exit_root)); + v3_cpu_arch_t core_type = v3_cpu_types[core->pcpu_id]; + + V3_Print("Exit information for Core %d\n", core->vcpu_id); + + if (!node) { + V3_Print("No information yet for this core\n"); + continue; + } + + do { + evt = rb_entry(node, struct exit_event, tree_node); + const char * code_str; + switch(core_type) { + #ifdef V3_CONFIG_SVM + case V3_SVM_CPU: + case V3_SVM_REV3_CPU: + code_str = v3_svm_exit_code_to_str((svm_exit_t)(evt->exit_code)); + break; + #endif + #ifdef V3_CONFIG_VMX + case V3_VMX_CPU: + case V3_VMX_EPT_CPU: + case V3_VMX_EPT_UG_CPU: + code_str = v3_vmx_exit_code_to_str((vmx_exit_t)(evt->exit_code)); + break; + #endif + default: + code_str = NULL; + } + + V3_Print("%s%s:%sCnt=%u,%sAvg. Time=%u\n", + hdr_buf, + code_str, + (strlen(code_str) > 13) ? "\t" : "\t\t", + evt->cnt, + (evt->cnt >= 100) ? "\t" : "\t\t", + (uint32_t)(evt->handler_time / evt->cnt)); + } while ((node = v3_rb_next(node))); } diff --git a/palacios/src/palacios/vmx.c b/palacios/src/palacios/vmx.c index b592f15..8b080e3 100644 --- a/palacios/src/palacios/vmx.c +++ b/palacios/src/palacios/vmx.c @@ -304,12 +304,22 @@ static int init_vmcs_bios(struct guest_info * core, struct vmx_data * vmx_state) int i = 0; // For now we will assume that unrestricted guest mode is assured w/ EPT +// CR0.NE (bit 5) must be set in vmx operation. In restricted guest mode +// this bit is managed by vmxassist but here we must handle attempts to clear it +#define CR0_NE 0x00000020 +// NOTE: we need to react when CR0_PG changes but we don't need to watch CR0_PE +// (compare with restricted guest case few lines above) + vmx_ret |= check_vmcs_write(VMCS_CR0_MASK, (CR0_PG | CR0_WP | CR0_NE)); core->vm_regs.rsp = 0x00; core->rip = 0xfff0; core->vm_regs.rdx = 0x00000f00; core->ctrl_regs.rflags = 0x00000002; // The reserved bit is always 1 - core->ctrl_regs.cr0 = 0x60010010; // Set the WP flag so the memory hooks work in real-mode + // CR0.NE (bit 5) must be set in CR0 to enter VMX mode! + core->ctrl_regs.cr0 = 0x60010030; // Set the WP flag so the memory hooks work in real-mode + // CR4.VMXE (bit 13) must be set in CR4 to enter VMX mode! + // NOTE: when in restricted guest mode, then vmxassist sets this bit + core->ctrl_regs.cr4 = 0x00002000; core->segments.cs.selector = 0xf000; @@ -856,7 +866,7 @@ int v3_vmx_enter(struct guest_info * info) { update_irq_exit_state(info); #endif - if (exit_info.exit_reason == VMEXIT_INTR_WINDOW) { + if (exit_info.exit_reason == VMX_VMEXIT_INTR_WINDOW) { // This is a special case whose only job is to inject an interrupt vmcs_read(VMCS_PROC_CTRLS, &(vmx_info->pri_proc_ctrls.value)); vmx_info->pri_proc_ctrls.int_wndw_exit = 0; @@ -962,8 +972,23 @@ int v3_is_vmx_capable() { PrintDebug("MSRREGlow: 0x%.8x\n", feature_msr.lo); if ((feature_msr.lo & CPUID_VMX_FEATURES) != CPUID_VMX_FEATURES) { - PrintDebug("VMX is locked -- enable in the BIOS\n"); - return 0; + if((feature_msr.lo & CPUID_VMX_FEATURES) == 1) { // IA32_FEATURE_CONTROL_LOCK_BIT + PrintDebug("VMX is disabled and lock bit is 1 -- enable VMX in the BIOS\n"); + return 0; + } else { + PrintDebug("VMX lock bit seems to be 0\nTrying to enable VMX\n"); + feature_msr.lo |= 5; // IA32_FEATURE_CONTROL_LOCK_BIT | IA32_FEATURE_CONTROL_VMX_ENABLE_BIT + v3_set_msr(VMX_FEATURE_CONTROL_MSR, feature_msr.hi, feature_msr.lo); + // check results + v3_get_msr(VMX_FEATURE_CONTROL_MSR, &(feature_msr.hi), &(feature_msr.lo)); + if ((feature_msr.lo & CPUID_VMX_FEATURES) != CPUID_VMX_FEATURES) { + PrintDebug("failed to unlock VMX\n"); + return 0; + } else { + PrintDebug("VMX enabled!\n"); + return 1; + } + } } } else { diff --git a/palacios/src/palacios/vmx_ctrl_regs.c b/palacios/src/palacios/vmx_ctrl_regs.c index 7f95b9c..ed4de70 100644 --- a/palacios/src/palacios/vmx_ctrl_regs.c +++ b/palacios/src/palacios/vmx_ctrl_regs.c @@ -32,6 +32,8 @@ #define PrintDebug(fmt, args...) #endif +extern v3_cpu_arch_t v3_cpu_types[]; + static v3_reg_t * get_reg_ptr(struct guest_info * info, struct vmx_exit_cr_qual * cr_qual); static int handle_mov_to_cr0(struct guest_info * info, v3_reg_t * new_val, struct vmx_exit_info * exit_info); static int handle_mov_to_cr3(struct guest_info * info, v3_reg_t * cr3_reg); @@ -135,7 +137,7 @@ static int ept_handle_cr4_write(struct guest_info * info, v3_reg_t * reg) { *(uint32_t*)hw_cr4, *(uint32_t*)guest_cr4, *(uint32_t*)new_cr4); // update shadow anyway *guest_cr4 = *new_cr4; - if(info->mem_mode == VIRTUAL_MEM) { + if((info->mem_mode == VIRTUAL_MEM) || (v3_cpu_types[info->pcpu_id] == V3_VMX_EPT_UG_CPU)) { // we have paging enabled, so only care about VMXE *hw_cr4 = *new_cr4; *(uint32_t*)hw_cr4 |= CR4_VMXE; @@ -223,7 +225,8 @@ static int handle_mov_to_cr0(struct guest_info * info, v3_reg_t * new_cr0, struc (uint32_t)info->shdw_pg_state.guest_cr0, (uint32_t)*new_cr0); */ - if (new_shdw_cr0->pe != shdw_cr0->pe) { + // we don't need vmxassist in case of UG mode + if ((new_shdw_cr0->pe != shdw_cr0->pe) && (v3_cpu_types[info->pcpu_id] != V3_VMX_EPT_UG_CPU)) { /* PrintDebug("Guest CR0: 0x%x\n", *(uint32_t *)guest_cr0); PrintDebug("Old shadow CR0: 0x%x\n", *(uint32_t *)shdw_cr0); @@ -261,15 +264,21 @@ static int handle_mov_to_cr0(struct guest_info * info, v3_reg_t * new_cr0, struc // and set them to the guest values *guest_cr0 = *shdw_cr0; - // Except PG, PE, and NE, which are always set - guest_cr0->pe = 1; - guest_cr0->pg = 1; - guest_cr0->ne = 1; + if(v3_cpu_types[info->pcpu_id] == V3_VMX_EPT_UG_CPU) { + // Except NE, must be always set in vmx operation + guest_cr0->ne = 1; + } else { + // Except PG, PE, and NE, which are always set + guest_cr0->pe = 1; + guest_cr0->pg = 1; + guest_cr0->ne = 1; + } if ((paging_transition)) { // Paging transition - - if (v3_get_vm_mem_mode(info) == VIRTUAL_MEM) { + // PrintDebug("Paging transition\n"); + + if ((v3_get_vm_mem_mode(info) == VIRTUAL_MEM) || (v3_cpu_types[info->pcpu_id] == V3_VMX_EPT_UG_CPU)) { struct efer_64 * vm_efer = (struct efer_64 *)&(info->shdw_pg_state.guest_efer); struct efer_64 * hw_efer = (struct efer_64 *)&(info->ctrl_regs.efer); @@ -290,20 +299,24 @@ static int handle_mov_to_cr0(struct guest_info * info, v3_reg_t * new_cr0, struc return -1; } } else { - // EPT mode, need to update cached CR3, CR4 - info->ctrl_regs.cr3 = info->shdw_pg_state.guest_cr3; - // Disable CR3 exits as guest enabled paging - vmx_info->pri_proc_ctrls.cr3_ld_exit = 0; - vmx_info->pri_proc_ctrls.cr3_str_exit = 0; - if(v3_update_vmcs_ctrl_fields(info)) return -1; - // write guest CR4 - struct cr4_32 *guest_cr4 = (struct cr4_32 *)&vmx_info->guest_cr4; - struct cr4_32 *hw_cr4 = (struct cr4_32 *)&info->ctrl_regs.cr4; - *hw_cr4 = *guest_cr4; - *(uint32_t*)hw_cr4 |= CR4_VMXE; - PrintDebug("Guest enables paging. Restored cached CR3 (%x), CR4 (%x)." - " Guest EFER %x, guest HW EFER %x\n", (uint32_t)info->ctrl_regs.cr3, *(uint32_t*)guest_cr4, - *(uint32_t*)vm_efer, *(uint32_t*)hw_efer); + if(v3_cpu_types[info->pcpu_id] != V3_VMX_EPT_UG_CPU) { + // EPT mode, need to update cached CR3, CR4 + info->ctrl_regs.cr3 = info->shdw_pg_state.guest_cr3; + // Disable CR3 exits as guest enabled paging + vmx_info->pri_proc_ctrls.cr3_ld_exit = 0; + vmx_info->pri_proc_ctrls.cr3_str_exit = 0; + if(v3_update_vmcs_ctrl_fields(info)) return -1; + // write guest CR4 + struct cr4_32 *guest_cr4 = (struct cr4_32 *)&vmx_info->guest_cr4; + struct cr4_32 *hw_cr4 = (struct cr4_32 *)&info->ctrl_regs.cr4; + *hw_cr4 = *guest_cr4; + *(uint32_t*)hw_cr4 |= CR4_VMXE; + PrintDebug("Guest enables paging. Restored cached CR3 (%x), CR4 (%x)." + " Guest EFER %x, guest HW EFER %x\n", (uint32_t)info->ctrl_regs.cr3, *(uint32_t*)guest_cr4, + *(uint32_t*)vm_efer, *(uint32_t*)hw_efer); + } else { + PrintDebug("Guest (unrestricted) enables paging. Leaving CR3, CR4 and EFER as set by guest\n"); + } } diff --git a/palacios/src/palacios/vmx_handler.c b/palacios/src/palacios/vmx_handler.c index 63c8960..123d1ef 100644 --- a/palacios/src/palacios/vmx_handler.c +++ b/palacios/src/palacios/vmx_handler.c @@ -58,12 +58,12 @@ int v3_handle_vmx_exit(struct guest_info * info, struct vmx_exit_info * exit_inf if (basic_info->entry_error == 1) { switch (basic_info->reason) { - case VMEXIT_INVALID_GUEST_STATE: + case VMX_VMEXIT_INVALID_GUEST_STATE: PrintError("VM Entry failed due to invalid guest state\n"); PrintError("Printing VMCS: (NOTE: This VMCS may not belong to the correct guest)\n"); v3_print_vmcs(); break; - case VMEXIT_INVALID_MSR_LOAD: + case VMX_VMEXIT_INVALID_MSR_LOAD: PrintError("VM Entry failed due to error loading MSRs\n"); break; default: @@ -82,7 +82,7 @@ int v3_handle_vmx_exit(struct guest_info * info, struct vmx_exit_info * exit_inf #endif switch (basic_info->reason) { - case VMEXIT_INFO_EXCEPTION_OR_NMI: { + case VMX_VMEXIT_INFO_EXCEPTION_OR_NMI: { pf_error_t error_code = *(pf_error_t *)&(exit_info->int_err); @@ -113,7 +113,7 @@ int v3_handle_vmx_exit(struct guest_info * info, struct vmx_exit_info * exit_inf break; } - case VMEXIT_EPT_VIOLATION: { + case VMX_VMEXIT_EPT_VIOLATION: { struct ept_exit_qual * ept_qual = (struct ept_exit_qual *)&(exit_info->exit_qual); if (v3_handle_ept_fault(info, exit_info->ept_fault_addr, ept_qual) == -1) { @@ -123,7 +123,7 @@ int v3_handle_vmx_exit(struct guest_info * info, struct vmx_exit_info * exit_inf break; } - case VMEXIT_INVLPG: + case VMX_VMEXIT_INVLPG: if (info->shdw_pg_mode == SHADOW_PAGING) { if (v3_handle_shadow_invlpg(info) == -1) { PrintError("Error handling INVLPG\n"); @@ -133,7 +133,7 @@ int v3_handle_vmx_exit(struct guest_info * info, struct vmx_exit_info * exit_inf break; - case VMEXIT_RDTSC: + case VMX_VMEXIT_RDTSC: #ifdef V3_CONFIG_DEBUG_TIME PrintDebug("RDTSC\n"); #endif @@ -144,28 +144,28 @@ int v3_handle_vmx_exit(struct guest_info * info, struct vmx_exit_info * exit_inf break; - case VMEXIT_CPUID: + case VMX_VMEXIT_CPUID: if (v3_handle_cpuid(info) == -1) { PrintError("Error Handling CPUID instruction\n"); return -1; } break; - case VMEXIT_RDMSR: + case VMX_VMEXIT_RDMSR: if (v3_handle_msr_read(info) == -1) { PrintError("Error handling MSR Read\n"); return -1; } break; - case VMEXIT_WRMSR: + case VMX_VMEXIT_WRMSR: if (v3_handle_msr_write(info) == -1) { PrintError("Error handling MSR Write\n"); return -1; } break; - case VMEXIT_VMCALL: + case VMX_VMEXIT_VMCALL: /* * Hypercall */ @@ -178,7 +178,7 @@ int v3_handle_vmx_exit(struct guest_info * info, struct vmx_exit_info * exit_inf return -1; } break; - case VMEXIT_IO_INSTR: { + case VMX_VMEXIT_IO_INSTR: { struct vmx_exit_io_qual * io_qual = (struct vmx_exit_io_qual *)&(exit_info->exit_qual); if (io_qual->dir == 0) { @@ -208,7 +208,7 @@ int v3_handle_vmx_exit(struct guest_info * info, struct vmx_exit_info * exit_inf } break; } - case VMEXIT_CR_REG_ACCESSES: { + case VMX_VMEXIT_CR_REG_ACCESSES: { struct vmx_exit_cr_qual * cr_qual = (struct vmx_exit_cr_qual *)&(exit_info->exit_qual); // PrintDebug("Control register: %d\n", cr_qual->access_type); @@ -246,7 +246,7 @@ int v3_handle_vmx_exit(struct guest_info * info, struct vmx_exit_info * exit_inf break; } - case VMEXIT_HLT: + case VMX_VMEXIT_HLT: PrintDebug("Guest halted\n"); if (v3_handle_halt(info) == -1) { @@ -258,15 +258,15 @@ int v3_handle_vmx_exit(struct guest_info * info, struct vmx_exit_info * exit_inf - case VMEXIT_PAUSE: + case VMX_VMEXIT_PAUSE: // Handled as NOP info->rip += 2; break; - case VMEXIT_EXTERNAL_INTR: + case VMX_VMEXIT_EXTERNAL_INTR: // Interrupts are handled outside switch break; - case VMEXIT_INTR_WINDOW: + case VMX_VMEXIT_INTR_WINDOW: // This is handled in the atomic part of the vmx code, // not in the generic (interruptable) vmx handler break; @@ -345,105 +345,105 @@ static const char VMEXIT_XSETBV_STR[] = "VMEXIT_XSETBV"; const char * v3_vmx_exit_code_to_str(vmx_exit_t exit) { switch(exit) { - case VMEXIT_INFO_EXCEPTION_OR_NMI: + case VMX_VMEXIT_INFO_EXCEPTION_OR_NMI: return VMEXIT_INFO_EXCEPTION_OR_NMI_STR; - case VMEXIT_EXTERNAL_INTR: + case VMX_VMEXIT_EXTERNAL_INTR: return VMEXIT_EXTERNAL_INTR_STR; - case VMEXIT_TRIPLE_FAULT: + case VMX_VMEXIT_TRIPLE_FAULT: return VMEXIT_TRIPLE_FAULT_STR; - case VMEXIT_INIT_SIGNAL: + case VMX_VMEXIT_INIT_SIGNAL: return VMEXIT_INIT_SIGNAL_STR; - case VMEXIT_STARTUP_IPI: + case VMX_VMEXIT_STARTUP_IPI: return VMEXIT_STARTUP_IPI_STR; - case VMEXIT_IO_SMI: + case VMX_VMEXIT_IO_SMI: return VMEXIT_IO_SMI_STR; - case VMEXIT_OTHER_SMI: + case VMX_VMEXIT_OTHER_SMI: return VMEXIT_OTHER_SMI_STR; - case VMEXIT_INTR_WINDOW: + case VMX_VMEXIT_INTR_WINDOW: return VMEXIT_INTR_WINDOW_STR; - case VMEXIT_NMI_WINDOW: + case VMX_VMEXIT_NMI_WINDOW: return VMEXIT_NMI_WINDOW_STR; - case VMEXIT_TASK_SWITCH: + case VMX_VMEXIT_TASK_SWITCH: return VMEXIT_TASK_SWITCH_STR; - case VMEXIT_CPUID: + case VMX_VMEXIT_CPUID: return VMEXIT_CPUID_STR; - case VMEXIT_HLT: + case VMX_VMEXIT_HLT: return VMEXIT_HLT_STR; - case VMEXIT_INVD: + case VMX_VMEXIT_INVD: return VMEXIT_INVD_STR; - case VMEXIT_INVLPG: + case VMX_VMEXIT_INVLPG: return VMEXIT_INVLPG_STR; - case VMEXIT_RDPMC: + case VMX_VMEXIT_RDPMC: return VMEXIT_RDPMC_STR; - case VMEXIT_RDTSC: + case VMX_VMEXIT_RDTSC: return VMEXIT_RDTSC_STR; - case VMEXIT_RSM: + case VMX_VMEXIT_RSM: return VMEXIT_RSM_STR; - case VMEXIT_VMCALL: + case VMX_VMEXIT_VMCALL: return VMEXIT_VMCALL_STR; - case VMEXIT_VMCLEAR: + case VMX_VMEXIT_VMCLEAR: return VMEXIT_VMCLEAR_STR; - case VMEXIT_VMLAUNCH: + case VMX_VMEXIT_VMLAUNCH: return VMEXIT_VMLAUNCH_STR; - case VMEXIT_VMPTRLD: + case VMX_VMEXIT_VMPTRLD: return VMEXIT_VMPTRLD_STR; - case VMEXIT_VMPTRST: + case VMX_VMEXIT_VMPTRST: return VMEXIT_VMPTRST_STR; - case VMEXIT_VMREAD: + case VMX_VMEXIT_VMREAD: return VMEXIT_VMREAD_STR; - case VMEXIT_VMRESUME: + case VMX_VMEXIT_VMRESUME: return VMEXIT_VMRESUME_STR; - case VMEXIT_VMWRITE: + case VMX_VMEXIT_VMWRITE: return VMEXIT_VMWRITE_STR; - case VMEXIT_VMXOFF: + case VMX_VMEXIT_VMXOFF: return VMEXIT_VMXOFF_STR; - case VMEXIT_VMXON: + case VMX_VMEXIT_VMXON: return VMEXIT_VMXON_STR; - case VMEXIT_CR_REG_ACCESSES: + case VMX_VMEXIT_CR_REG_ACCESSES: return VMEXIT_CR_REG_ACCESSES_STR; - case VMEXIT_MOV_DR: + case VMX_VMEXIT_MOV_DR: return VMEXIT_MOV_DR_STR; - case VMEXIT_IO_INSTR: + case VMX_VMEXIT_IO_INSTR: return VMEXIT_IO_INSTR_STR; - case VMEXIT_RDMSR: + case VMX_VMEXIT_RDMSR: return VMEXIT_RDMSR_STR; - case VMEXIT_WRMSR: + case VMX_VMEXIT_WRMSR: return VMEXIT_WRMSR_STR; - case VMEXIT_INVALID_GUEST_STATE: + case VMX_VMEXIT_INVALID_GUEST_STATE: return VMEXIT_INVALID_GUEST_STATE_STR; - case VMEXIT_INVALID_MSR_LOAD: + case VMX_VMEXIT_INVALID_MSR_LOAD: return VMEXIT_INVALID_MSR_LOAD_STR; - case VMEXIT_MWAIT: + case VMX_VMEXIT_MWAIT: return VMEXIT_MWAIT_STR; - case VMEXIT_MONITOR: + case VMX_VMEXIT_MONITOR: return VMEXIT_MONITOR_STR; - case VMEXIT_PAUSE: + case VMX_VMEXIT_PAUSE: return VMEXIT_PAUSE_STR; - case VMEXIT_INVALID_MACHINE_CHECK: + case VMX_VMEXIT_INVALID_MACHINE_CHECK: return VMEXIT_INVALID_MACHINE_CHECK_STR; - case VMEXIT_TPR_BELOW_THRESHOLD: + case VMX_VMEXIT_TPR_BELOW_THRESHOLD: return VMEXIT_TPR_BELOW_THRESHOLD_STR; - case VMEXIT_APIC: + case VMX_VMEXIT_APIC: return VMEXIT_APIC_STR; - case VMEXIT_GDTR_IDTR: + case VMX_VMEXIT_GDTR_IDTR: return VMEXIT_GDTR_IDTR_STR; - case VMEXIT_LDTR_TR: + case VMX_VMEXIT_LDTR_TR: return VMEXIT_LDTR_TR_STR; - case VMEXIT_EPT_VIOLATION: + case VMX_VMEXIT_EPT_VIOLATION: return VMEXIT_EPT_VIOLATION_STR; - case VMEXIT_EPT_CONFIG: + case VMX_VMEXIT_EPT_CONFIG: return VMEXIT_EPT_CONFIG_STR; - case VMEXIT_INVEPT: + case VMX_VMEXIT_INVEPT: return VMEXIT_INVEPT_STR; - case VMEXIT_RDTSCP: + case VMX_VMEXIT_RDTSCP: return VMEXIT_RDTSCP_STR; - case VMEXIT_EXPIRED_PREEMPT_TIMER: + case VMX_VMEXIT_EXPIRED_PREEMPT_TIMER: return VMEXIT_EXPIRED_PREEMPT_TIMER_STR; - case VMEXIT_INVVPID: + case VMX_VMEXIT_INVVPID: return VMEXIT_INVVPID_STR; - case VMEXIT_WBINVD: + case VMX_VMEXIT_WBINVD: return VMEXIT_WBINVD_STR; - case VMEXIT_XSETBV: + case VMX_VMEXIT_XSETBV: return VMEXIT_XSETBV_STR; } return NULL; diff --git a/palacios/src/palacios/vmx_hw_info.c b/palacios/src/palacios/vmx_hw_info.c index d5fe494..26e3045 100644 --- a/palacios/src/palacios/vmx_hw_info.c +++ b/palacios/src/palacios/vmx_hw_info.c @@ -125,9 +125,15 @@ int v3_init_vmx_hw(struct vmx_hw_info * hw_info) { v3_get_msr(VMX_PROCBASED_CTLS2_MSR,&(proc2.hi),&(proc2.lo)); - if ( (proc2.hi & 0x2) || (proc2.hi & 0x20) ) { - v3_get_msr(VMX_EPT_VPID_CAP_MSR, &(hw_info->ept_info.hi), &(hw_info->ept_info.lo)); - } + if ( (proc2.hi & 0x2) || (proc2.hi & 0x20) ) { + v3_get_msr(VMX_EPT_VPID_CAP_MSR, &(hw_info->ept_info.hi), &(hw_info->ept_info.lo)); + } else { + // w/o this message you'll have to think a lot when + // you much later see the message "Unsupported EPT Table depth" + PrintError("EPT data unavailable! i.e. procbased_ctls2[33]=procbased_ctrls2[37] == 0\n"); + } + } else { + PrintError("Secondary procbased controls are unavailable!\n"); } get_cr_fields(&(hw_info->cr0), VMX_CR0_FIXED1_MSR, VMX_CR0_FIXED0_MSR); -- 1.7.5.4