-
/*
* This file is part of the Palacios Virtual Machine Monitor developed
* by the V3VEE Project with funding from the United States National
#include <palacios/vmm_types.h>
-
-
-/* 16 bit guest state */
-#define VMCS_GUEST_ES_SELECTOR 0x00000800
-#define VMCS_GUEST_CS_SELECTOR 0x00000802
-#define VMCS_GUEST_SS_SELECTOR 0x00000804
-#define VMCS_GUEST_DS_SELECTOR 0x00000806
-#define VMCS_GUEST_FS_SELECTOR 0x00000808
-#define VMCS_GUEST_GS_SELECTOR 0x0000080A
-#define VMCS_GUEST_LDTR_SELECTOR 0x0000080C
-#define VMCS_GUEST_TR_SELECTOR 0x0000080E
-
-/* 16 bit host state */
-#define VMCS_HOST_ES_SELECTOR 0x00000C00
-#define VMCS_HOST_CS_SELECTOR 0x00000C02
-#define VMCS_HOST_SS_SELECTOR 0x00000C04
-#define VMCS_HOST_DS_SELECTOR 0x00000C06
-#define VMCS_HOST_FS_SELECTOR 0x00000C08
-#define VMCS_HOST_GS_SELECTOR 0x00000C0A
-#define VMCS_HOST_TR_SELECTOR 0x00000C0C
-
-/* 64 bit control fields */
-#define IO_BITMAP_A_ADDR 0x00002000
-#define IO_BITMAP_A_ADDR_HIGH 0x00002001
-#define IO_BITMAP_B_ADDR 0x00002002
-#define IO_BITMAP_B_ADDR_HIGH 0x00002003
-// Only with "Use MSR Bitmaps" enabled
-#define MSR_BITMAPS 0x00002004
-#define MSR_BITMAPS_HIGH 0x00002005
-//
-#define VM_EXIT_MSR_STORE_ADDR 0x00002006
-#define VM_EXIT_MSR_STORE_ADDR_HIGH 0x00002007
-#define VM_EXIT_MSR_LOAD_ADDR 0x00002008
-#define VM_EXIT_MSR_LOAD_ADDR_HIGH 0x00002009
-#define VM_ENTRY_MSR_LOAD_ADDR 0x0000200A
-#define VM_ENTRY_MSR_LOAD_ADDR_HIGH 0x0000200B
-#define VMCS_EXEC_PTR 0x0000200C
-#define VMCS_EXEC_PTR_HIGH 0x0000200D
-#define TSC_OFFSET 0x00002010
-#define TSC_OFFSET_HIGH 0x00002011
-// Only with "Use TPR Shadow" enabled
-#define VIRT_APIC_PAGE_ADDR 0x00002012
-#define VIRT_APIC_PAGE_ADDR_HIGH 0x00002013
-//
-
-
-/* 64 bit guest state fields */
-#define VMCS_LINK_PTR 0x00002800
-#define VMCS_LINK_PTR_HIGH 0x00002801
-#define GUEST_IA32_DEBUGCTL 0x00002802
-#define GUEST_IA32_DEBUGCTL_HIGH 0x00002803
-
-
-/* 32 bit control fields */
-#define PIN_VM_EXEC_CTRLS 0x00004000
-#define PROC_VM_EXEC_CTRLS 0x00004002
-#define EXCEPTION_BITMAP 0x00004004
-#define PAGE_FAULT_ERROR_MASK 0x00004006
-#define PAGE_FAULT_ERROR_MATCH 0x00004008
-#define CR3_TARGET_COUNT 0x0000400A
-#define VM_EXIT_CTRLS 0x0000400C
-#define VM_EXIT_MSR_STORE_COUNT 0x0000400E
-#define VM_EXIT_MSR_LOAD_COUNT 0x00004010
-#define VM_ENTRY_CTRLS 0x00004012
-#define VM_ENTRY_MSR_LOAD_COUNT 0x00004014
-#define VM_ENTRY_INT_INFO_FIELD 0x00004016
-#define VM_ENTRY_EXCEPTION_ERROR 0x00004018
-#define VM_ENTRY_INSTR_LENGTH 0x0000401A
-// Only with "Use TPR Shadow" Enabled
-#define TPR_THRESHOLD 0x0000401C
-//
-
-
-/* 32 bit Read Only data fields */
-#define VM_INSTR_ERROR 0x00004400
-#define EXIT_REASON 0x00004402
-#define VM_EXIT_INT_INFO 0x00004404
-#define VM_EXIT_INT_ERROR 0x00004406
-#define IDT_VECTOR_INFO 0x00004408
-#define IDT_VECTOR_ERROR 0x0000440A
-#define VM_EXIT_INSTR_LENGTH 0x0000440C
-#define VMX_INSTR_INFO 0x0000440E
-
-/* 32 bit Guest state fields */
-#define GUEST_ES_LIMIT 0x00004800
-#define GUEST_CS_LIMIT 0x00004802
-#define GUEST_SS_LIMIT 0x00004804
-#define GUEST_DS_LIMIT 0x00004806
-#define GUEST_FS_LIMIT 0x00004808
-#define GUEST_GS_LIMIT 0x0000480A
-#define GUEST_LDTR_LIMIT 0x0000480C
-#define GUEST_TR_LIMIT 0x0000480E
-#define GUEST_GDTR_LIMIT 0x00004810
-#define GUEST_IDTR_LIMIT 0x00004812
-#define GUEST_ES_ACCESS 0x00004814
-#define GUEST_CS_ACCESS 0x00004816
-#define GUEST_SS_ACCESS 0x00004818
-#define GUEST_DS_ACCESS 0x0000481A
-#define GUEST_FS_ACCESS 0x0000481C
-#define GUEST_GS_ACCESS 0x0000481E
-#define GUEST_LDTR_ACCESS 0x00004820
-#define GUEST_TR_ACCESS 0x00004822
-#define GUEST_INT_STATE 0x00004824
-#define GUEST_ACTIVITY_STATE 0x00004826
-#define GUEST_SMBASE 0x00004828
-#define GUEST_IA32_SYSENTER_CS 0x0000482A
-
-
-/* 32 bit host state field */
-#define HOST_IA32_SYSENTER_CS 0x00004C00
-
-/* Natural Width Control Fields */
-#define CR0_GUEST_HOST_MASK 0x00006000
-#define CR4_GUEST_HOST_MASK 0x00006002
-#define CR0_READ_SHADOW 0x00006004
-#define CR4_READ_SHADOW 0x00006006
-#define CR3_TARGET_VALUE_0 0x00006008
-#define CR3_TARGET_VALUE_1 0x0000600A
-#define CR3_TARGET_VALUE_2 0x0000600C
-#define CR3_TARGET_VALUE_3 0x0000600E
-
-
-/* Natural Width Read Only Fields */
-#define EXIT_QUALIFICATION 0x00006400
-#define IO_RCX 0x00006402
-#define IO_RSI 0x00006404
-#define IO_RDI 0x00006406
-#define IO_RIP 0x00006408
-#define GUEST_LINEAR_ADDR 0x0000640A
-
-/* Natural Width Guest State Fields */
-#define GUEST_CR0 0x00006800
-#define GUEST_CR3 0x00006802
-#define GUEST_CR4 0x00006804
-#define GUEST_ES_BASE 0x00006806
-#define GUEST_CS_BASE 0x00006808
-#define GUEST_SS_BASE 0x0000680A
-#define GUEST_DS_BASE 0x0000680C
-#define GUEST_FS_BASE 0x0000680E
-#define GUEST_GS_BASE 0x00006810
-#define GUEST_LDTR_BASE 0x00006812
-#define GUEST_TR_BASE 0x00006814
-#define GUEST_GDTR_BASE 0x00006816
-#define GUEST_IDTR_BASE 0x00006818
-#define GUEST_DR7 0x0000681A
-#define GUEST_RSP 0x0000681C
-#define GUEST_RIP 0x0000681E
-#define GUEST_RFLAGS 0x00006820
-#define GUEST_PENDING_DEBUG_EXCS 0x00006822
-#define GUEST_IA32_SYSENTER_ESP 0x00006824
-#define GUEST_IA32_SYSENTER_EIP 0x00006826
-
-
-/* Natural Width Host State Fields */
-#define HOST_CR0 0x00006C00
-#define HOST_CR3 0x00006C02
-#define HOST_CR4 0x00006C04
-#define HOST_FS_BASE 0x00006C06
-#define HOST_GS_BASE 0x00006C08
-#define HOST_TR_BASE 0x00006C0A
-#define HOST_GDTR_BASE 0x00006C0C
-#define HOST_IDTR_BASE 0x00006C0E
-#define HOST_IA32_SYSENTER_ESP 0x00006C10
-#define HOST_IA32_SYSENTER_EIP 0x00006C12
-#define HOST_RSP 0x00006C14
-#define HOST_RIP 0x00006C16
-
-/* Pin Based VM Execution Controls */
-/* INTEL MANUAL: 20-10 vol 3B */
-#define EXTERNAL_INTERRUPT_EXITING 0x00000001
-#define NMI_EXITING 0x00000008
-#define VIRTUAL_NMIS 0x00000020
-
-
-/* Processor Based VM Execution Controls */
-/* INTEL MANUAL: 20-11 vol. 3B */
-#define INTERRUPT_WINDOWS_EXIT 0x00000004
-#define USE_TSC_OFFSETTING 0x00000008
-#define HLT_EXITING 0x00000080
-#define INVLPG_EXITING 0x00000200
-#define MWAIT_EXITING 0x00000400
-#define RDPMC_EXITING 0x00000800
-#define RDTSC_EXITING 0x00001000
-#define CR8_LOAD_EXITING 0x00080000
-#define CR8_STORE_EXITING 0x00100000
-#define USE_TPR_SHADOW 0x00200000
-#define NMI_WINDOW_EXITING 0x00400000
-#define MOVDR_EXITING 0x00800000
-#define UNCONDITION_IO_EXITING 0x01000000
-#define USE_IO_BITMAPS 0x02000000
-#define USE_MSR_BITMAPS 0x10000000
-#define MONITOR_EXITING 0x20000000
-#define PAUSE_EXITING 0x40000000
+#include <palacios/vm_guest.h>
/* VM-Exit Controls */
/* INTEL MANUAL: 20-16 vol. 3B */
-#define HOST_ADDR_SPACE_SIZE 0x00000200
-#define ACK_IRQ_ON_EXIT 0x00008000
-
-// Exit Reasons
-#define VM_EXIT_REASON_INFO_EXCEPTION_OR_NMI 0
-#define VM_EXIT_REASON_EXTERNAL_INTR 1
-#define VM_EXIT_REASON_TRIPLE_FAULT 2
-#define VM_EXIT_REASON_INIT_SIGNAL 3
-#define VM_EXIT_REASON_STARTUP_IPI 4
-#define VM_EXIT_REASON_IO_SMI 5
-#define VM_EXIT_REASON_OTHER_SMI 6
-#define VM_EXIT_REASON_INTR_WINDOW 7
-#define VM_EXIT_REASON_NMI_WINDOW 8
-#define VM_EXIT_REASON_TASK_SWITCH 9
-#define VM_EXIT_REASON_CPUID 10
-#define VM_EXIT_REASON_HLT 12
-#define VM_EXIT_REASON_INVD 13
-#define VM_EXIT_REASON_INVLPG 14
-#define VM_EXIT_REASON_RDPMC 15
-#define VM_EXIT_REASON_RDTSC 16
-#define VM_EXIT_REASON_RSM 17
-#define VM_EXIT_REASON_VMCALL 18
-#define VM_EXIT_REASON_VMCLEAR 19
-#define VM_EXIT_REASON_VMLAUNCH 20
-#define VM_EXIT_REASON_VMPTRLD 21
-#define VM_EXIT_REASON_VMPTRST 22
-#define VM_EXIT_REASON_VMREAD 23
-#define VM_EXIT_REASON_VMRESUME 24
-#define VM_EXIT_REASON_VMWRITE 25
-#define VM_EXIT_REASON_VMXOFF 26
-#define VM_EXIT_REASON_VMXON 27
-#define VM_EXIT_REASON_CR_REG_ACCESSES 28
-#define VM_EXIT_REASON_MOV_DR 29
-#define VM_EXIT_REASON_IO_INSTR 30
-#define VM_EXIT_REASON_RDMSR 31
-#define VM_EXIT_REASON_WRMSR 32
-#define VM_EXIT_REASON_ENTRY_FAIL_INVALID_GUEST_STATE 33
-#define VM_EXIT_REASON_ENTRY_FAIL_MSR_LOAD 34
-#define VM_EXIT_REASON_MWAIT 36
-#define VM_EXIT_REASON_MONITOR 39
-#define VM_EXIT_REASON_PAUSE 40
-#define VM_EXIT_REASON_ENTRY_FAILURE_MACHINE_CHECK 41
-#define VM_EXIT_REASON_TPR_BELOW_THRESHOLD 43
-
-
-extern char *exception_names[];
-extern char *exception_type_names[];
-
-
-
-
-typedef void VMCS;
-
-
-
-
-/* VMCS Exit QUALIFICATIONs */
-struct VMExitIOQual {
- uint_t accessSize : 3; // (0: 1 Byte ;; 1: 2 Bytes ;; 3: 4 Bytes)
- uint_t dir : 1; // (0: Out ;; 1: In)
- uint_t string : 1; // (0: not string ;; 1: string)
- uint_t REP : 1; // (0: not REP ;; 1: REP)
- uint_t opEnc : 1; // (0: DX ;; 1: immediate)
- uint_t rsvd : 9; // Set to 0
- uint_t port : 16; // IO Port Number
-} __attribute__((packed));
+#define HOST_ADDR_SPACE_SIZE 0x00000200
+#define ACK_IRQ_ON_EXIT 0x00008000
+/* Control register exit masks */
+#define CR4_VMXE 0x00002000
+#define CR4_PAE 0x00000020
-struct VMExitDBGQual {
- uint_t B0 : 1; // Breakpoint 0 condition met
- uint_t B1 : 1; // Breakpoint 1 condition met
- uint_t B2 : 1; // Breakpoint 2 condition met
- uint_t B3 : 1; // Breakpoint 3 condition met
- uint_t rsvd : 9; // reserved to 0
- uint_t BD : 1; // detected DBG reg access
- uint_t BS : 1; // cause either single instr or taken branch
-} __attribute__((packed));
-
-struct VMExitTSQual {
- uint_t selector : 16; // selector of destination TSS
- uint_t rsvd : 14; // reserved to 0
- uint_t src : 2; // (0: CALL ; 1: IRET ; 2: JMP ; 3: Task gate in IDT)
+struct vmcs_field_encoding {
+ uint8_t access_type : 1; /* 0 = full, 1 = high, (for accessing 64 bit fields on 32bit CPU) */
+ uint16_t index : 9;
+ uint8_t type : 2; /* 0=ctrl, 1=read-only, 2 = guest state, 3 = host state */
+ uint8_t rsvd1 : 1; /* MBZ */
+ uint8_t width : 2; /* 0 = 16bit, 1 = 64bit, 2 = 32bit, 3 = natural width */
+ uint32_t rsvd2 : 17;
} __attribute__((packed));
-struct VMExitCRQual {
- uint_t crID : 4; // cr number (0 for CLTS and LMSW) (bit 3 always 0, on 32bit)
- uint_t accessType : 2; // (0: MOV to CR ; 1: MOV from CR ; 2: CLTS ; 3: LMSW)
- uint_t lmswOpType : 1; // (0: register ; 1: memory)
- uint_t rsvd1 : 1; // reserved to 0
- uint_t gpr : 4; // (0:RAX+[CLTS/LMSW], 1:RCX, 2:RDX, 3:RBX, 4:RSP, 5:RBP, 6:RSI, 6:RDI, 8-15:64bit regs)
- uint_t rsvd2 : 4; // reserved to 0
- uint_t lmswSrc : 16; // src data for lmsw
-} __attribute__((packed));
-struct VMExitMovDRQual {
- uint_t regID : 3; // debug register number
- uint_t rsvd1 : 1; // reserved to 0
- uint_t dir : 1; // (0: MOV to DR , 1: MOV from DR)
- uint_t rsvd2 : 3; // reserved to 0
- uint_t gpr : 4; // (0:RAX, 1:RCX, 2:RDX, 3:RBX, 4:RSP, 5:RBP, 6:RSI, 6:RDI, 8-15:64bit regs)
+typedef enum {
+ /* 16 bit control field */
+ VMCS_VPID = 0x00000000,
+ /* 16 bit guest state */
+ VMCS_GUEST_ES_SELECTOR = 0x00000800,
+ VMCS_GUEST_CS_SELECTOR = 0x00000802,
+ VMCS_GUEST_SS_SELECTOR = 0x00000804,
+ VMCS_GUEST_DS_SELECTOR = 0x00000806,
+ VMCS_GUEST_FS_SELECTOR = 0x00000808,
+ VMCS_GUEST_GS_SELECTOR = 0x0000080A,
+ VMCS_GUEST_LDTR_SELECTOR = 0x0000080C,
+ VMCS_GUEST_TR_SELECTOR = 0x0000080E,
+ /* 16 bit host state */
+ VMCS_HOST_ES_SELECTOR = 0x00000C00,
+ VMCS_HOST_CS_SELECTOR = 0x00000C02,
+ VMCS_HOST_SS_SELECTOR = 0x00000C04,
+ VMCS_HOST_DS_SELECTOR = 0x00000C06,
+ VMCS_HOST_FS_SELECTOR = 0x00000C08,
+ VMCS_HOST_GS_SELECTOR = 0x00000C0A,
+ VMCS_HOST_TR_SELECTOR = 0x00000C0C,
+ /* 64 bit control fields */
+ VMCS_IO_BITMAP_A_ADDR = 0x00002000,
+ VMCS_IO_BITMAP_A_ADDR_HIGH = 0x00002001,
+ VMCS_IO_BITMAP_B_ADDR = 0x00002002,
+ VMCS_IO_BITMAP_B_ADDR_HIGH = 0x00002003,
+ VMCS_MSR_BITMAP = 0x00002004,
+ VMCS_MSR_BITMAP_HIGH = 0x00002005,
+ VMCS_EXIT_MSR_STORE_ADDR = 0x00002006,
+ VMCS_EXIT_MSR_STORE_ADDR_HIGH = 0x00002007,
+ VMCS_EXIT_MSR_LOAD_ADDR = 0x00002008,
+ VMCS_EXIT_MSR_LOAD_ADDR_HIGH = 0x00002009,
+ VMCS_ENTRY_MSR_LOAD_ADDR = 0x0000200A,
+ VMCS_ENTRY_MSR_LOAD_ADDR_HIGH = 0x0000200B,
+ VMCS_EXEC_PTR = 0x0000200C,
+ VMCS_EXEC_PTR_HIGH = 0x0000200D,
+ VMCS_TSC_OFFSET = 0x00002010,
+ VMCS_TSC_OFFSET_HIGH = 0x00002011,
+ VMCS_VAPIC_ADDR = 0x00002012,
+ VMCS_VAPIC_ADDR_HIGH = 0x00002013,
+ VMCS_APIC_ACCESS_ADDR = 0x00002014,
+ VMCS_APIC_ACCESS_ADDR_HIGH = 0x00002015,
+ VMCS_EPT_PTR = 0x0000201A,
+ VMCS_EPT_PTR_HIGH = 0x0000201B,
+ /* 64 bit read only data field */
+ VMCS_GUEST_PHYS_ADDR = 0x00002400,
+ VMCS_GUEST_PHYS_ADDR_HIGH = 0x00002401,
+ /* 64 bit guest state fields */
+ VMCS_LINK_PTR = 0x00002800,
+ VMCS_LINK_PTR_HIGH = 0x00002801,
+ VMCS_GUEST_DBG_CTL = 0x00002802,
+ VMCS_GUEST_DBG_CTL_HIGH = 0x00002803,
+ VMCS_GUEST_PAT = 0x00002804,
+ VMCS_GUEST_PAT_HIGH = 0x00002805,
+ VMCS_GUEST_EFER = 0x00002806,
+ VMCS_GUEST_EFER_HIGH = 0x00002807,
+ VMCS_GUEST_PERF_GLOBAL_CTRL = 0x00002808,
+ VMCS_GUEST_PERF_GLOBAL_CTRL_HIGH = 0x00002809,
+ VMCS_GUEST_PDPTE0 = 0x0000280A,
+ VMCS_GUEST_PDPTE0_HIGH = 0x0000280B,
+ VMCS_GUEST_PDPTE1 = 0x0000280C,
+ VMCS_GUEST_PDPTE1_HIGH = 0x0000280D,
+ VMCS_GUEST_PDPTE2 = 0x0000280E,
+ VMCS_GUEST_PDPTE2_HIGH = 0x0000280F,
+ VMCS_GUEST_PDPTE3 = 0x00002810,
+ VMCS_GUEST_PDPTE3_HIGH = 0x00002811,
+ /* 64 bit host state fields */
+ VMCS_HOST_PAT = 0x00002c00,
+ VMCS_HOST_PAT_HIGH = 0x00002c01,
+ VMCS_HOST_EFER = 0x00002c02,
+ VMCS_HOST_EFER_HIGH = 0x00002c03,
+ VMCS_HOST_PERF_GLOBAL_CTRL = 0x00002c04,
+ VMCS_HOST_PERF_GLOBAL_CTRL_HIGH = 0x00002c05,
+ /* 32 bit control fields */
+ VMCS_PIN_CTRLS = 0x00004000,
+ VMCS_PROC_CTRLS = 0x00004002,
+ VMCS_EXCP_BITMAP = 0x00004004,
+ VMCS_PG_FAULT_ERR_MASK = 0x00004006,
+ VMCS_PG_FAULT_ERR_MATCH = 0x00004008,
+ VMCS_CR3_TGT_CNT = 0x0000400A,
+ VMCS_EXIT_CTRLS = 0x0000400C,
+ VMCS_EXIT_MSR_STORE_CNT = 0x0000400E,
+ VMCS_EXIT_MSR_LOAD_CNT = 0x00004010,
+ VMCS_ENTRY_CTRLS = 0x00004012,
+ VMCS_ENTRY_MSR_LOAD_CNT = 0x00004014,
+ VMCS_ENTRY_INT_INFO = 0x00004016,
+ VMCS_ENTRY_EXCP_ERR = 0x00004018,
+ VMCS_ENTRY_INSTR_LEN = 0x0000401A,
+ VMCS_TPR_THRESHOLD = 0x0000401C,
+ VMCS_SEC_PROC_CTRLS = 0x0000401e,
+ VMCS_PLE_GAP = 0x00004020,
+ VMCS_PLE_WINDOW = 0x00004022,
+ /* 32 bit Read Only data fields */
+ VMCS_INSTR_ERR = 0x00004400,
+ VMCS_EXIT_REASON = 0x00004402,
+ VMCS_EXIT_INT_INFO = 0x00004404,
+ VMCS_EXIT_INT_ERR = 0x00004406,
+ VMCS_IDT_VECTOR_INFO = 0x00004408,
+ VMCS_IDT_VECTOR_ERR = 0x0000440A,
+ VMCS_EXIT_INSTR_LEN = 0x0000440C,
+ VMCS_EXIT_INSTR_INFO = 0x0000440E,
+ /* 32 bit Guest state fields */
+ VMCS_GUEST_ES_LIMIT = 0x00004800,
+ VMCS_GUEST_CS_LIMIT = 0x00004802,
+ VMCS_GUEST_SS_LIMIT = 0x00004804,
+ VMCS_GUEST_DS_LIMIT = 0x00004806,
+ VMCS_GUEST_FS_LIMIT = 0x00004808,
+ VMCS_GUEST_GS_LIMIT = 0x0000480A,
+ VMCS_GUEST_LDTR_LIMIT = 0x0000480C,
+ VMCS_GUEST_TR_LIMIT = 0x0000480E,
+ VMCS_GUEST_GDTR_LIMIT = 0x00004810,
+ VMCS_GUEST_IDTR_LIMIT = 0x00004812,
+ VMCS_GUEST_ES_ACCESS = 0x00004814,
+ VMCS_GUEST_CS_ACCESS = 0x00004816,
+ VMCS_GUEST_SS_ACCESS = 0x00004818,
+ VMCS_GUEST_DS_ACCESS = 0x0000481A,
+ VMCS_GUEST_FS_ACCESS = 0x0000481C,
+ VMCS_GUEST_GS_ACCESS = 0x0000481E,
+ VMCS_GUEST_LDTR_ACCESS = 0x00004820,
+ VMCS_GUEST_TR_ACCESS = 0x00004822,
+ VMCS_GUEST_INT_STATE = 0x00004824,
+ VMCS_GUEST_ACTIVITY_STATE = 0x00004826,
+ VMCS_GUEST_SMBASE = 0x00004828,
+ VMCS_GUEST_SYSENTER_CS = 0x0000482A,
+ VMCS_PREEMPT_TIMER = 0x0000482E,
+ /* 32 bit host state field */
+ VMCS_HOST_SYSENTER_CS = 0x00004C00,
+ /* Natural Width Control Fields */
+ VMCS_CR0_MASK = 0x00006000,
+ VMCS_CR4_MASK = 0x00006002,
+ VMCS_CR0_READ_SHDW = 0x00006004,
+ VMCS_CR4_READ_SHDW = 0x00006006,
+ VMCS_CR3_TGT_VAL_0 = 0x00006008,
+ VMCS_CR3_TGT_VAL_1 = 0x0000600A,
+ VMCS_CR3_TGT_VAL_2 = 0x0000600C,
+ VMCS_CR3_TGT_VAL_3 = 0x0000600E,
+ /* Natural Width Read Only Fields */
+ VMCS_EXIT_QUAL = 0x00006400,
+ VMCS_IO_RCX = 0x00006402,
+ VMCS_IO_RSI = 0x00006404,
+ VMCS_IO_RDI = 0x00006406,
+ VMCS_IO_RIP = 0x00006408,
+ VMCS_GUEST_LINEAR_ADDR = 0x0000640A,
+ /* Natural Width Guest State Fields */
+ VMCS_GUEST_CR0 = 0x00006800,
+ VMCS_GUEST_CR3 = 0x00006802,
+ VMCS_GUEST_CR4 = 0x00006804,
+ VMCS_GUEST_ES_BASE = 0x00006806,
+ VMCS_GUEST_CS_BASE = 0x00006808,
+ VMCS_GUEST_SS_BASE = 0x0000680A,
+ VMCS_GUEST_DS_BASE = 0x0000680C,
+ VMCS_GUEST_FS_BASE = 0x0000680E,
+ VMCS_GUEST_GS_BASE = 0x00006810,
+ VMCS_GUEST_LDTR_BASE = 0x00006812,
+ VMCS_GUEST_TR_BASE = 0x00006814,
+ VMCS_GUEST_GDTR_BASE = 0x00006816,
+ VMCS_GUEST_IDTR_BASE = 0x00006818,
+ VMCS_GUEST_DR7 = 0x0000681A,
+ VMCS_GUEST_RSP = 0x0000681C,
+ VMCS_GUEST_RIP = 0x0000681E,
+ VMCS_GUEST_RFLAGS = 0x00006820,
+ VMCS_GUEST_PENDING_DBG_EXCP = 0x00006822,
+ VMCS_GUEST_SYSENTER_ESP = 0x00006824,
+ VMCS_GUEST_SYSENTER_EIP = 0x00006826,
+ /* Natural Width Host State Fields */
+ VMCS_HOST_CR0 = 0x00006C00,
+ VMCS_HOST_CR3 = 0x00006C02,
+ VMCS_HOST_CR4 = 0x00006C04,
+ VMCS_HOST_FS_BASE = 0x00006C06,
+ VMCS_HOST_GS_BASE = 0x00006C08,
+ VMCS_HOST_TR_BASE = 0x00006C0A,
+ VMCS_HOST_GDTR_BASE = 0x00006C0C,
+ VMCS_HOST_IDTR_BASE = 0x00006C0E,
+ VMCS_HOST_SYSENTER_ESP = 0x00006C10,
+ VMCS_HOST_SYSENTER_EIP = 0x00006C12,
+ VMCS_HOST_RSP = 0x00006C14,
+ VMCS_HOST_RIP = 0x00006C16,
+} vmcs_field_t;
+
+
+
+struct vmx_exception_bitmap {
+ union {
+ uint32_t value;
+ struct {
+ uint_t de : 1; // (0) divide by zero
+ uint_t db : 1; // (1) Debug
+ uint_t nmi : 1; // (2) Non-maskable interrupt
+ uint_t bp : 1; // (3) Breakpoint
+ uint_t of : 1; // (4) Overflow
+ uint_t br : 1; // (5) Bound-Range
+ uint_t ud : 1; // (6) Invalid-Opcode
+ uint_t nm : 1; // (7) Device-not-available
+ uint_t df : 1; // (8) Double Fault
+ uint_t ex9 : 1;
+ uint_t ts : 1; // (10) Invalid TSS
+ uint_t np : 1; // (11) Segment-not-present
+ uint_t ss : 1; // (12) Stack
+ uint_t gp : 1; // (13) General Protection Fault
+ uint_t pf : 1; // (14) Page fault
+ uint_t ex15 : 1;
+ uint_t mf : 1; // (15) Floating point exception
+ uint_t ac : 1; // (16) Alignment-check
+ uint_t mc : 1; // (17) Machine Check
+ uint_t xf : 1; // (18) SIMD floating-point
+ uint_t ex20 : 1;
+ uint_t ex21 : 1;
+ uint_t ex22 : 1;
+ uint_t ex23 : 1;
+ uint_t ex24 : 1;
+ uint_t ex25 : 1;
+ uint_t ex26 : 1;
+ uint_t ex27 : 1;
+ uint_t ex28 : 1;
+ uint_t ex29 : 1;
+ uint_t sx : 1; // (30) Security Exception
+ uint_t ex31 : 1;
+ } __attribute__ ((packed));
+ } __attribute__ ((packed));
} __attribute__((packed));
-/* End Exit Qualifications */
-
-/* Exit Vector Info */
-struct VMExitIntInfo {
- uint_t nr : 8; // IRQ number, exception vector, NMI = 2
- uint_t type : 3; // (0: ext. IRQ , 2: NMI , 3: hw exception , 6: sw exception
- uint_t errorCode : 1; // 1: error Code present
- uint_t iret : 1; // something to do with NMIs and IRETs (Intel 3B, sec. 23.2.2)
- uint_t rsvd : 18; // always 0
- uint_t valid : 1; // always 1 if valid
-} __attribute__((packed));
+struct vmx_intr_state {
+ union {
+ uint32_t value;
+ struct {
+ uint32_t block_sti : 1;
+ uint32_t block_mov_ss : 1;
+ uint32_t block_smi : 1;
+ uint32_t block_nmi : 1;
+ uint32_t rsvd : 28;
+ } __attribute__((packed));
+ } __attribute__((packed));
+} __attribute__((packed));
-/* End Exit Vector Info */
-
-
-
+struct vmx_pending_dbg_excps {
+ union {
+ uint64_t value;
+
+ struct {
+ uint32_t lo;
+ uint32_t hi;
+ } __attribute__((packed));
+
+ struct {
+ uint64_t b0 : 1;
+ uint64_t b1 : 1;
+ uint64_t b2 : 1;
+ uint64_t b3 : 1;
+ uint64_t rsvd1 : 8;
+ uint64_t bp_set : 1;
+ uint64_t rsvd2 : 1;
+ uint64_t bp_ss : 1;
+ uint64_t rsvd3 : 49;
+ } __attribute__((packed));
+ } __attribute__((packed));
+} __attribute__((packed));
/* Segment Selector Access Rights (32 bits) */
/* INTEL Manual: 20-4 vol 3B */
-union SegAccess {
- struct {
- uchar_t type;
- uint_t descType : 1;
- uint_t dpl : 2;
- uint_t present : 1;
- uchar_t rsvd1;
- uint_t avail : 1;
- uint_t L : 1; // CS only (64 bit active), reserved otherwise
- uint_t DB : 1;
- uint_t granularity : 1;
- uint_t unusable : 1;
- uint_t rsvd2 : 15;
- } __attribute__((packed)) as_fields;
- uint_t as_dword;
-} __attribute__((packed));
-
-
-struct VMCSSegment {
- ushort_t selector ;
- union SegAccess access;
- uint_t limit ;
- uint_t baseAddr ; // should be 64 bits?
+struct vmcs_segment {
+ uint16_t selector;
+ uint32_t limit;
+ uint64_t base;
+
+ union {
+ uint32_t val;
+ struct {
+ uint32_t type : 4;
+ uint32_t desc_type : 1;
+ uint32_t dpl : 2;
+ uint32_t present : 1;
+ uint32_t rsvd1 : 4;
+ uint32_t avail : 1;
+ uint32_t long_mode : 1; // CS only (64 bit active), reserved otherwise
+ uint32_t db : 1;
+ uint32_t granularity : 1;
+ uint32_t unusable : 1;
+ uint32_t rsvd2 : 15;
+ } __attribute__((packed));
+ } __attribute__((packed)) access;
};
-
-struct VMCSGuestStateArea {
- /* (1) Guest State Area */
- /* (1.1) Guest Register State */
- uint_t cr0 ; // should be 64 bits?
- uint_t cr3 ; // should be 64 bits?
- uint_t cr4 ; // should be 64 bits?
- uint_t dr7 ; // should be 64 bits?
- uint_t rsp ; // should be 64 bits?
- uint_t rip ; // should be 64 bits?
- uint_t rflags ; // should be 64 bits?
-
-
- struct VMCSSegment cs ;
- struct VMCSSegment ss ;
- struct VMCSSegment ds ;
- struct VMCSSegment es ;
- struct VMCSSegment fs ;
- struct VMCSSegment gs ;
- struct VMCSSegment ldtr ;
- struct VMCSSegment tr ;
-
- struct VMCSSegment gdtr ;
- struct VMCSSegment idtr ;
-
- // MSRs
- ullong_t dbg_ctrl ;
- uint_t sysenter_cs ;
- ullong_t sysenter_esp ; // should be 64 bits?
- ullong_t sysenter_eip ; // should be 64 bits?
-
- uint_t smbase ;
-
- /* (1.2) Guest Non-register State */
- uint_t activity ; /* (0=Active, 1=HLT, 2=Shutdown, 3=Wait-for-SIPI)
- (listed in MSR: IA32_VMX_MISC) */
-
- uint_t interrupt_state ; // see Table 20-3 (page 20-6) INTEL MANUAL 3B
-
- ullong_t pending_dbg_exceptions ; // should be 64 bits?
- /* Table 20-4 page 20-8 INTEL MANUAL 3B */
-
- ullong_t vmcs_link ; // should be set to 0xffffffff_ffffffff
-};
-
-
-int CopyOutVMCSGuestStateArea(struct VMCSGuestStateArea * p);
-int CopyInVMCSGuestStateArea(struct VMCSGuestStateArea * p);
-
-
-
-struct VMCSHostStateArea {
- /* (2) Host State Area */
- ullong_t cr0 ; // Should be 64 bits?
- ullong_t cr3 ; // should be 64 bits?
- ullong_t cr4 ; // should be 64 bits?
- ullong_t rsp ; // should be 64 bits?
- ullong_t rip ; // should be 64 bits?
-
- ushort_t csSelector ;
- ushort_t ssSelector ;
- ushort_t dsSelector ;
- ushort_t esSelector ;
- ushort_t fsSelector ;
- ushort_t gsSelector ;
- ushort_t trSelector ;
-
- ullong_t fsBaseAddr ; // Should be 64 bits?
- ullong_t gsBaseAddr ; // Should be 64 bits?
- ullong_t trBaseAddr ; // Should be 64 bits?
- ullong_t gdtrBaseAddr ; // Should be 64 bits?
- ullong_t idtrBaseAddr ; // Should be 64 bits?
-
-
- /* MSRs */
- uint_t sysenter_cs ;
- ullong_t sysenter_esp ; // Should be 64 bits?
- ullong_t sysenter_eip ; // Should be 64 bits?
-
-};
-
-int CopyOutVMCSHostStateArea(struct VMCSHostStateArea *p);
-int CopyInVMCSHostStateArea(struct VMCSHostStateArea *p);
-
-
-struct VMCSExecCtrlFields {
- uint_t pinCtrls ; // Table 20-5, Vol 3B. (pg. 20-10)
- uint_t procCtrls ; // Table 20-6, Vol 3B. (pg. 20-11)
- uint_t execBitmap ;
- uint_t pageFaultErrorMask ;
- uint_t pageFaultErrorMatch ;
- uint_t ioBitmapA ;
- uint_t ioBitmapB ;
- ullong_t tscOffset ;
- uint_t cr0GuestHostMask ; // Should be 64 bits?
- uint_t cr0ReadShadow ; // Should be 64 bits?
- uint_t cr4GuestHostMask ; // Should be 64 bits?
- uint_t cr4ReadShadow ; // Should be 64 bits?
- uint_t cr3TargetValue0 ; // should be 64 bits?
- uint_t cr3TargetValue1 ; // should be 64 bits?
- uint_t cr3TargetValue2 ; // should be 64 bits?
- uint_t cr3TargetValue3 ; // should be 64 bits?
- uint_t cr3TargetCount ;
-
-
-
- /* these fields enabled if "use TPR shadow"==1 */
- /* may not need them */
- ullong_t virtApicPageAddr ;
- // uint_t virtApicPageAddrHigh
- uint_t tprThreshold ;
- /**/
-
- ullong_t MSRBitmapsBaseAddr;
-
-
- ullong_t vmcsExecPtr ;
-
-};
-
-int CopyOutVMCSExecCtrlFields(struct VMCSExecCtrlFields *p);
-int CopyInVMCSExecCtrlFields(struct VMCSExecCtrlFields *p);
-
-
-
-
-struct VMCSExitCtrlFields {
- uint_t exitCtrls ; // Table 20-7, Vol. 3B (pg. 20-16)
- uint_t msrStoreCount ;
- ullong_t msrStoreAddr ;
- uint_t msrLoadCount ;
- ullong_t msrLoadAddr ;
-};
-
-int CopyOutVMCSExitCtrlFields(struct VMCSExitCtrlFields *p);
-int CopyInVMCSExitCtrlFields(struct VMCSExitCtrlFields *p);
-
-
-
-struct VMCSEntryCtrlFields {
- uint_t entryCtrls ; // Table 20-9, Vol. 3B (pg. 20-18)
- uint_t msrLoadCount ;
- ullong_t msrLoadAddr ;
- uint_t intInfo ; // Table 20-10, Vol. 3B (pg. 20-19)
- uint_t exceptionErrorCode ;
- uint_t instrLength ;
-};
+struct vmcs_msr_entry {
+ uint32_t index;
+ uint32_t rsvd;
+ uint32_t lo;
+ uint32_t hi;
+} __attribute__((packed));
-int CopyOutVMCSEntryCtrlFields(struct VMCSEntryCtrlFields *p);
-int CopyInVMCSEntryCtrlFields(struct VMCSEntryCtrlFields *p);
+struct vmcs_interrupt_state {
+ union {
+ uint32_t val;
+ struct {
+ uint32_t sti_blocking : 1;
+ uint32_t mov_ss_blocking : 1;
+ uint32_t smi_blocking : 1;
+ uint32_t nmi_blocking : 1;
+ uint32_t rsvd1 : 28;
+ } __attribute__((packed));
+ } __attribute__((packed));
+} __attribute__((packed));
-struct VMCSExitInfoFields {
- uint_t reason; // Table 20-11, Vol. 3B (pg. 20-20)
- uint_t qualification ; // Should be 64 bits?
- uint_t intInfo ;
- uint_t intErrorCode ;
- uint_t idtVectorInfo ;
- uint_t idtVectorErrorCode ;
- uint_t instrLength ;
- ullong_t guestLinearAddr ; // Should be 64 bits?
- uint_t instrInfo ;
- ullong_t ioRCX ; // Should be 64 bits?
- ullong_t ioRSI ; // Should be 64 bits?
- ullong_t ioRDI ; // Should be 64 bits?
- ullong_t ioRIP ; // Should be 64 bits?
- uint_t instrErrorField ;
-};
+struct vmcs_data {
+ uint32_t revision ;
+ uint32_t abort ;
+} __attribute__((packed));
-int CopyOutVMCSExitInfoFields(struct VMCSExitInfoFields *p);
+int v3_vmcs_get_field_len(vmcs_field_t field);
-struct VMCSData {
- uint_t revision ;
- uint_t abort ;
- uint_t exitCtrlFlags;
- struct VMCSGuestStateArea guestStateArea ;
- struct VMCSHostStateArea hostStateArea ;
- struct VMCSExecCtrlFields execCtrlFields ;
- struct VMCSExitCtrlFields exitCtrlFields ;
- struct VMCSEntryCtrlFields entryCtrlFields ;
- struct VMCSExitInfoFields exitInfoFields ;
-};
+const char * v3_vmcs_field_to_str(vmcs_field_t field);
+void v3_print_vmcs();
-int CopyOutVMCSData(struct VMCSData *p);
-int CopyInVMCSData(struct VMCSData *p);
-struct VMXRegs {
- uint_t edi;
- uint_t esi;
- uint_t ebp;
- uint_t esp;
- uint_t ebx;
- uint_t edx;
- uint_t ecx;
- uint_t eax;
-};
-
-void PrintTrace_VMX_Regs(struct VMXRegs *regs);
-void PrintTrace_VMCSData(struct VMCSData * vmcs);
-void PrintTrace_VMCSGuestStateArea(struct VMCSGuestStateArea * guestState);
-void PrintTrace_VMCSHostStateArea(struct VMCSHostStateArea * hostState);
-void PrintTrace_VMCSExecCtrlFields(struct VMCSExecCtrlFields * execCtrls);
-void PrintTrace_VMCSExitCtrlFields(struct VMCSExitCtrlFields * exitCtrls);
-void PrintTrace_VMCSEntryCtrlFields(struct VMCSEntryCtrlFields * entryCtrls);
-void PrintTrace_VMCSExitInfoFields(struct VMCSExitInfoFields * exitInfo);
-void PrintTrace_VMCSSegment(char * segname, struct VMCSSegment * seg, int abbr);
+int v3_vmx_save_vmcs(struct guest_info * info);
+int v3_vmx_restore_vmcs(struct guest_info * info);
-VMCS * CreateVMCS();
-extern uint_t VMCS_WRITE();
-extern uint_t VMCS_READ();
-//uint_t VMCSRead(uint_t tag, void * val);
+int v3_update_vmcs_host_state(struct guest_info * info);
+int v3_update_vmcs_ctrl_fields(struct guest_info * info);
-#include <palacios/vmcs_gen.h>
+int v3_read_vmcs_segments(struct v3_segments * segs);
+int v3_write_vmcs_segments(struct v3_segments * segs);
+void v3_vmxseg_to_seg(struct vmcs_segment * vmcs_seg, struct v3_segment * seg);
+void v3_seg_to_vmxseg(struct v3_segment * seg, struct vmcs_segment * vmcs_seg);
#endif // ! __V3VEE__