|
@@ -1,537 +0,0 @@
|
|
|
-use bitflags::bitflags;
|
|
|
-use num_derive::FromPrimitive;
|
|
|
-
|
|
|
-pub const PAGE_SIZE: usize = 0x1000;
|
|
|
-
|
|
|
-#[repr(C, align(4096))]
|
|
|
-#[derive(Clone, Debug)]
|
|
|
-pub struct VMCSRegion {
|
|
|
- pub revision_id: u32,
|
|
|
- pub abort_indicator: u32,
|
|
|
- data: [u8; PAGE_SIZE - 8],
|
|
|
-}
|
|
|
-
|
|
|
-// (Intel Manual: 25.11.2 VMREAD, VMWRITE, and Encodings of VMCS Fields)
|
|
|
-#[derive(FromPrimitive)]
|
|
|
-enum VmcsAccessType {
|
|
|
- FULL = 0,
|
|
|
- HIGH = 1,
|
|
|
-}
|
|
|
-
|
|
|
-#[derive(FromPrimitive)]
|
|
|
-enum VmcsType {
|
|
|
- CONTROL = 0,
|
|
|
- VMEXIT = 1,
|
|
|
- GUEST = 2,
|
|
|
- HOST = 3,
|
|
|
-}
|
|
|
-
|
|
|
-#[derive(FromPrimitive)]
|
|
|
-enum VmcsWidth {
|
|
|
- BIT16 = 0,
|
|
|
- BIT64 = 1,
|
|
|
- BIT32 = 2,
|
|
|
- NATURAL = 3,
|
|
|
-}
|
|
|
-
|
|
|
-#[derive(FromPrimitive)]
|
|
|
-#[allow(non_camel_case_types)]
|
|
|
-// (Intel Manual: APPENDIX B FIELD ENCODING IN VMCS)
|
|
|
-pub enum VmcsFields {
|
|
|
- // [CONTROL] fields
|
|
|
- // 16-bit control fields
|
|
|
- CTRL_VIRT_PROC_ID = encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT16, 0) as isize,
|
|
|
- CTRL_POSTED_INTR_N_VECTOR =
|
|
|
- encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT16, 1) as isize,
|
|
|
- CTRL_EPTP_INDEX = encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT16, 2) as isize,
|
|
|
- // 64-bit control fields
|
|
|
- CTRL_IO_BITMAP_A_ADDR = encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT64, 0) as isize,
|
|
|
- CTRL_IO_BITMAP_B_ADDR = encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT64, 1) as isize,
|
|
|
- CTRL_MSR_BITMAP_ADDR = encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT64, 2) as isize, // control whether RDMSR or WRMSR cause VM exit
|
|
|
- CTRL_VMEXIT_MSR_STORE_ADDR =
|
|
|
- encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT64, 3) as isize,
|
|
|
- CTRL_VMEXIT_MSR_LOAD_ADDR =
|
|
|
- encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT64, 4) as isize,
|
|
|
- CTRL_VMENTRY_MSR_LOAD_ADDR =
|
|
|
- encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT64, 5) as isize,
|
|
|
- CTRL_EXECUTIVE_VMCS_PTR =
|
|
|
- encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT64, 6) as isize,
|
|
|
- CTRL_PML_ADDR = encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT64, 7) as isize,
|
|
|
- CTRL_TSC_ADDR = encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT64, 8) as isize,
|
|
|
- CTRL_VIRT_APIC_ADDR = encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT64, 9) as isize,
|
|
|
- CTRL_APIC_ACCESS_ADDR =
|
|
|
- encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT64, 10) as isize,
|
|
|
- CTRL_POSTED_INTR_DESC_ADDR =
|
|
|
- encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT64, 11) as isize,
|
|
|
- CTRL_VMFUNC_CTRL = encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT64, 12) as isize,
|
|
|
- CTRL_EPTP_PTR = encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT64, 13) as isize,
|
|
|
- CTRL_EOI_EXIT_BITMAP_0 =
|
|
|
- encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT64, 14) as isize,
|
|
|
- CTRL_EOI_EXIT_BITMAP_1 =
|
|
|
- encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT64, 15) as isize,
|
|
|
- CTRL_EOI_EXIT_BITMAP_2 =
|
|
|
- encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT64, 16) as isize,
|
|
|
- CTRL_EOI_EXIT_BITMAP_3 =
|
|
|
- encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT64, 17) as isize,
|
|
|
- CTRL_EPT_LIST_ADDR = encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT64, 18) as isize,
|
|
|
- CTRL_VMREAD_BITMAP_ADDR =
|
|
|
- encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT64, 19) as isize,
|
|
|
- CTRL_VMWRITE_BITMAP_ADDR =
|
|
|
- encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT64, 20) as isize,
|
|
|
- CTRL_VIRT_EXECPT_INFO_ADDR =
|
|
|
- encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT64, 21) as isize,
|
|
|
- CTRL_XSS_EXITING_BITMAP =
|
|
|
- encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT64, 22) as isize,
|
|
|
- CTRL_ENCLS_EXITING_BITMAP =
|
|
|
- encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT64, 23) as isize,
|
|
|
- CTRL_TSC_MULTIPLIER = encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT64, 25) as isize,
|
|
|
- // 32-bit control fields
|
|
|
- CTRL_PIN_BASED_VM_EXEC_CTRLS =
|
|
|
- encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT32, 0) as isize, // control async event handling (i.e. interrupts)
|
|
|
- CTRL_PRIMARY_PROCESSOR_VM_EXEC_CTRLS =
|
|
|
- encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT32, 1) as isize, // control sync event handling (i.e. instruction exits)
|
|
|
- CTRL_EXPECTION_BITMAP = encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT32, 2) as isize, // bitmap to control exceptions that cause a VM exit
|
|
|
- CTRL_PAGE_FAULT_ERR_CODE_MASK =
|
|
|
- encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT32, 3) as isize,
|
|
|
- CTRL_PAGE_FAULT_ERR_CODE_MATCH =
|
|
|
- encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT32, 4) as isize,
|
|
|
- CTRL_CR3_TARGET_COUNT = encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT32, 5) as isize,
|
|
|
- CTRL_PRIMARY_VM_EXIT_CTRLS =
|
|
|
- encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT32, 6) as isize,
|
|
|
- CTRL_VM_EXIT_MSR_STORE_COUNT =
|
|
|
- encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT32, 7) as isize,
|
|
|
- CTRL_VM_EXIT_MSR_LOAD_COUNT =
|
|
|
- encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT32, 8) as isize,
|
|
|
- CTRL_VM_ENTRY_CTRLS = encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT32, 9) as isize,
|
|
|
- CTRL_VM_ENTRY_MSR_LOAD_COUNT =
|
|
|
- encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT32, 10) as isize,
|
|
|
- CTRL_VM_ENTRY_INTR_INFO_FIELD =
|
|
|
- encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT32, 11) as isize,
|
|
|
- CTRL_VM_ENTRY_EXCEPTION_ERR_CODE =
|
|
|
- encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT32, 12) as isize,
|
|
|
- CTRL_VM_ENTRY_INSTR_LEN =
|
|
|
- encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT32, 13) as isize,
|
|
|
- CTRL_TPR_THRESHOLD = encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT32, 14) as isize,
|
|
|
- CTRL_SECONDARY_PROCESSOR_VM_EXEC_CTRLS =
|
|
|
- encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT32, 15) as isize,
|
|
|
- CTRL_PLE_GAP = encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT32, 16) as isize,
|
|
|
- CTRL_PLE_WINDOW = encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT32, 17) as isize,
|
|
|
- // natural control fields
|
|
|
- CTRL_CR0_GUEST_HOST_MASK =
|
|
|
- encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::NATURAL, 0) as isize, // control executions of insts that access cr0
|
|
|
- CTRL_CR4_GUEST_HOST_MASK =
|
|
|
- encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::NATURAL, 1) as isize,
|
|
|
- CTRL_CR0_READ_SHADOW =
|
|
|
- encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::NATURAL, 2) as isize, // control executions of insts that access cr0
|
|
|
- CTRL_CR4_READ_SHADOW =
|
|
|
- encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::NATURAL, 3) as isize,
|
|
|
- CTRL_CR3_TARGET_VALUE_0 =
|
|
|
- encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::NATURAL, 4) as isize,
|
|
|
- CTRL_CR3_TARGET_VALUE_1 =
|
|
|
- encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::NATURAL, 5) as isize,
|
|
|
- CTRL_CR3_TARGET_VALUE_2 =
|
|
|
- encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::NATURAL, 6) as isize,
|
|
|
- CTRL_CR3_TARGET_VALUE_3 =
|
|
|
- encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::NATURAL, 7) as isize,
|
|
|
-
|
|
|
- // [VMEXIT] fields read-only
|
|
|
- // No 16-bit vmexit fields
|
|
|
- // 64-bit vmexit fields
|
|
|
- VMEXIT_GUEST_PHY_ADDR = encode_vmcs_field_full(VmcsType::VMEXIT, VmcsWidth::BIT64, 0) as isize,
|
|
|
- // 32-bit vmexit fields
|
|
|
- VMEXIT_INSTR_ERR = encode_vmcs_field_full(VmcsType::VMEXIT, VmcsWidth::BIT32, 0) as isize,
|
|
|
- VMEXIT_EXIT_REASON = encode_vmcs_field_full(VmcsType::VMEXIT, VmcsWidth::BIT32, 1) as isize,
|
|
|
- VMEXIT_INT_INFO = encode_vmcs_field_full(VmcsType::VMEXIT, VmcsWidth::BIT32, 2) as isize,
|
|
|
- VMEXIT_INT_ERR_CODE = encode_vmcs_field_full(VmcsType::VMEXIT, VmcsWidth::BIT32, 3) as isize,
|
|
|
- VMEXIT_IDT_VECTOR_INFO = encode_vmcs_field_full(VmcsType::VMEXIT, VmcsWidth::BIT32, 4) as isize,
|
|
|
- VMEXIT_IDT_VECTOR_ERR_CODE =
|
|
|
- encode_vmcs_field_full(VmcsType::VMEXIT, VmcsWidth::BIT32, 5) as isize,
|
|
|
- VMEXIT_INSTR_LEN = encode_vmcs_field_full(VmcsType::VMEXIT, VmcsWidth::BIT32, 6) as isize,
|
|
|
- VMEXIT_INSTR_INFO = encode_vmcs_field_full(VmcsType::VMEXIT, VmcsWidth::BIT32, 7) as isize,
|
|
|
- // natural vmexit fields
|
|
|
- VMEXIT_QUALIFICATION = encode_vmcs_field_full(VmcsType::VMEXIT, VmcsWidth::NATURAL, 0) as isize,
|
|
|
- VMEXIT_IO_RCX = encode_vmcs_field_full(VmcsType::VMEXIT, VmcsWidth::NATURAL, 1) as isize,
|
|
|
- VMEXIT_IO_RSX = encode_vmcs_field_full(VmcsType::VMEXIT, VmcsWidth::NATURAL, 2) as isize,
|
|
|
- VMEXIT_IO_RDI = encode_vmcs_field_full(VmcsType::VMEXIT, VmcsWidth::NATURAL, 3) as isize,
|
|
|
- VMEXIT_IO_RIP = encode_vmcs_field_full(VmcsType::VMEXIT, VmcsWidth::NATURAL, 4) as isize,
|
|
|
- VMEXIT_GUEST_LINEAR_ADDR =
|
|
|
- encode_vmcs_field_full(VmcsType::VMEXIT, VmcsWidth::NATURAL, 5) as isize,
|
|
|
-
|
|
|
- // [GUEST] fields
|
|
|
- // 16-bit guest fields
|
|
|
- GUEST_ES_SELECTOR = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::BIT16, 0) as isize,
|
|
|
- GUEST_CS_SELECTOR = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::BIT16, 1) as isize,
|
|
|
- GUEST_SS_SELECTOR = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::BIT16, 2) as isize,
|
|
|
- GUEST_DS_SELECTOR = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::BIT16, 3) as isize,
|
|
|
- GUEST_FS_SELECTOR = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::BIT16, 4) as isize,
|
|
|
- GUEST_GS_SELECTOR = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::BIT16, 5) as isize,
|
|
|
- GUEST_LDTR_SELECTOR = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::BIT16, 6) as isize,
|
|
|
- GUEST_TR_SELECTOR = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::BIT16, 7) as isize,
|
|
|
- GUEST_INTR_STATUS = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::BIT16, 8) as isize,
|
|
|
- GUEST_PML_INDEX = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::BIT16, 9) as isize,
|
|
|
- // 64-bit guest fields
|
|
|
- GUEST_VMCS_LINK_PTR = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::BIT64, 0) as isize,
|
|
|
- GUEST_DEBUGCTL = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::BIT64, 1) as isize,
|
|
|
- GUEST_PAT = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::BIT64, 2) as isize,
|
|
|
- GUEST_EFER = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::BIT64, 3) as isize,
|
|
|
- GUEST_PERF_GLOBAL_CTRL = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::BIT64, 4) as isize,
|
|
|
- GUEST_PDPTE0 = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::BIT64, 5) as isize,
|
|
|
- GUEST_PDPTE1 = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::BIT64, 6) as isize,
|
|
|
- GUEST_PDPTE2 = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::BIT64, 7) as isize,
|
|
|
- GUEST_PDPTE3 = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::BIT64, 8) as isize,
|
|
|
- // 32-bit guest fields
|
|
|
- GUEST_ES_LIMIT = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::BIT32, 0) as isize,
|
|
|
- GUEST_CS_LIMIT = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::BIT32, 1) as isize,
|
|
|
- GUEST_SS_LIMIT = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::BIT32, 2) as isize,
|
|
|
- GUEST_DS_LIMIT = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::BIT32, 3) as isize,
|
|
|
- GUEST_FS_LIMIT = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::BIT32, 4) as isize,
|
|
|
- GUEST_GS_LIMIT = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::BIT32, 5) as isize,
|
|
|
- GUEST_LDTR_LIMIT = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::BIT32, 6) as isize,
|
|
|
- GUEST_TR_LIMIT = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::BIT32, 7) as isize,
|
|
|
- GUEST_GDTR_LIMIT = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::BIT32, 8) as isize,
|
|
|
- GUEST_IDTR_LIMIT = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::BIT32, 9) as isize,
|
|
|
- GUEST_ES_ACCESS_RIGHTS = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::BIT32, 10) as isize,
|
|
|
- GUEST_CS_ACCESS_RIGHTS = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::BIT32, 11) as isize,
|
|
|
- GUEST_SS_ACCESS_RIGHTS = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::BIT32, 12) as isize,
|
|
|
- GUEST_DS_ACCESS_RIGHTS = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::BIT32, 13) as isize,
|
|
|
- GUEST_FS_ACCESS_RIGHTS = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::BIT32, 14) as isize,
|
|
|
- GUEST_GS_ACCESS_RIGHTS = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::BIT32, 15) as isize,
|
|
|
- GUEST_LDTR_ACCESS_RIGHTS =
|
|
|
- encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::BIT32, 16) as isize,
|
|
|
- GUEST_TR_ACCESS_RIGHTS = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::BIT32, 17) as isize,
|
|
|
- GUEST_INTERRUPTIBILITY_STATE =
|
|
|
- encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::BIT32, 18) as isize,
|
|
|
- GUEST_ACTIVITY_STATE = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::BIT32, 19) as isize,
|
|
|
- GUEST_SMBASE = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::BIT32, 20) as isize,
|
|
|
- GUEST_SYSENTER_CS = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::BIT32, 21) as isize,
|
|
|
- GUEST_VMX_PREEMPT_TIMER_VALUE = 0x482E_isize,
|
|
|
- // natural guest fields
|
|
|
- GUEST_CR0 = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::NATURAL, 0) as isize,
|
|
|
- GUEST_CR3 = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::NATURAL, 1) as isize,
|
|
|
- GUEST_CR4 = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::NATURAL, 2) as isize,
|
|
|
- GUEST_ES_BASE = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::NATURAL, 3) as isize,
|
|
|
- GUEST_CS_BASE = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::NATURAL, 4) as isize,
|
|
|
- GUEST_SS_BASE = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::NATURAL, 5) as isize,
|
|
|
- GUEST_DS_BASE = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::NATURAL, 6) as isize,
|
|
|
- GUEST_FS_BASE = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::NATURAL, 7) as isize,
|
|
|
- GUEST_GS_BASE = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::NATURAL, 8) as isize,
|
|
|
- GUEST_LDTR_BASE = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::NATURAL, 9) as isize,
|
|
|
- GUEST_TR_BASE = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::NATURAL, 10) as isize,
|
|
|
- GUEST_GDTR_BASE = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::NATURAL, 11) as isize,
|
|
|
- GUEST_IDTR_BASE = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::NATURAL, 12) as isize,
|
|
|
- GUEST_DR7 = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::NATURAL, 13) as isize,
|
|
|
- GUEST_RSP = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::NATURAL, 14) as isize,
|
|
|
- GUEST_RIP = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::NATURAL, 15) as isize,
|
|
|
- GUEST_RFLAGS = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::NATURAL, 16) as isize,
|
|
|
- GUEST_PENDING_DBG_EXCEPTIONS =
|
|
|
- encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::NATURAL, 17) as isize,
|
|
|
- GUEST_SYSENTER_ESP = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::NATURAL, 18) as isize,
|
|
|
- GUEST_SYSENTER_EIP = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::NATURAL, 19) as isize,
|
|
|
-
|
|
|
- // [HOST] fields
|
|
|
- // host 16 bit fields
|
|
|
- HOST_ES_SELECTOR = encode_vmcs_field_full(VmcsType::HOST, VmcsWidth::BIT16, 0) as isize,
|
|
|
- HOST_CS_SELECTOR = encode_vmcs_field_full(VmcsType::HOST, VmcsWidth::BIT16, 1) as isize,
|
|
|
- HOST_SS_SELECTOR = encode_vmcs_field_full(VmcsType::HOST, VmcsWidth::BIT16, 2) as isize,
|
|
|
- HOST_DS_SELECTOR = encode_vmcs_field_full(VmcsType::HOST, VmcsWidth::BIT16, 3) as isize,
|
|
|
- HOST_FS_SELECTOR = encode_vmcs_field_full(VmcsType::HOST, VmcsWidth::BIT16, 4) as isize,
|
|
|
- HOST_GS_SELECTOR = encode_vmcs_field_full(VmcsType::HOST, VmcsWidth::BIT16, 5) as isize,
|
|
|
- HOST_TR_SELECTOR = encode_vmcs_field_full(VmcsType::HOST, VmcsWidth::BIT16, 6) as isize,
|
|
|
- // host 64 bit fields
|
|
|
- HOST_PAT = encode_vmcs_field_full(VmcsType::HOST, VmcsWidth::BIT64, 0) as isize,
|
|
|
- HOST_EFER = encode_vmcs_field_full(VmcsType::HOST, VmcsWidth::BIT64, 1) as isize,
|
|
|
- HOST_PERF_GLOBAL_CTRL = encode_vmcs_field_full(VmcsType::HOST, VmcsWidth::BIT64, 2) as isize,
|
|
|
- // host 32 bit fields
|
|
|
- HOST_SYSENTER_CS = encode_vmcs_field_full(VmcsType::HOST, VmcsWidth::BIT32, 0) as isize,
|
|
|
- // host natural fields
|
|
|
- HOST_CR0 = encode_vmcs_field_full(VmcsType::HOST, VmcsWidth::NATURAL, 0) as isize,
|
|
|
- HOST_CR3 = encode_vmcs_field_full(VmcsType::HOST, VmcsWidth::NATURAL, 1) as isize,
|
|
|
- HOST_CR4 = encode_vmcs_field_full(VmcsType::HOST, VmcsWidth::NATURAL, 2) as isize,
|
|
|
- HOST_FS_BASE = encode_vmcs_field_full(VmcsType::HOST, VmcsWidth::NATURAL, 3) as isize,
|
|
|
- HOST_GS_BASE = encode_vmcs_field_full(VmcsType::HOST, VmcsWidth::NATURAL, 4) as isize,
|
|
|
- HOST_TR_BASE = encode_vmcs_field_full(VmcsType::HOST, VmcsWidth::NATURAL, 5) as isize,
|
|
|
- HOST_GDTR_BASE = encode_vmcs_field_full(VmcsType::HOST, VmcsWidth::NATURAL, 6) as isize,
|
|
|
- HOST_IDTR_BASE = encode_vmcs_field_full(VmcsType::HOST, VmcsWidth::NATURAL, 7) as isize,
|
|
|
- HOST_SYSENTER_ESP = encode_vmcs_field_full(VmcsType::HOST, VmcsWidth::NATURAL, 8) as isize,
|
|
|
- HOST_SYSENTER_EIP = encode_vmcs_field_full(VmcsType::HOST, VmcsWidth::NATURAL, 9) as isize,
|
|
|
- HOST_RSP = encode_vmcs_field_full(VmcsType::HOST, VmcsWidth::NATURAL, 10) as isize,
|
|
|
- HOST_RIP = encode_vmcs_field_full(VmcsType::HOST, VmcsWidth::NATURAL, 11) as isize,
|
|
|
-}
|
|
|
-
|
|
|
-// (Intel Manual: 25.6 VM-EXECUTION CONTROL FIELDS)
|
|
|
-bitflags! {
|
|
|
- // (Intel Manual: 25.6.1 Pin-Based VM-Execution Controls)
|
|
|
- #[allow(non_camel_case_types)]
|
|
|
- pub struct VmxPinBasedExecuteCtrl: u32 {
|
|
|
- const EXTERNAL_INTERRUPT_EXITING = 1 << 0; // external interrupts cause VM exits
|
|
|
- const NMI_EXITING = 1 << 3; // non-maskable interrupts (NMIs) cause VM exits.
|
|
|
- const VIRTUAL_NMIS = 1 << 5; // NMIs are never blocked and the “blocking by NMI” bit (bit 3) in the interruptibility-state field indicates “virtual-NMI blocking”
|
|
|
- const VMX_PREEMPTION_TIMER = 1 << 6; // the VMX-preemption timer counts down in VMX non-root operation
|
|
|
- const PROCESS_POSTED_INTERRUPTS = 1 << 7; // he processor treats interrupts with the posted-interrupt notification vector
|
|
|
- }
|
|
|
-
|
|
|
- // (Intel Manual: 25.6.2 Processor-Based VM-Execution Controls)
|
|
|
- #[allow(non_camel_case_types)]
|
|
|
- pub struct VmxPrimaryProcessBasedExecuteCtrl: u32{
|
|
|
- const INTERRUPT_WINDOW_EXITING = 1 << 2; // VM exits on interrupt window RFLAGS.IF = 1
|
|
|
- const USE_TSC_OFFSETTING = 1 << 3; // TSC offsetting is enabled
|
|
|
- const HLT_EXITING = 1 << 7;
|
|
|
- const INVLPG_EXITING = 1 << 9;
|
|
|
- const MWAIT_EXITING = 1 << 10;
|
|
|
- const RDPMC_EXITING = 1 << 11;
|
|
|
- const RDTSC_EXITING = 1 << 12;
|
|
|
- const CR3_LOAD_EXITING = 1 << 15;
|
|
|
- const CR3_STR_EXITING = 1 << 16;
|
|
|
- const CR8_LOAD_EXITING = 1 << 19;
|
|
|
- const CR8_STR_EXITING = 1 << 20;
|
|
|
- const USE_TPR_SHADOW = 1 << 21;
|
|
|
- const NMI_WINDOW_EXITING = 1 << 22;
|
|
|
- const MOV_DR_EXITING = 1 << 23;
|
|
|
- const UNCOND_IO_EXITING = 1 << 24;
|
|
|
- const USE_IO_BITMAPS = 1 << 25;
|
|
|
- const MONITOR_TRAP_FLAG = 1 << 27;
|
|
|
- const USE_MSR_BITMAPS = 1 << 28;
|
|
|
- const MONITOR_EXITING = 1 << 29;
|
|
|
- const PAUSE_EXITING = 1 << 30;
|
|
|
- const ACTIVATE_SECONDARY_CONTROLS = 1 << 31;
|
|
|
- }
|
|
|
-
|
|
|
- // (Intel Manual: 25.6.2 Processor-Based VM-Execution Controls)
|
|
|
- pub struct VmxSecondaryProcessBasedExecuteCtrl: u32{
|
|
|
- const VIRT_APIC_ACCESS = 1 << 0;
|
|
|
- const ENABLE_EPT = 1 << 1;
|
|
|
- const DESCRIPTOR_TABLE_EXITING = 1 << 2;
|
|
|
- const ENABLE_RDTSCP = 1 << 3;
|
|
|
- const VIRT_X2APIC_MODE = 1 << 4;
|
|
|
- const ENABLE_VPID = 1 << 5;
|
|
|
- const WBINVD_EXITING = 1 << 6;
|
|
|
- const UNRESTRICTED_GUEST = 1 << 7;
|
|
|
- const APCI_REGISTER_VIRT = 1 << 8;
|
|
|
- const VIRT_INTR_DELIVERY = 1 << 9;
|
|
|
- const PAUSE_LOOP_EXITING = 1 << 10;
|
|
|
- const RDRAND_EXITING = 1 << 11;
|
|
|
- const ENABLE_INVPCID = 1 << 12;
|
|
|
- const ENABLE_VM_FUNCTIONS = 1 << 13;
|
|
|
- const VMCS_SHADOWING = 1 << 14;
|
|
|
- const ENABLE_ENCLS_EXITING = 1 << 15;
|
|
|
- const RDSEED_EXITING = 1 << 16;
|
|
|
- const ENABLE_PML = 1 << 17;
|
|
|
- const EPT_VIOLATION_VE = 1 << 18;
|
|
|
- const CONCEAL_VMX_FROM_PT = 1 << 19;
|
|
|
- const ENABLE_XSAVES_XRSTORS = 1 << 20;
|
|
|
- const PASID_TRANSLATION = 1 << 21;
|
|
|
- const MODE_BASED_EPT_EXEC = 1 << 22;
|
|
|
- const SUB_PAGE_WRITE_PERM = 1 << 23;
|
|
|
- const PT_USE_GUEST_PYH_ADDR = 1 << 24;
|
|
|
- const USE_TSC_SCALING = 1 << 25;
|
|
|
- const ENABLE_USER_WAIT_PAUSE = 1 << 26;
|
|
|
- const ENABLE_PCONFIG = 1 << 27;
|
|
|
- const ENABLE_ENCLV_EXITING = 1 << 28;
|
|
|
- const VMM_BUS_LOCK_DETECTION = 1 << 30;
|
|
|
- const INST_TIMEOUT = 1 << 31;
|
|
|
- }
|
|
|
-
|
|
|
- // (Intel Manual: 25.7.1 VM-Exit Controls)
|
|
|
- #[allow(non_camel_case_types)]
|
|
|
- pub struct VmxPrimaryExitCtrl: u32 {
|
|
|
- const SAVE_DBG_CTRLS = 1 << 2;
|
|
|
- const HOST_ADDR_SPACE_SIZE = 1 << 9; // determines if a virtual processor will be in 64-bit mode after a VM exit
|
|
|
- const LOAD_IA32_PERF_GLOBAL_CTRL = 1 << 12;
|
|
|
- const ACK_INTERRUPT_ON_EXIT = 1 << 15;
|
|
|
- const SAVE_IA32_PAT = 1 << 18;
|
|
|
- const LOAD_IA32_PAT = 1 << 19;
|
|
|
- const SAVE_IA32_EFER = 1 << 20;
|
|
|
- const LOAD_IA32_EFER = 1 << 21;
|
|
|
- const SAVE_VMX_PREEMPT_TIMER_VALUE = 1 << 22;
|
|
|
- const CLEAR_IA32_BNDCFGS = 1 << 23;
|
|
|
- const CONCEAL_VMX_FROM_PT = 1 << 24;
|
|
|
- const CLEAR_IA32_RTIT_CTL = 1 << 25;
|
|
|
- const CLEAR_IA32_LBR_CTL = 1 << 26;
|
|
|
- const CLEAR_UINV = 1 << 27;
|
|
|
- const LOAD_CET_STATE = 1 << 28;
|
|
|
- const LOAD_PKRS = 1 << 29;
|
|
|
- const SAVE_IA32_PERF_GLOBAL_CTL = 1 << 30;
|
|
|
- const ACTIVATE_SECONDARY_CONTROLS = 1 << 31;
|
|
|
- }
|
|
|
-
|
|
|
- // (Intel Manual: 25.8.1 VM-Entry Controls)
|
|
|
- #[allow(non_camel_case_types)]
|
|
|
- pub struct VmxEntryCtrl: u32 {
|
|
|
- const LOAD_DBG_CTRLS = 1 << 2;
|
|
|
- const IA32E_MODE_GUEST = 1 << 9;
|
|
|
- const ENTRY_TO_SMM = 1 << 10;
|
|
|
- const DEACTIVATE_DUAL_MONITOR = 1 << 11;
|
|
|
- const LOAD_IA32_PERF_GLOBAL_CTRL = 1 << 13;
|
|
|
- const LOAD_IA32_PAT = 1 << 14;
|
|
|
- const LOAD_IA32_EFER = 1 << 15;
|
|
|
- const LOAD_IA32_BNDCFGS = 1 << 16;
|
|
|
- const CONCEAL_VMX_FROM_PT = 1 << 17;
|
|
|
- const LOAD_IA32_RTIT_CTL = 1 << 18;
|
|
|
- const LOAD_UINV = 1 << 19;
|
|
|
- const LOAD_CET_STATE = 1 << 20;
|
|
|
- const LOAD_PKRS = 1 << 21;
|
|
|
- const LOAD_IA32_PERF_GLOBAL_CTL = 1 << 22;
|
|
|
- }
|
|
|
-
|
|
|
-}
|
|
|
-
|
|
|
-#[derive(FromPrimitive)]
|
|
|
-#[allow(non_camel_case_types)]
|
|
|
-pub enum VmxExitReason {
|
|
|
- EXCEPTION_OR_NMI = 0,
|
|
|
- EXTERNAL_INTERRUPT = 1,
|
|
|
- TRIPLE_FAULT = 2,
|
|
|
- INIT_SIGNAL = 3,
|
|
|
- SIPI = 4,
|
|
|
- IO_SMI = 5,
|
|
|
- OTHER_SMI = 6,
|
|
|
- INTERRUPT_WINDOW = 7,
|
|
|
- NMI_WINDOW = 8,
|
|
|
- TASK_SWITCH = 9,
|
|
|
- CPUID = 10,
|
|
|
- GETSEC = 11,
|
|
|
- HLT = 12,
|
|
|
- INVD = 13,
|
|
|
- INVLPG = 14,
|
|
|
- RDPMC = 15,
|
|
|
- RDTSC = 16,
|
|
|
- RSM = 17,
|
|
|
- VMCALL = 18,
|
|
|
- VMCLEAR = 19,
|
|
|
- VMLAUNCH = 20,
|
|
|
- VMPTRLD = 21,
|
|
|
- VMPTRST = 22,
|
|
|
- VMREAD = 23,
|
|
|
- VMRESUME = 24,
|
|
|
- VMWRITE = 25,
|
|
|
- VMXOFF = 26,
|
|
|
- VMXON = 27,
|
|
|
- CR_ACCESS = 28,
|
|
|
- DR_ACCESS = 29,
|
|
|
- IO_INSTRUCTION = 30,
|
|
|
- RDMSR = 31,
|
|
|
- WRMSR = 32,
|
|
|
- VM_ENTRY_FAILURE_INVALID_GUEST_STATE = 33,
|
|
|
- VM_ENTRY_FAILURE_MSR_LOADING = 34,
|
|
|
- MWAIT = 36,
|
|
|
- MONITOR_TRAP_FLAG = 37,
|
|
|
- MONITOR = 39,
|
|
|
- PAUSE = 40,
|
|
|
- VM_ENTRY_FAILURE_MACHINE_CHECK_EVENT = 41,
|
|
|
- TPR_BELOW_THRESHOLD = 43,
|
|
|
- APIC_ACCESS = 44,
|
|
|
- VIRTUALIZED_EOI = 45,
|
|
|
- ACCESS_GDTR_OR_IDTR = 46,
|
|
|
- ACCESS_LDTR_OR_TR = 47,
|
|
|
- EPT_VIOLATION = 48,
|
|
|
- EPT_MISCONFIG = 49,
|
|
|
- INVEPT = 50,
|
|
|
- RDTSCP = 51,
|
|
|
- VMX_PREEMPTION_TIMER_EXPIRED = 52,
|
|
|
- INVVPID = 53,
|
|
|
- WBINVD = 54,
|
|
|
- XSETBV = 55,
|
|
|
- APIC_WRITE = 56,
|
|
|
- RDRAND = 57,
|
|
|
- INVPCID = 58,
|
|
|
- VMFUNC = 59,
|
|
|
- ENCLS = 60,
|
|
|
- RDSEED = 61,
|
|
|
- PML_FULL = 62,
|
|
|
- XSAVES = 63,
|
|
|
- XRSTORS = 64,
|
|
|
-}
|
|
|
-
|
|
|
-impl From<i32> for VmxExitReason {
|
|
|
- fn from(num: i32) -> Self {
|
|
|
- match num {
|
|
|
- 0 => VmxExitReason::EXCEPTION_OR_NMI,
|
|
|
- 1 => VmxExitReason::EXTERNAL_INTERRUPT,
|
|
|
- 2 => VmxExitReason::TRIPLE_FAULT,
|
|
|
- 3 => VmxExitReason::INIT_SIGNAL,
|
|
|
- 4 => VmxExitReason::SIPI,
|
|
|
- 5 => VmxExitReason::IO_SMI,
|
|
|
- 6 => VmxExitReason::OTHER_SMI,
|
|
|
- 7 => VmxExitReason::INTERRUPT_WINDOW,
|
|
|
- 8 => VmxExitReason::NMI_WINDOW,
|
|
|
- 9 => VmxExitReason::TASK_SWITCH,
|
|
|
- 10 => VmxExitReason::CPUID,
|
|
|
- 11 => VmxExitReason::GETSEC,
|
|
|
- 12 => VmxExitReason::HLT,
|
|
|
- 13 => VmxExitReason::INVD,
|
|
|
- 14 => VmxExitReason::INVLPG,
|
|
|
- 15 => VmxExitReason::RDPMC,
|
|
|
- 16 => VmxExitReason::RDTSC,
|
|
|
- 17 => VmxExitReason::RSM,
|
|
|
- 18 => VmxExitReason::VMCALL,
|
|
|
- 19 => VmxExitReason::VMCLEAR,
|
|
|
- 20 => VmxExitReason::VMLAUNCH,
|
|
|
- 21 => VmxExitReason::VMPTRLD,
|
|
|
- 22 => VmxExitReason::VMPTRST,
|
|
|
- 23 => VmxExitReason::VMREAD,
|
|
|
- 24 => VmxExitReason::VMRESUME,
|
|
|
- 25 => VmxExitReason::VMWRITE,
|
|
|
- 26 => VmxExitReason::VMXOFF,
|
|
|
- 27 => VmxExitReason::VMXON,
|
|
|
- 28 => VmxExitReason::CR_ACCESS,
|
|
|
- 29 => VmxExitReason::DR_ACCESS,
|
|
|
- 30 => VmxExitReason::IO_INSTRUCTION,
|
|
|
- 31 => VmxExitReason::RDMSR,
|
|
|
- 32 => VmxExitReason::WRMSR,
|
|
|
- 33 => VmxExitReason::VM_ENTRY_FAILURE_INVALID_GUEST_STATE,
|
|
|
- 34 => VmxExitReason::VM_ENTRY_FAILURE_MSR_LOADING,
|
|
|
- 36 => VmxExitReason::MWAIT,
|
|
|
- 37 => VmxExitReason::MONITOR_TRAP_FLAG,
|
|
|
- 39 => VmxExitReason::MONITOR,
|
|
|
- 40 => VmxExitReason::PAUSE,
|
|
|
- 41 => VmxExitReason::VM_ENTRY_FAILURE_MACHINE_CHECK_EVENT,
|
|
|
- 43 => VmxExitReason::TPR_BELOW_THRESHOLD,
|
|
|
- 44 => VmxExitReason::APIC_ACCESS,
|
|
|
- 45 => VmxExitReason::VIRTUALIZED_EOI,
|
|
|
- 46 => VmxExitReason::ACCESS_GDTR_OR_IDTR,
|
|
|
- 47 => VmxExitReason::ACCESS_LDTR_OR_TR,
|
|
|
- 48 => VmxExitReason::EPT_VIOLATION,
|
|
|
- 49 => VmxExitReason::EPT_MISCONFIG,
|
|
|
- 50 => VmxExitReason::INVEPT,
|
|
|
- 51 => VmxExitReason::RDTSCP,
|
|
|
- 52 => VmxExitReason::VMX_PREEMPTION_TIMER_EXPIRED,
|
|
|
- 53 => VmxExitReason::INVVPID,
|
|
|
- 54 => VmxExitReason::WBINVD,
|
|
|
- 55 => VmxExitReason::XSETBV,
|
|
|
- 56 => VmxExitReason::APIC_WRITE,
|
|
|
- 57 => VmxExitReason::RDRAND,
|
|
|
- 58 => VmxExitReason::INVPCID,
|
|
|
- 59 => VmxExitReason::VMFUNC,
|
|
|
- 60 => VmxExitReason::ENCLS,
|
|
|
- 61 => VmxExitReason::RDSEED,
|
|
|
- 62 => VmxExitReason::PML_FULL,
|
|
|
- 63 => VmxExitReason::XSAVES,
|
|
|
- 64 => VmxExitReason::XRSTORS,
|
|
|
- _ => panic!("Invalid VmxExitReason number: {}", num),
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-const fn encode_vmcs_field(
|
|
|
- access_type: VmcsAccessType,
|
|
|
- vmcs_type: VmcsType,
|
|
|
- vmcs_width: VmcsWidth,
|
|
|
- index: u32,
|
|
|
-) -> u32 {
|
|
|
- let mut encoding: u32 = 0;
|
|
|
- encoding |=
|
|
|
- (access_type as u32) | (index) << 1 | (vmcs_type as u32) << 10 | (vmcs_width as u32) << 13;
|
|
|
- return encoding;
|
|
|
-}
|
|
|
-
|
|
|
-const fn encode_vmcs_field_full(vmcs_type: VmcsType, vmcs_width: VmcsWidth, index: u32) -> u32 {
|
|
|
- encode_vmcs_field(VmcsAccessType::FULL, vmcs_type, vmcs_width, index)
|
|
|
-}
|
|
|
-
|
|
|
-// fn decode_vmcs_field(field: u32) -> (VmcsAccessType, VmcsType, VmcsWidth, u16){
|
|
|
-// (FromPrimitive::from_u32(field & 1).unwrap() ,
|
|
|
-// FromPrimitive::from_u32((field>>10) & 0x3).unwrap(),
|
|
|
-// FromPrimitive::from_u32((field>>13) & 0x3).unwrap(),
|
|
|
-// ((field>>1) & 0x1ff) as u16
|
|
|
-// )
|
|
|
-// }
|