140314b30SXiaoye Zheng use bitflags::bitflags;
240314b30SXiaoye Zheng use num_derive::FromPrimitive;
340314b30SXiaoye Zheng
440314b30SXiaoye Zheng pub const PAGE_SIZE: usize = 0x1000;
540314b30SXiaoye Zheng
640314b30SXiaoye Zheng #[repr(C, align(4096))]
740314b30SXiaoye Zheng #[derive(Clone, Debug)]
840314b30SXiaoye Zheng pub struct VMCSRegion {
940314b30SXiaoye Zheng pub revision_id: u32,
1040314b30SXiaoye Zheng pub abort_indicator: u32,
1140314b30SXiaoye Zheng data: [u8; PAGE_SIZE - 8],
1240314b30SXiaoye Zheng }
1340314b30SXiaoye Zheng
1440314b30SXiaoye Zheng // (Intel Manual: 25.11.2 VMREAD, VMWRITE, and Encodings of VMCS Fields)
1540314b30SXiaoye Zheng #[derive(FromPrimitive)]
1640314b30SXiaoye Zheng enum VmcsAccessType {
1740314b30SXiaoye Zheng FULL = 0,
1840314b30SXiaoye Zheng HIGH = 1,
1940314b30SXiaoye Zheng }
2040314b30SXiaoye Zheng
2140314b30SXiaoye Zheng #[derive(FromPrimitive)]
2240314b30SXiaoye Zheng enum VmcsType {
2340314b30SXiaoye Zheng CONTROL = 0,
2440314b30SXiaoye Zheng VMEXIT = 1,
2540314b30SXiaoye Zheng GUEST = 2,
2640314b30SXiaoye Zheng HOST = 3,
2740314b30SXiaoye Zheng }
2840314b30SXiaoye Zheng
2940314b30SXiaoye Zheng #[derive(FromPrimitive)]
3040314b30SXiaoye Zheng enum VmcsWidth {
3140314b30SXiaoye Zheng BIT16 = 0,
3240314b30SXiaoye Zheng BIT64 = 1,
3340314b30SXiaoye Zheng BIT32 = 2,
3440314b30SXiaoye Zheng NATURAL = 3,
3540314b30SXiaoye Zheng }
3640314b30SXiaoye Zheng
3740314b30SXiaoye Zheng #[derive(FromPrimitive)]
3840314b30SXiaoye Zheng #[allow(non_camel_case_types)]
3940314b30SXiaoye Zheng // (Intel Manual: APPENDIX B FIELD ENCODING IN VMCS)
4040314b30SXiaoye Zheng pub enum VmcsFields {
4140314b30SXiaoye Zheng // [CONTROL] fields
4240314b30SXiaoye Zheng // 16-bit control fields
4340314b30SXiaoye Zheng CTRL_VIRT_PROC_ID = encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT16, 0) as isize,
4440314b30SXiaoye Zheng CTRL_POSTED_INTR_N_VECTOR =
4540314b30SXiaoye Zheng encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT16, 1) as isize,
4640314b30SXiaoye Zheng CTRL_EPTP_INDEX = encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT16, 2) as isize,
4740314b30SXiaoye Zheng // 64-bit control fields
4840314b30SXiaoye Zheng CTRL_IO_BITMAP_A_ADDR = encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT64, 0) as isize,
4940314b30SXiaoye Zheng CTRL_IO_BITMAP_B_ADDR = encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT64, 1) as isize,
5040314b30SXiaoye Zheng CTRL_MSR_BITMAP_ADDR = encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT64, 2) as isize, // control whether RDMSR or WRMSR cause VM exit
5140314b30SXiaoye Zheng CTRL_VMEXIT_MSR_STORE_ADDR =
5240314b30SXiaoye Zheng encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT64, 3) as isize,
5340314b30SXiaoye Zheng CTRL_VMEXIT_MSR_LOAD_ADDR =
5440314b30SXiaoye Zheng encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT64, 4) as isize,
5540314b30SXiaoye Zheng CTRL_VMENTRY_MSR_LOAD_ADDR =
5640314b30SXiaoye Zheng encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT64, 5) as isize,
5740314b30SXiaoye Zheng CTRL_EXECUTIVE_VMCS_PTR =
5840314b30SXiaoye Zheng encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT64, 6) as isize,
5940314b30SXiaoye Zheng CTRL_PML_ADDR = encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT64, 7) as isize,
6040314b30SXiaoye Zheng CTRL_TSC_ADDR = encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT64, 8) as isize,
6140314b30SXiaoye Zheng CTRL_VIRT_APIC_ADDR = encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT64, 9) as isize,
6240314b30SXiaoye Zheng CTRL_APIC_ACCESS_ADDR =
6340314b30SXiaoye Zheng encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT64, 10) as isize,
6440314b30SXiaoye Zheng CTRL_POSTED_INTR_DESC_ADDR =
6540314b30SXiaoye Zheng encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT64, 11) as isize,
6640314b30SXiaoye Zheng CTRL_VMFUNC_CTRL = encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT64, 12) as isize,
6740314b30SXiaoye Zheng CTRL_EPTP_PTR = encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT64, 13) as isize,
6840314b30SXiaoye Zheng CTRL_EOI_EXIT_BITMAP_0 =
6940314b30SXiaoye Zheng encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT64, 14) as isize,
7040314b30SXiaoye Zheng CTRL_EOI_EXIT_BITMAP_1 =
7140314b30SXiaoye Zheng encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT64, 15) as isize,
7240314b30SXiaoye Zheng CTRL_EOI_EXIT_BITMAP_2 =
7340314b30SXiaoye Zheng encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT64, 16) as isize,
7440314b30SXiaoye Zheng CTRL_EOI_EXIT_BITMAP_3 =
7540314b30SXiaoye Zheng encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT64, 17) as isize,
7640314b30SXiaoye Zheng CTRL_EPT_LIST_ADDR = encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT64, 18) as isize,
7740314b30SXiaoye Zheng CTRL_VMREAD_BITMAP_ADDR =
7840314b30SXiaoye Zheng encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT64, 19) as isize,
7940314b30SXiaoye Zheng CTRL_VMWRITE_BITMAP_ADDR =
8040314b30SXiaoye Zheng encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT64, 20) as isize,
8140314b30SXiaoye Zheng CTRL_VIRT_EXECPT_INFO_ADDR =
8240314b30SXiaoye Zheng encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT64, 21) as isize,
8340314b30SXiaoye Zheng CTRL_XSS_EXITING_BITMAP =
8440314b30SXiaoye Zheng encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT64, 22) as isize,
8540314b30SXiaoye Zheng CTRL_ENCLS_EXITING_BITMAP =
8640314b30SXiaoye Zheng encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT64, 23) as isize,
8740314b30SXiaoye Zheng CTRL_TSC_MULTIPLIER = encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT64, 25) as isize,
8840314b30SXiaoye Zheng // 32-bit control fields
8940314b30SXiaoye Zheng CTRL_PIN_BASED_VM_EXEC_CTRLS =
9040314b30SXiaoye Zheng encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT32, 0) as isize, // control async event handling (i.e. interrupts)
9140314b30SXiaoye Zheng CTRL_PRIMARY_PROCESSOR_VM_EXEC_CTRLS =
9240314b30SXiaoye Zheng encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT32, 1) as isize, // control sync event handling (i.e. instruction exits)
9340314b30SXiaoye Zheng CTRL_EXPECTION_BITMAP = encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT32, 2) as isize, // bitmap to control exceptions that cause a VM exit
9440314b30SXiaoye Zheng CTRL_PAGE_FAULT_ERR_CODE_MASK =
9540314b30SXiaoye Zheng encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT32, 3) as isize,
9640314b30SXiaoye Zheng CTRL_PAGE_FAULT_ERR_CODE_MATCH =
9740314b30SXiaoye Zheng encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT32, 4) as isize,
9840314b30SXiaoye Zheng CTRL_CR3_TARGET_COUNT = encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT32, 5) as isize,
9940314b30SXiaoye Zheng CTRL_PRIMARY_VM_EXIT_CTRLS =
10040314b30SXiaoye Zheng encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT32, 6) as isize,
10140314b30SXiaoye Zheng CTRL_VM_EXIT_MSR_STORE_COUNT =
10240314b30SXiaoye Zheng encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT32, 7) as isize,
10340314b30SXiaoye Zheng CTRL_VM_EXIT_MSR_LOAD_COUNT =
10440314b30SXiaoye Zheng encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT32, 8) as isize,
10540314b30SXiaoye Zheng CTRL_VM_ENTRY_CTRLS = encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT32, 9) as isize,
10640314b30SXiaoye Zheng CTRL_VM_ENTRY_MSR_LOAD_COUNT =
10740314b30SXiaoye Zheng encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT32, 10) as isize,
10840314b30SXiaoye Zheng CTRL_VM_ENTRY_INTR_INFO_FIELD =
10940314b30SXiaoye Zheng encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT32, 11) as isize,
11040314b30SXiaoye Zheng CTRL_VM_ENTRY_EXCEPTION_ERR_CODE =
11140314b30SXiaoye Zheng encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT32, 12) as isize,
11240314b30SXiaoye Zheng CTRL_VM_ENTRY_INSTR_LEN =
11340314b30SXiaoye Zheng encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT32, 13) as isize,
11440314b30SXiaoye Zheng CTRL_TPR_THRESHOLD = encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT32, 14) as isize,
11540314b30SXiaoye Zheng CTRL_SECONDARY_PROCESSOR_VM_EXEC_CTRLS =
11640314b30SXiaoye Zheng encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT32, 15) as isize,
11740314b30SXiaoye Zheng CTRL_PLE_GAP = encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT32, 16) as isize,
11840314b30SXiaoye Zheng CTRL_PLE_WINDOW = encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::BIT32, 17) as isize,
11940314b30SXiaoye Zheng // natural control fields
12040314b30SXiaoye Zheng CTRL_CR0_GUEST_HOST_MASK =
12140314b30SXiaoye Zheng encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::NATURAL, 0) as isize, // control executions of insts that access cr0
12240314b30SXiaoye Zheng CTRL_CR4_GUEST_HOST_MASK =
12340314b30SXiaoye Zheng encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::NATURAL, 1) as isize,
12440314b30SXiaoye Zheng CTRL_CR0_READ_SHADOW =
12540314b30SXiaoye Zheng encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::NATURAL, 2) as isize, // control executions of insts that access cr0
12640314b30SXiaoye Zheng CTRL_CR4_READ_SHADOW =
12740314b30SXiaoye Zheng encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::NATURAL, 3) as isize,
12840314b30SXiaoye Zheng CTRL_CR3_TARGET_VALUE_0 =
12940314b30SXiaoye Zheng encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::NATURAL, 4) as isize,
13040314b30SXiaoye Zheng CTRL_CR3_TARGET_VALUE_1 =
13140314b30SXiaoye Zheng encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::NATURAL, 5) as isize,
13240314b30SXiaoye Zheng CTRL_CR3_TARGET_VALUE_2 =
13340314b30SXiaoye Zheng encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::NATURAL, 6) as isize,
13440314b30SXiaoye Zheng CTRL_CR3_TARGET_VALUE_3 =
13540314b30SXiaoye Zheng encode_vmcs_field_full(VmcsType::CONTROL, VmcsWidth::NATURAL, 7) as isize,
13640314b30SXiaoye Zheng
13740314b30SXiaoye Zheng // [VMEXIT] fields read-only
13840314b30SXiaoye Zheng // No 16-bit vmexit fields
13940314b30SXiaoye Zheng // 64-bit vmexit fields
14040314b30SXiaoye Zheng VMEXIT_GUEST_PHY_ADDR = encode_vmcs_field_full(VmcsType::VMEXIT, VmcsWidth::BIT64, 0) as isize,
14140314b30SXiaoye Zheng // 32-bit vmexit fields
14240314b30SXiaoye Zheng VMEXIT_INSTR_ERR = encode_vmcs_field_full(VmcsType::VMEXIT, VmcsWidth::BIT32, 0) as isize,
14340314b30SXiaoye Zheng VMEXIT_EXIT_REASON = encode_vmcs_field_full(VmcsType::VMEXIT, VmcsWidth::BIT32, 1) as isize,
14440314b30SXiaoye Zheng VMEXIT_INT_INFO = encode_vmcs_field_full(VmcsType::VMEXIT, VmcsWidth::BIT32, 2) as isize,
14540314b30SXiaoye Zheng VMEXIT_INT_ERR_CODE = encode_vmcs_field_full(VmcsType::VMEXIT, VmcsWidth::BIT32, 3) as isize,
14640314b30SXiaoye Zheng VMEXIT_IDT_VECTOR_INFO = encode_vmcs_field_full(VmcsType::VMEXIT, VmcsWidth::BIT32, 4) as isize,
14740314b30SXiaoye Zheng VMEXIT_IDT_VECTOR_ERR_CODE =
14840314b30SXiaoye Zheng encode_vmcs_field_full(VmcsType::VMEXIT, VmcsWidth::BIT32, 5) as isize,
14940314b30SXiaoye Zheng VMEXIT_INSTR_LEN = encode_vmcs_field_full(VmcsType::VMEXIT, VmcsWidth::BIT32, 6) as isize,
15040314b30SXiaoye Zheng VMEXIT_INSTR_INFO = encode_vmcs_field_full(VmcsType::VMEXIT, VmcsWidth::BIT32, 7) as isize,
15140314b30SXiaoye Zheng // natural vmexit fields
15240314b30SXiaoye Zheng VMEXIT_QUALIFICATION = encode_vmcs_field_full(VmcsType::VMEXIT, VmcsWidth::NATURAL, 0) as isize,
15340314b30SXiaoye Zheng VMEXIT_IO_RCX = encode_vmcs_field_full(VmcsType::VMEXIT, VmcsWidth::NATURAL, 1) as isize,
15440314b30SXiaoye Zheng VMEXIT_IO_RSX = encode_vmcs_field_full(VmcsType::VMEXIT, VmcsWidth::NATURAL, 2) as isize,
15540314b30SXiaoye Zheng VMEXIT_IO_RDI = encode_vmcs_field_full(VmcsType::VMEXIT, VmcsWidth::NATURAL, 3) as isize,
15640314b30SXiaoye Zheng VMEXIT_IO_RIP = encode_vmcs_field_full(VmcsType::VMEXIT, VmcsWidth::NATURAL, 4) as isize,
15740314b30SXiaoye Zheng VMEXIT_GUEST_LINEAR_ADDR =
15840314b30SXiaoye Zheng encode_vmcs_field_full(VmcsType::VMEXIT, VmcsWidth::NATURAL, 5) as isize,
15940314b30SXiaoye Zheng
16040314b30SXiaoye Zheng // [GUEST] fields
16140314b30SXiaoye Zheng // 16-bit guest fields
16240314b30SXiaoye Zheng GUEST_ES_SELECTOR = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::BIT16, 0) as isize,
16340314b30SXiaoye Zheng GUEST_CS_SELECTOR = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::BIT16, 1) as isize,
16440314b30SXiaoye Zheng GUEST_SS_SELECTOR = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::BIT16, 2) as isize,
16540314b30SXiaoye Zheng GUEST_DS_SELECTOR = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::BIT16, 3) as isize,
16640314b30SXiaoye Zheng GUEST_FS_SELECTOR = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::BIT16, 4) as isize,
16740314b30SXiaoye Zheng GUEST_GS_SELECTOR = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::BIT16, 5) as isize,
16840314b30SXiaoye Zheng GUEST_LDTR_SELECTOR = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::BIT16, 6) as isize,
16940314b30SXiaoye Zheng GUEST_TR_SELECTOR = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::BIT16, 7) as isize,
17040314b30SXiaoye Zheng GUEST_INTR_STATUS = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::BIT16, 8) as isize,
17140314b30SXiaoye Zheng GUEST_PML_INDEX = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::BIT16, 9) as isize,
17240314b30SXiaoye Zheng // 64-bit guest fields
17340314b30SXiaoye Zheng GUEST_VMCS_LINK_PTR = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::BIT64, 0) as isize,
17440314b30SXiaoye Zheng GUEST_DEBUGCTL = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::BIT64, 1) as isize,
17540314b30SXiaoye Zheng GUEST_PAT = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::BIT64, 2) as isize,
17640314b30SXiaoye Zheng GUEST_EFER = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::BIT64, 3) as isize,
17740314b30SXiaoye Zheng GUEST_PERF_GLOBAL_CTRL = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::BIT64, 4) as isize,
17840314b30SXiaoye Zheng GUEST_PDPTE0 = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::BIT64, 5) as isize,
17940314b30SXiaoye Zheng GUEST_PDPTE1 = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::BIT64, 6) as isize,
18040314b30SXiaoye Zheng GUEST_PDPTE2 = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::BIT64, 7) as isize,
18140314b30SXiaoye Zheng GUEST_PDPTE3 = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::BIT64, 8) as isize,
18240314b30SXiaoye Zheng // 32-bit guest fields
18340314b30SXiaoye Zheng GUEST_ES_LIMIT = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::BIT32, 0) as isize,
18440314b30SXiaoye Zheng GUEST_CS_LIMIT = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::BIT32, 1) as isize,
18540314b30SXiaoye Zheng GUEST_SS_LIMIT = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::BIT32, 2) as isize,
18640314b30SXiaoye Zheng GUEST_DS_LIMIT = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::BIT32, 3) as isize,
18740314b30SXiaoye Zheng GUEST_FS_LIMIT = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::BIT32, 4) as isize,
18840314b30SXiaoye Zheng GUEST_GS_LIMIT = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::BIT32, 5) as isize,
18940314b30SXiaoye Zheng GUEST_LDTR_LIMIT = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::BIT32, 6) as isize,
19040314b30SXiaoye Zheng GUEST_TR_LIMIT = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::BIT32, 7) as isize,
19140314b30SXiaoye Zheng GUEST_GDTR_LIMIT = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::BIT32, 8) as isize,
19240314b30SXiaoye Zheng GUEST_IDTR_LIMIT = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::BIT32, 9) as isize,
19340314b30SXiaoye Zheng GUEST_ES_ACCESS_RIGHTS = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::BIT32, 10) as isize,
19440314b30SXiaoye Zheng GUEST_CS_ACCESS_RIGHTS = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::BIT32, 11) as isize,
19540314b30SXiaoye Zheng GUEST_SS_ACCESS_RIGHTS = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::BIT32, 12) as isize,
19640314b30SXiaoye Zheng GUEST_DS_ACCESS_RIGHTS = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::BIT32, 13) as isize,
19740314b30SXiaoye Zheng GUEST_FS_ACCESS_RIGHTS = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::BIT32, 14) as isize,
19840314b30SXiaoye Zheng GUEST_GS_ACCESS_RIGHTS = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::BIT32, 15) as isize,
19940314b30SXiaoye Zheng GUEST_LDTR_ACCESS_RIGHTS =
20040314b30SXiaoye Zheng encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::BIT32, 16) as isize,
20140314b30SXiaoye Zheng GUEST_TR_ACCESS_RIGHTS = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::BIT32, 17) as isize,
20240314b30SXiaoye Zheng GUEST_INTERRUPTIBILITY_STATE =
20340314b30SXiaoye Zheng encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::BIT32, 18) as isize,
20440314b30SXiaoye Zheng GUEST_ACTIVITY_STATE = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::BIT32, 19) as isize,
20540314b30SXiaoye Zheng GUEST_SMBASE = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::BIT32, 20) as isize,
20640314b30SXiaoye Zheng GUEST_SYSENTER_CS = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::BIT32, 21) as isize,
207*b5b571e0SLoGin GUEST_VMX_PREEMPT_TIMER_VALUE = 0x482E_isize,
20840314b30SXiaoye Zheng // natural guest fields
20940314b30SXiaoye Zheng GUEST_CR0 = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::NATURAL, 0) as isize,
21040314b30SXiaoye Zheng GUEST_CR3 = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::NATURAL, 1) as isize,
21140314b30SXiaoye Zheng GUEST_CR4 = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::NATURAL, 2) as isize,
21240314b30SXiaoye Zheng GUEST_ES_BASE = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::NATURAL, 3) as isize,
21340314b30SXiaoye Zheng GUEST_CS_BASE = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::NATURAL, 4) as isize,
21440314b30SXiaoye Zheng GUEST_SS_BASE = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::NATURAL, 5) as isize,
21540314b30SXiaoye Zheng GUEST_DS_BASE = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::NATURAL, 6) as isize,
21640314b30SXiaoye Zheng GUEST_FS_BASE = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::NATURAL, 7) as isize,
21740314b30SXiaoye Zheng GUEST_GS_BASE = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::NATURAL, 8) as isize,
21840314b30SXiaoye Zheng GUEST_LDTR_BASE = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::NATURAL, 9) as isize,
21940314b30SXiaoye Zheng GUEST_TR_BASE = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::NATURAL, 10) as isize,
22040314b30SXiaoye Zheng GUEST_GDTR_BASE = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::NATURAL, 11) as isize,
22140314b30SXiaoye Zheng GUEST_IDTR_BASE = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::NATURAL, 12) as isize,
22240314b30SXiaoye Zheng GUEST_DR7 = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::NATURAL, 13) as isize,
22340314b30SXiaoye Zheng GUEST_RSP = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::NATURAL, 14) as isize,
22440314b30SXiaoye Zheng GUEST_RIP = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::NATURAL, 15) as isize,
22540314b30SXiaoye Zheng GUEST_RFLAGS = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::NATURAL, 16) as isize,
22640314b30SXiaoye Zheng GUEST_PENDING_DBG_EXCEPTIONS =
22740314b30SXiaoye Zheng encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::NATURAL, 17) as isize,
22840314b30SXiaoye Zheng GUEST_SYSENTER_ESP = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::NATURAL, 18) as isize,
22940314b30SXiaoye Zheng GUEST_SYSENTER_EIP = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::NATURAL, 19) as isize,
23040314b30SXiaoye Zheng
23140314b30SXiaoye Zheng // [HOST] fields
23240314b30SXiaoye Zheng // host 16 bit fields
23340314b30SXiaoye Zheng HOST_ES_SELECTOR = encode_vmcs_field_full(VmcsType::HOST, VmcsWidth::BIT16, 0) as isize,
23440314b30SXiaoye Zheng HOST_CS_SELECTOR = encode_vmcs_field_full(VmcsType::HOST, VmcsWidth::BIT16, 1) as isize,
23540314b30SXiaoye Zheng HOST_SS_SELECTOR = encode_vmcs_field_full(VmcsType::HOST, VmcsWidth::BIT16, 2) as isize,
23640314b30SXiaoye Zheng HOST_DS_SELECTOR = encode_vmcs_field_full(VmcsType::HOST, VmcsWidth::BIT16, 3) as isize,
23740314b30SXiaoye Zheng HOST_FS_SELECTOR = encode_vmcs_field_full(VmcsType::HOST, VmcsWidth::BIT16, 4) as isize,
23840314b30SXiaoye Zheng HOST_GS_SELECTOR = encode_vmcs_field_full(VmcsType::HOST, VmcsWidth::BIT16, 5) as isize,
23940314b30SXiaoye Zheng HOST_TR_SELECTOR = encode_vmcs_field_full(VmcsType::HOST, VmcsWidth::BIT16, 6) as isize,
24040314b30SXiaoye Zheng // host 64 bit fields
24140314b30SXiaoye Zheng HOST_PAT = encode_vmcs_field_full(VmcsType::HOST, VmcsWidth::BIT64, 0) as isize,
24240314b30SXiaoye Zheng HOST_EFER = encode_vmcs_field_full(VmcsType::HOST, VmcsWidth::BIT64, 1) as isize,
24340314b30SXiaoye Zheng HOST_PERF_GLOBAL_CTRL = encode_vmcs_field_full(VmcsType::HOST, VmcsWidth::BIT64, 2) as isize,
24440314b30SXiaoye Zheng // host 32 bit fields
24540314b30SXiaoye Zheng HOST_SYSENTER_CS = encode_vmcs_field_full(VmcsType::HOST, VmcsWidth::BIT32, 0) as isize,
24640314b30SXiaoye Zheng // host natural fields
24740314b30SXiaoye Zheng HOST_CR0 = encode_vmcs_field_full(VmcsType::HOST, VmcsWidth::NATURAL, 0) as isize,
24840314b30SXiaoye Zheng HOST_CR3 = encode_vmcs_field_full(VmcsType::HOST, VmcsWidth::NATURAL, 1) as isize,
24940314b30SXiaoye Zheng HOST_CR4 = encode_vmcs_field_full(VmcsType::HOST, VmcsWidth::NATURAL, 2) as isize,
25040314b30SXiaoye Zheng HOST_FS_BASE = encode_vmcs_field_full(VmcsType::HOST, VmcsWidth::NATURAL, 3) as isize,
25140314b30SXiaoye Zheng HOST_GS_BASE = encode_vmcs_field_full(VmcsType::HOST, VmcsWidth::NATURAL, 4) as isize,
25240314b30SXiaoye Zheng HOST_TR_BASE = encode_vmcs_field_full(VmcsType::HOST, VmcsWidth::NATURAL, 5) as isize,
25340314b30SXiaoye Zheng HOST_GDTR_BASE = encode_vmcs_field_full(VmcsType::HOST, VmcsWidth::NATURAL, 6) as isize,
25440314b30SXiaoye Zheng HOST_IDTR_BASE = encode_vmcs_field_full(VmcsType::HOST, VmcsWidth::NATURAL, 7) as isize,
25540314b30SXiaoye Zheng HOST_SYSENTER_ESP = encode_vmcs_field_full(VmcsType::HOST, VmcsWidth::NATURAL, 8) as isize,
25640314b30SXiaoye Zheng HOST_SYSENTER_EIP = encode_vmcs_field_full(VmcsType::HOST, VmcsWidth::NATURAL, 9) as isize,
25740314b30SXiaoye Zheng HOST_RSP = encode_vmcs_field_full(VmcsType::HOST, VmcsWidth::NATURAL, 10) as isize,
25840314b30SXiaoye Zheng HOST_RIP = encode_vmcs_field_full(VmcsType::HOST, VmcsWidth::NATURAL, 11) as isize,
25940314b30SXiaoye Zheng }
26040314b30SXiaoye Zheng
26140314b30SXiaoye Zheng // (Intel Manual: 25.6 VM-EXECUTION CONTROL FIELDS)
26240314b30SXiaoye Zheng bitflags! {
26340314b30SXiaoye Zheng // (Intel Manual: 25.6.1 Pin-Based VM-Execution Controls)
26440314b30SXiaoye Zheng #[allow(non_camel_case_types)]
26540314b30SXiaoye Zheng pub struct VmxPinBasedExecuteCtrl: u32 {
26640314b30SXiaoye Zheng const EXTERNAL_INTERRUPT_EXITING = 1 << 0; // external interrupts cause VM exits
26740314b30SXiaoye Zheng const NMI_EXITING = 1 << 3; // non-maskable interrupts (NMIs) cause VM exits.
26840314b30SXiaoye Zheng 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”
26940314b30SXiaoye Zheng const VMX_PREEMPTION_TIMER = 1 << 6; // the VMX-preemption timer counts down in VMX non-root operation
27040314b30SXiaoye Zheng const PROCESS_POSTED_INTERRUPTS = 1 << 7; // he processor treats interrupts with the posted-interrupt notification vector
27140314b30SXiaoye Zheng }
27240314b30SXiaoye Zheng
27340314b30SXiaoye Zheng // (Intel Manual: 25.6.2 Processor-Based VM-Execution Controls)
27440314b30SXiaoye Zheng #[allow(non_camel_case_types)]
27540314b30SXiaoye Zheng pub struct VmxPrimaryProcessBasedExecuteCtrl: u32{
27640314b30SXiaoye Zheng const INTERRUPT_WINDOW_EXITING = 1 << 2; // VM exits on interrupt window RFLAGS.IF = 1
27740314b30SXiaoye Zheng const USE_TSC_OFFSETTING = 1 << 3; // TSC offsetting is enabled
27840314b30SXiaoye Zheng const HLT_EXITING = 1 << 7;
27940314b30SXiaoye Zheng const INVLPG_EXITING = 1 << 9;
28040314b30SXiaoye Zheng const MWAIT_EXITING = 1 << 10;
28140314b30SXiaoye Zheng const RDPMC_EXITING = 1 << 11;
28240314b30SXiaoye Zheng const RDTSC_EXITING = 1 << 12;
28340314b30SXiaoye Zheng const CR3_LOAD_EXITING = 1 << 15;
28440314b30SXiaoye Zheng const CR3_STR_EXITING = 1 << 16;
28540314b30SXiaoye Zheng const CR8_LOAD_EXITING = 1 << 19;
28640314b30SXiaoye Zheng const CR8_STR_EXITING = 1 << 20;
28740314b30SXiaoye Zheng const USE_TPR_SHADOW = 1 << 21;
28840314b30SXiaoye Zheng const NMI_WINDOW_EXITING = 1 << 22;
28940314b30SXiaoye Zheng const MOV_DR_EXITING = 1 << 23;
29040314b30SXiaoye Zheng const UNCOND_IO_EXITING = 1 << 24;
29140314b30SXiaoye Zheng const USE_IO_BITMAPS = 1 << 25;
29240314b30SXiaoye Zheng const MONITOR_TRAP_FLAG = 1 << 27;
29340314b30SXiaoye Zheng const USE_MSR_BITMAPS = 1 << 28;
29440314b30SXiaoye Zheng const MONITOR_EXITING = 1 << 29;
29540314b30SXiaoye Zheng const PAUSE_EXITING = 1 << 30;
29640314b30SXiaoye Zheng const ACTIVATE_SECONDARY_CONTROLS = 1 << 31;
29740314b30SXiaoye Zheng }
29840314b30SXiaoye Zheng
29940314b30SXiaoye Zheng // (Intel Manual: 25.6.2 Processor-Based VM-Execution Controls)
30040314b30SXiaoye Zheng pub struct VmxSecondaryProcessBasedExecuteCtrl: u32{
30140314b30SXiaoye Zheng const VIRT_APIC_ACCESS = 1 << 0;
30240314b30SXiaoye Zheng const ENABLE_EPT = 1 << 1;
30340314b30SXiaoye Zheng const DESCRIPTOR_TABLE_EXITING = 1 << 2;
30440314b30SXiaoye Zheng const ENABLE_RDTSCP = 1 << 3;
30540314b30SXiaoye Zheng const VIRT_X2APIC_MODE = 1 << 4;
30640314b30SXiaoye Zheng const ENABLE_VPID = 1 << 5;
30740314b30SXiaoye Zheng const WBINVD_EXITING = 1 << 6;
30840314b30SXiaoye Zheng const UNRESTRICTED_GUEST = 1 << 7;
30940314b30SXiaoye Zheng const APCI_REGISTER_VIRT = 1 << 8;
31040314b30SXiaoye Zheng const VIRT_INTR_DELIVERY = 1 << 9;
31140314b30SXiaoye Zheng const PAUSE_LOOP_EXITING = 1 << 10;
31240314b30SXiaoye Zheng const RDRAND_EXITING = 1 << 11;
31340314b30SXiaoye Zheng const ENABLE_INVPCID = 1 << 12;
31440314b30SXiaoye Zheng const ENABLE_VM_FUNCTIONS = 1 << 13;
31540314b30SXiaoye Zheng const VMCS_SHADOWING = 1 << 14;
31640314b30SXiaoye Zheng const ENABLE_ENCLS_EXITING = 1 << 15;
31740314b30SXiaoye Zheng const RDSEED_EXITING = 1 << 16;
31840314b30SXiaoye Zheng const ENABLE_PML = 1 << 17;
31940314b30SXiaoye Zheng const EPT_VIOLATION_VE = 1 << 18;
32040314b30SXiaoye Zheng const CONCEAL_VMX_FROM_PT = 1 << 19;
32140314b30SXiaoye Zheng const ENABLE_XSAVES_XRSTORS = 1 << 20;
32240314b30SXiaoye Zheng const PASID_TRANSLATION = 1 << 21;
32340314b30SXiaoye Zheng const MODE_BASED_EPT_EXEC = 1 << 22;
32440314b30SXiaoye Zheng const SUB_PAGE_WRITE_PERM = 1 << 23;
32540314b30SXiaoye Zheng const PT_USE_GUEST_PYH_ADDR = 1 << 24;
32640314b30SXiaoye Zheng const USE_TSC_SCALING = 1 << 25;
32740314b30SXiaoye Zheng const ENABLE_USER_WAIT_PAUSE = 1 << 26;
32840314b30SXiaoye Zheng const ENABLE_PCONFIG = 1 << 27;
32940314b30SXiaoye Zheng const ENABLE_ENCLV_EXITING = 1 << 28;
33040314b30SXiaoye Zheng const VMM_BUS_LOCK_DETECTION = 1 << 30;
33140314b30SXiaoye Zheng const INST_TIMEOUT = 1 << 31;
33240314b30SXiaoye Zheng }
33340314b30SXiaoye Zheng
33440314b30SXiaoye Zheng // (Intel Manual: 25.7.1 VM-Exit Controls)
33540314b30SXiaoye Zheng #[allow(non_camel_case_types)]
33640314b30SXiaoye Zheng pub struct VmxPrimaryExitCtrl: u32 {
33740314b30SXiaoye Zheng const SAVE_DBG_CTRLS = 1 << 2;
33840314b30SXiaoye Zheng const HOST_ADDR_SPACE_SIZE = 1 << 9; // determines if a virtual processor will be in 64-bit mode after a VM exit
33940314b30SXiaoye Zheng const LOAD_IA32_PERF_GLOBAL_CTRL = 1 << 12;
34040314b30SXiaoye Zheng const ACK_INTERRUPT_ON_EXIT = 1 << 15;
34140314b30SXiaoye Zheng const SAVE_IA32_PAT = 1 << 18;
34240314b30SXiaoye Zheng const LOAD_IA32_PAT = 1 << 19;
34340314b30SXiaoye Zheng const SAVE_IA32_EFER = 1 << 20;
34440314b30SXiaoye Zheng const LOAD_IA32_EFER = 1 << 21;
34540314b30SXiaoye Zheng const SAVE_VMX_PREEMPT_TIMER_VALUE = 1 << 22;
34640314b30SXiaoye Zheng const CLEAR_IA32_BNDCFGS = 1 << 23;
34740314b30SXiaoye Zheng const CONCEAL_VMX_FROM_PT = 1 << 24;
34840314b30SXiaoye Zheng const CLEAR_IA32_RTIT_CTL = 1 << 25;
34940314b30SXiaoye Zheng const CLEAR_IA32_LBR_CTL = 1 << 26;
35040314b30SXiaoye Zheng const CLEAR_UINV = 1 << 27;
35140314b30SXiaoye Zheng const LOAD_CET_STATE = 1 << 28;
35240314b30SXiaoye Zheng const LOAD_PKRS = 1 << 29;
35340314b30SXiaoye Zheng const SAVE_IA32_PERF_GLOBAL_CTL = 1 << 30;
35440314b30SXiaoye Zheng const ACTIVATE_SECONDARY_CONTROLS = 1 << 31;
35540314b30SXiaoye Zheng }
35640314b30SXiaoye Zheng
35740314b30SXiaoye Zheng // (Intel Manual: 25.8.1 VM-Entry Controls)
35840314b30SXiaoye Zheng #[allow(non_camel_case_types)]
35940314b30SXiaoye Zheng pub struct VmxEntryCtrl: u32 {
36040314b30SXiaoye Zheng const LOAD_DBG_CTRLS = 1 << 2;
36140314b30SXiaoye Zheng const IA32E_MODE_GUEST = 1 << 9;
36240314b30SXiaoye Zheng const ENTRY_TO_SMM = 1 << 10;
36340314b30SXiaoye Zheng const DEACTIVATE_DUAL_MONITOR = 1 << 11;
36440314b30SXiaoye Zheng const LOAD_IA32_PERF_GLOBAL_CTRL = 1 << 13;
36540314b30SXiaoye Zheng const LOAD_IA32_PAT = 1 << 14;
36640314b30SXiaoye Zheng const LOAD_IA32_EFER = 1 << 15;
36740314b30SXiaoye Zheng const LOAD_IA32_BNDCFGS = 1 << 16;
36840314b30SXiaoye Zheng const CONCEAL_VMX_FROM_PT = 1 << 17;
36940314b30SXiaoye Zheng const LOAD_IA32_RTIT_CTL = 1 << 18;
37040314b30SXiaoye Zheng const LOAD_UINV = 1 << 19;
37140314b30SXiaoye Zheng const LOAD_CET_STATE = 1 << 20;
37240314b30SXiaoye Zheng const LOAD_PKRS = 1 << 21;
37340314b30SXiaoye Zheng const LOAD_IA32_PERF_GLOBAL_CTL = 1 << 22;
37440314b30SXiaoye Zheng }
37540314b30SXiaoye Zheng
37640314b30SXiaoye Zheng }
37740314b30SXiaoye Zheng
37840314b30SXiaoye Zheng #[derive(FromPrimitive)]
37940314b30SXiaoye Zheng #[allow(non_camel_case_types)]
38040314b30SXiaoye Zheng pub enum VmxExitReason {
38140314b30SXiaoye Zheng EXCEPTION_OR_NMI = 0,
38240314b30SXiaoye Zheng EXTERNAL_INTERRUPT = 1,
38340314b30SXiaoye Zheng TRIPLE_FAULT = 2,
38440314b30SXiaoye Zheng INIT_SIGNAL = 3,
38540314b30SXiaoye Zheng SIPI = 4,
38640314b30SXiaoye Zheng IO_SMI = 5,
38740314b30SXiaoye Zheng OTHER_SMI = 6,
38840314b30SXiaoye Zheng INTERRUPT_WINDOW = 7,
38940314b30SXiaoye Zheng NMI_WINDOW = 8,
39040314b30SXiaoye Zheng TASK_SWITCH = 9,
39140314b30SXiaoye Zheng CPUID = 10,
39240314b30SXiaoye Zheng GETSEC = 11,
39340314b30SXiaoye Zheng HLT = 12,
39440314b30SXiaoye Zheng INVD = 13,
39540314b30SXiaoye Zheng INVLPG = 14,
39640314b30SXiaoye Zheng RDPMC = 15,
39740314b30SXiaoye Zheng RDTSC = 16,
39840314b30SXiaoye Zheng RSM = 17,
39940314b30SXiaoye Zheng VMCALL = 18,
40040314b30SXiaoye Zheng VMCLEAR = 19,
40140314b30SXiaoye Zheng VMLAUNCH = 20,
40240314b30SXiaoye Zheng VMPTRLD = 21,
40340314b30SXiaoye Zheng VMPTRST = 22,
40440314b30SXiaoye Zheng VMREAD = 23,
40540314b30SXiaoye Zheng VMRESUME = 24,
40640314b30SXiaoye Zheng VMWRITE = 25,
40740314b30SXiaoye Zheng VMXOFF = 26,
40840314b30SXiaoye Zheng VMXON = 27,
40940314b30SXiaoye Zheng CR_ACCESS = 28,
41040314b30SXiaoye Zheng DR_ACCESS = 29,
41140314b30SXiaoye Zheng IO_INSTRUCTION = 30,
41240314b30SXiaoye Zheng RDMSR = 31,
41340314b30SXiaoye Zheng WRMSR = 32,
41440314b30SXiaoye Zheng VM_ENTRY_FAILURE_INVALID_GUEST_STATE = 33,
41540314b30SXiaoye Zheng VM_ENTRY_FAILURE_MSR_LOADING = 34,
41640314b30SXiaoye Zheng MWAIT = 36,
41740314b30SXiaoye Zheng MONITOR_TRAP_FLAG = 37,
41840314b30SXiaoye Zheng MONITOR = 39,
41940314b30SXiaoye Zheng PAUSE = 40,
42040314b30SXiaoye Zheng VM_ENTRY_FAILURE_MACHINE_CHECK_EVENT = 41,
42140314b30SXiaoye Zheng TPR_BELOW_THRESHOLD = 43,
42240314b30SXiaoye Zheng APIC_ACCESS = 44,
42340314b30SXiaoye Zheng VIRTUALIZED_EOI = 45,
42440314b30SXiaoye Zheng ACCESS_GDTR_OR_IDTR = 46,
42540314b30SXiaoye Zheng ACCESS_LDTR_OR_TR = 47,
42640314b30SXiaoye Zheng EPT_VIOLATION = 48,
42740314b30SXiaoye Zheng EPT_MISCONFIG = 49,
42840314b30SXiaoye Zheng INVEPT = 50,
42940314b30SXiaoye Zheng RDTSCP = 51,
43040314b30SXiaoye Zheng VMX_PREEMPTION_TIMER_EXPIRED = 52,
43140314b30SXiaoye Zheng INVVPID = 53,
43240314b30SXiaoye Zheng WBINVD = 54,
43340314b30SXiaoye Zheng XSETBV = 55,
43440314b30SXiaoye Zheng APIC_WRITE = 56,
43540314b30SXiaoye Zheng RDRAND = 57,
43640314b30SXiaoye Zheng INVPCID = 58,
43740314b30SXiaoye Zheng VMFUNC = 59,
43840314b30SXiaoye Zheng ENCLS = 60,
43940314b30SXiaoye Zheng RDSEED = 61,
44040314b30SXiaoye Zheng PML_FULL = 62,
44140314b30SXiaoye Zheng XSAVES = 63,
44240314b30SXiaoye Zheng XRSTORS = 64,
44340314b30SXiaoye Zheng }
44440314b30SXiaoye Zheng
44540314b30SXiaoye Zheng impl From<i32> for VmxExitReason {
from(num: i32) -> Self44640314b30SXiaoye Zheng fn from(num: i32) -> Self {
44740314b30SXiaoye Zheng match num {
44840314b30SXiaoye Zheng 0 => VmxExitReason::EXCEPTION_OR_NMI,
44940314b30SXiaoye Zheng 1 => VmxExitReason::EXTERNAL_INTERRUPT,
45040314b30SXiaoye Zheng 2 => VmxExitReason::TRIPLE_FAULT,
45140314b30SXiaoye Zheng 3 => VmxExitReason::INIT_SIGNAL,
45240314b30SXiaoye Zheng 4 => VmxExitReason::SIPI,
45340314b30SXiaoye Zheng 5 => VmxExitReason::IO_SMI,
45440314b30SXiaoye Zheng 6 => VmxExitReason::OTHER_SMI,
45540314b30SXiaoye Zheng 7 => VmxExitReason::INTERRUPT_WINDOW,
45640314b30SXiaoye Zheng 8 => VmxExitReason::NMI_WINDOW,
45740314b30SXiaoye Zheng 9 => VmxExitReason::TASK_SWITCH,
45840314b30SXiaoye Zheng 10 => VmxExitReason::CPUID,
45940314b30SXiaoye Zheng 11 => VmxExitReason::GETSEC,
46040314b30SXiaoye Zheng 12 => VmxExitReason::HLT,
46140314b30SXiaoye Zheng 13 => VmxExitReason::INVD,
46240314b30SXiaoye Zheng 14 => VmxExitReason::INVLPG,
46340314b30SXiaoye Zheng 15 => VmxExitReason::RDPMC,
46440314b30SXiaoye Zheng 16 => VmxExitReason::RDTSC,
46540314b30SXiaoye Zheng 17 => VmxExitReason::RSM,
46640314b30SXiaoye Zheng 18 => VmxExitReason::VMCALL,
46740314b30SXiaoye Zheng 19 => VmxExitReason::VMCLEAR,
46840314b30SXiaoye Zheng 20 => VmxExitReason::VMLAUNCH,
46940314b30SXiaoye Zheng 21 => VmxExitReason::VMPTRLD,
47040314b30SXiaoye Zheng 22 => VmxExitReason::VMPTRST,
47140314b30SXiaoye Zheng 23 => VmxExitReason::VMREAD,
47240314b30SXiaoye Zheng 24 => VmxExitReason::VMRESUME,
47340314b30SXiaoye Zheng 25 => VmxExitReason::VMWRITE,
47440314b30SXiaoye Zheng 26 => VmxExitReason::VMXOFF,
47540314b30SXiaoye Zheng 27 => VmxExitReason::VMXON,
47640314b30SXiaoye Zheng 28 => VmxExitReason::CR_ACCESS,
47740314b30SXiaoye Zheng 29 => VmxExitReason::DR_ACCESS,
47840314b30SXiaoye Zheng 30 => VmxExitReason::IO_INSTRUCTION,
47940314b30SXiaoye Zheng 31 => VmxExitReason::RDMSR,
48040314b30SXiaoye Zheng 32 => VmxExitReason::WRMSR,
48140314b30SXiaoye Zheng 33 => VmxExitReason::VM_ENTRY_FAILURE_INVALID_GUEST_STATE,
48240314b30SXiaoye Zheng 34 => VmxExitReason::VM_ENTRY_FAILURE_MSR_LOADING,
48340314b30SXiaoye Zheng 36 => VmxExitReason::MWAIT,
48440314b30SXiaoye Zheng 37 => VmxExitReason::MONITOR_TRAP_FLAG,
48540314b30SXiaoye Zheng 39 => VmxExitReason::MONITOR,
48640314b30SXiaoye Zheng 40 => VmxExitReason::PAUSE,
48740314b30SXiaoye Zheng 41 => VmxExitReason::VM_ENTRY_FAILURE_MACHINE_CHECK_EVENT,
48840314b30SXiaoye Zheng 43 => VmxExitReason::TPR_BELOW_THRESHOLD,
48940314b30SXiaoye Zheng 44 => VmxExitReason::APIC_ACCESS,
49040314b30SXiaoye Zheng 45 => VmxExitReason::VIRTUALIZED_EOI,
49140314b30SXiaoye Zheng 46 => VmxExitReason::ACCESS_GDTR_OR_IDTR,
49240314b30SXiaoye Zheng 47 => VmxExitReason::ACCESS_LDTR_OR_TR,
49340314b30SXiaoye Zheng 48 => VmxExitReason::EPT_VIOLATION,
49440314b30SXiaoye Zheng 49 => VmxExitReason::EPT_MISCONFIG,
49540314b30SXiaoye Zheng 50 => VmxExitReason::INVEPT,
49640314b30SXiaoye Zheng 51 => VmxExitReason::RDTSCP,
49740314b30SXiaoye Zheng 52 => VmxExitReason::VMX_PREEMPTION_TIMER_EXPIRED,
49840314b30SXiaoye Zheng 53 => VmxExitReason::INVVPID,
49940314b30SXiaoye Zheng 54 => VmxExitReason::WBINVD,
50040314b30SXiaoye Zheng 55 => VmxExitReason::XSETBV,
50140314b30SXiaoye Zheng 56 => VmxExitReason::APIC_WRITE,
50240314b30SXiaoye Zheng 57 => VmxExitReason::RDRAND,
50340314b30SXiaoye Zheng 58 => VmxExitReason::INVPCID,
50440314b30SXiaoye Zheng 59 => VmxExitReason::VMFUNC,
50540314b30SXiaoye Zheng 60 => VmxExitReason::ENCLS,
50640314b30SXiaoye Zheng 61 => VmxExitReason::RDSEED,
50740314b30SXiaoye Zheng 62 => VmxExitReason::PML_FULL,
50840314b30SXiaoye Zheng 63 => VmxExitReason::XSAVES,
50940314b30SXiaoye Zheng 64 => VmxExitReason::XRSTORS,
51040314b30SXiaoye Zheng _ => panic!("Invalid VmxExitReason number: {}", num),
51140314b30SXiaoye Zheng }
51240314b30SXiaoye Zheng }
51340314b30SXiaoye Zheng }
51440314b30SXiaoye Zheng
encode_vmcs_field( access_type: VmcsAccessType, vmcs_type: VmcsType, vmcs_width: VmcsWidth, index: u32, ) -> u3251540314b30SXiaoye Zheng const fn encode_vmcs_field(
51640314b30SXiaoye Zheng access_type: VmcsAccessType,
51740314b30SXiaoye Zheng vmcs_type: VmcsType,
51840314b30SXiaoye Zheng vmcs_width: VmcsWidth,
51940314b30SXiaoye Zheng index: u32,
52040314b30SXiaoye Zheng ) -> u32 {
52140314b30SXiaoye Zheng let mut encoding: u32 = 0;
522*b5b571e0SLoGin encoding |=
523*b5b571e0SLoGin (access_type as u32) | (index) << 1 | (vmcs_type as u32) << 10 | (vmcs_width as u32) << 13;
52440314b30SXiaoye Zheng return encoding;
52540314b30SXiaoye Zheng }
52640314b30SXiaoye Zheng
encode_vmcs_field_full(vmcs_type: VmcsType, vmcs_width: VmcsWidth, index: u32) -> u3252740314b30SXiaoye Zheng const fn encode_vmcs_field_full(vmcs_type: VmcsType, vmcs_width: VmcsWidth, index: u32) -> u32 {
52840314b30SXiaoye Zheng encode_vmcs_field(VmcsAccessType::FULL, vmcs_type, vmcs_width, index)
52940314b30SXiaoye Zheng }
53040314b30SXiaoye Zheng
53140314b30SXiaoye Zheng // fn decode_vmcs_field(field: u32) -> (VmcsAccessType, VmcsType, VmcsWidth, u16){
53240314b30SXiaoye Zheng // (FromPrimitive::from_u32(field & 1).unwrap() ,
53340314b30SXiaoye Zheng // FromPrimitive::from_u32((field>>10) & 0x3).unwrap(),
53440314b30SXiaoye Zheng // FromPrimitive::from_u32((field>>13) & 0x3).unwrap(),
53540314b30SXiaoye Zheng // ((field>>1) & 0x1ff) as u16
53640314b30SXiaoye Zheng // )
53740314b30SXiaoye Zheng // }
538