aboutsummaryrefslogtreecommitdiffstats
path: root/executor/kvm.h
diff options
context:
space:
mode:
authorAlexander Potapenko <glider@google.com>2025-11-18 11:07:02 +0100
committerAlexander Potapenko <glider@google.com>2025-11-19 08:59:40 +0000
commite5e08fbade9fe503f6dd211ecaf29510f1da05b6 (patch)
treef024d4909103be2dfbb0308a5854a2ece5cf640b /executor/kvm.h
parenta0dd64f852f58d267f78c25c35b3f3eae2b521c7 (diff)
executor: x86: implement SYZOS_API_NESTED_CREATE_VM
Provide basic setup for registers, page tables, and segments to create Intel/AMD-based nested virtual machines. Note that the machines do not get started yet.
Diffstat (limited to 'executor/kvm.h')
-rw-r--r--executor/kvm.h255
1 files changed, 254 insertions, 1 deletions
diff --git a/executor/kvm.h b/executor/kvm.h
index ab6c44601..85d605efe 100644
--- a/executor/kvm.h
+++ b/executor/kvm.h
@@ -184,6 +184,11 @@
#define X86_PDE64_PS (1ULL << 7)
#define X86_PDE64_G (1ULL << 8)
+// Intel-specific EPT Flags.
+#define EPT_MEMTYPE_WB (6ULL << 3)
+#define EPT_ACCESSED (1ULL << 8)
+#define EPT_DIRTY (1ULL << 9)
+
#define X86_SEL_LDT (1 << 3)
#define X86_SEL_CS16 (2 << 3)
#define X86_SEL_DS16 (3 << 3)
@@ -222,12 +227,260 @@
#define X86_MSR_IA32_SYSENTER_CS 0x174
#define X86_MSR_IA32_SYSENTER_ESP 0x175
#define X86_MSR_IA32_SYSENTER_EIP 0x176
+#define X86_MSR_IA32_CR_PAT 0x277
+#define X86_MSR_CORE_PERF_GLOBAL_CTRL 0x38f
+#define X86_MSR_IA32_VMX_TRUE_PINBASED_CTLS 0x48d
+#define X86_MSR_IA32_VMX_TRUE_PROCBASED_CTLS 0x48e
+#define X86_MSR_IA32_VMX_TRUE_EXIT_CTLS 0x48f
+#define X86_MSR_IA32_VMX_TRUE_ENTRY_CTLS 0x490
#define X86_MSR_IA32_EFER 0xc0000080
#define X86_MSR_IA32_STAR 0xC0000081
#define X86_MSR_IA32_LSTAR 0xC0000082
+#define X86_MSR_FS_BASE 0xc0000100
+#define X86_MSR_GS_BASE 0xc0000101
#define X86_MSR_VM_HSAVE_PA 0xc0010117
#define X86_MSR_IA32_VMX_PROCBASED_CTLS2 0x48B
+// VMX control bits
+#define RFLAGS_1_BIT (1ULL << 1)
+#define CPU_BASED_HLT_EXITING (1U << 7)
+#define AR_TSS_AVAILABLE 0x0089
+#define SVM_ATTR_LDTR_UNUSABLE 0x0000
+#define VMX_AR_TSS_BUSY 0x008b
+#define VMX_AR_TSS_AVAILABLE 0x0089
+#define VMX_AR_LDTR_UNUSABLE 0x10000
+#define VM_ENTRY_IA32E_MODE (1U << 9)
+#define SECONDARY_EXEC_ENABLE_EPT (1U << 1)
+#define VM_EXIT_HOST_ADDR_SPACE_SIZE (1U << 9)
+#define CPU_BASED_ACTIVATE_SECONDARY_CONTROLS (1U << 31)
+
+#define VMX_ACCESS_RIGHTS_P (1 << 7)
+#define VMX_ACCESS_RIGHTS_S (1 << 4)
+#define VMX_ACCESS_RIGHTS_TYPE_A (1 << 0)
+#define VMX_ACCESS_RIGHTS_TYPE_RW (1 << 1)
+#define VMX_ACCESS_RIGHTS_TYPE_E (1 << 3)
+#define VMX_ACCESS_RIGHTS_G (1 << 15)
+#define VMX_ACCESS_RIGHTS_DB (1 << 14)
+#define VMX_ACCESS_RIGHTS_L (1 << 13)
+
+// This is a 64-bit data/stack segment:
+// P=1, S=1, Type=3 (RW+Accessed), G=1, DB=1, L=0
+#define VMX_AR_64BIT_DATA_STACK (VMX_ACCESS_RIGHTS_P | VMX_ACCESS_RIGHTS_S | \
+ VMX_ACCESS_RIGHTS_TYPE_RW | VMX_ACCESS_RIGHTS_TYPE_A | \
+ VMX_ACCESS_RIGHTS_G | VMX_ACCESS_RIGHTS_DB)
+
+// This is a 64-bit code segment:
+// P=1, S=1, Type=11 (Exec/Read+Accessed), G=1, DB=0, L=1
+#define VMX_AR_64BIT_CODE (VMX_ACCESS_RIGHTS_P | VMX_ACCESS_RIGHTS_S | \
+ VMX_ACCESS_RIGHTS_TYPE_E | VMX_ACCESS_RIGHTS_TYPE_RW | \
+ VMX_ACCESS_RIGHTS_TYPE_A | VMX_ACCESS_RIGHTS_G | \
+ VMX_ACCESS_RIGHTS_L)
+
+// VMCS Control Fields.
+#define VMCS_VIRTUAL_PROCESSOR_ID 0x00000000
+#define VMCS_POSTED_INTR_NV 0x00000002
+#define VMCS_MSR_BITMAP 0x00002004
+#define VMCS_VMREAD_BITMAP 0x00002006
+#define VMCS_VMWRITE_BITMAP 0x00002008
+#define VMCS_EPT_POINTER 0x0000201a
+#define VMCS_LINK_POINTER 0x00002800
+#define VMCS_PIN_BASED_VM_EXEC_CONTROL 0x00004000
+#define VMCS_CPU_BASED_VM_EXEC_CONTROL 0x00004002
+#define VMCS_EXCEPTION_BITMAP 0x00004004
+#define VMCS_PAGE_FAULT_ERROR_CODE_MASK 0x00004006
+#define VMCS_PAGE_FAULT_ERROR_CODE_MATCH 0x00004008
+#define VMCS_CR3_TARGET_COUNT 0x0000400a
+#define VMCS_VM_EXIT_CONTROLS 0x0000400c
+#define VMCS_VM_EXIT_MSR_STORE_COUNT 0x0000400e
+#define VMCS_VM_EXIT_MSR_LOAD_COUNT 0x00004010
+#define VMCS_VM_ENTRY_CONTROLS 0x00004012
+#define VMCS_VM_ENTRY_MSR_LOAD_COUNT 0x00004014
+#define VMCS_VM_ENTRY_INTR_INFO_FIELD 0x00004016
+#define VMCS_TPR_THRESHOLD 0x0000401c
+#define VMCS_SECONDARY_VM_EXEC_CONTROL 0x0000401e
+#define VMCS_VMX_PREEMPTION_TIMER_VALUE 0x0000482e
+#define VMCS_CR0_GUEST_HOST_MASK 0x00006000
+#define VMCS_CR4_GUEST_HOST_MASK 0x00006002
+#define VMCS_CR0_READ_SHADOW 0x00006004
+#define VMCS_CR4_READ_SHADOW 0x00006006
+
+// VMCS Host State Fields.
+#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
+#define VMCS_HOST_IA32_PAT 0x00002c00
+#define VMCS_HOST_IA32_EFER 0x00002c02
+#define VMCS_HOST_IA32_PERF_GLOBAL_CTRL 0x00002c04
+#define VMCS_HOST_IA32_SYSENTER_CS 0x00004c00
+#define VMCS_HOST_CR0 0x00006c00
+#define VMCS_HOST_CR3 0x00006c02
+#define VMCS_HOST_CR4 0x00006c04
+#define VMCS_HOST_FS_BASE 0x00006c06
+#define VMCS_HOST_GS_BASE 0x00006c08
+#define VMCS_HOST_TR_BASE 0x00006c0a
+#define VMCS_HOST_GDTR_BASE 0x00006c0c
+#define VMCS_HOST_IDTR_BASE 0x00006c0e
+#define VMCS_HOST_IA32_SYSENTER_ESP 0x00006c10
+#define VMCS_HOST_IA32_SYSENTER_EIP 0x00006c12
+#define VMCS_HOST_RSP 0x00006c14
+#define VMCS_HOST_RIP 0x00006c16
+
+// VMCS Guest State Fields.
+#define VMCS_GUEST_INTR_STATUS 0x00000810
+#define VMCS_GUEST_PML_INDEX 0x00000812
+#define VMCS_GUEST_IA32_DEBUGCTL 0x00002802
+#define VMCS_GUEST_IA32_PAT 0x00002804
+#define VMCS_GUEST_IA32_EFER 0x00002806
+#define VMCS_GUEST_IA32_PERF_GLOBAL_CTRL 0x00002808
+#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
+#define VMCS_GUEST_ES_LIMIT 0x00004800
+#define VMCS_GUEST_CS_LIMIT 0x00004802
+#define VMCS_GUEST_SS_LIMIT 0x00004804
+#define VMCS_GUEST_DS_LIMIT 0x00004806
+#define VMCS_GUEST_FS_LIMIT 0x00004808
+#define VMCS_GUEST_GS_LIMIT 0x0000480a
+#define VMCS_GUEST_LDTR_LIMIT 0x0000480c
+#define VMCS_GUEST_TR_LIMIT 0x0000480e
+#define VMCS_GUEST_GDTR_LIMIT 0x00004810
+#define VMCS_GUEST_IDTR_LIMIT 0x00004812
+#define VMCS_GUEST_ES_ACCESS_RIGHTS 0x00004814
+#define VMCS_GUEST_CS_ACCESS_RIGHTS 0x00004816
+#define VMCS_GUEST_SS_ACCESS_RIGHTS 0x00004818
+#define VMCS_GUEST_DS_ACCESS_RIGHTS 0x0000481a
+#define VMCS_GUEST_FS_ACCESS_RIGHTS 0x0000481c
+#define VMCS_GUEST_GS_ACCESS_RIGHTS 0x0000481e
+#define VMCS_GUEST_LDTR_ACCESS_RIGHTS 0x00004820
+#define VMCS_GUEST_TR_ACCESS_RIGHTS 0x00004822
+#define VMCS_GUEST_ACTIVITY_STATE 0x00004824
+#define VMCS_GUEST_INTERRUPTIBILITY_INFO 0x00004826
+#define VMCS_GUEST_SYSENTER_CS 0x0000482a
+#define VMCS_GUEST_CR0 0x00006800
+#define VMCS_GUEST_CR3 0x00006802
+#define VMCS_GUEST_CR4 0x00006804
+#define VMCS_GUEST_ES_BASE 0x00006806
+#define VMCS_GUEST_CS_BASE 0x00006808
+#define VMCS_GUEST_SS_BASE 0x0000680a
+#define VMCS_GUEST_DS_BASE 0x0000680c
+#define VMCS_GUEST_FS_BASE 0x0000680e
+#define VMCS_GUEST_GS_BASE 0x00006810
+#define VMCS_GUEST_LDTR_BASE 0x00006812
+#define VMCS_GUEST_TR_BASE 0x00006814
+#define VMCS_GUEST_GDTR_BASE 0x00006816
+#define VMCS_GUEST_IDTR_BASE 0x00006818
+#define VMCS_GUEST_DR7 0x0000681a
+#define VMCS_GUEST_RSP 0x0000681c
+#define VMCS_GUEST_RIP 0x0000681e
+#define VMCS_GUEST_RFLAGS 0x00006820
+#define VMCS_GUEST_PENDING_DBG_EXCEPTIONS 0x00006822
+#define VMCS_GUEST_SYSENTER_ESP 0x00006824
+#define VMCS_GUEST_SYSENTER_EIP 0x00006826
+
+// VMCB (Virtual Machine Control Block) Field Offsets
+// (From AMD64 Programmer's Manual Vol 2, Appendix B)
+
+// Control Area
+#define VMCB_CTRL_INTERCEPT_VEC3 0x0c
+#define VMCB_CTRL_INTERCEPT_HLT (1 << 24) // Bit 24 in VEC3
+#define VMCB_CTRL_INTERCEPT_VEC4 0x10
+// Bits 0-9: intercept VMRUN, VMMCALL, VMLOAD, VMSAVE, STGI, CLGI, SKINIT, RDTSCP, ICEBP, WBINVD.
+#define VMCB_CTRL_INTERCEPT_VEC4_ALL (0x3ff)
+
+#define VMCB_CTRL_ASID 0x058
+#define VMCB_EXIT_CODE 0x070
+
+// NP_ENABLE is actually 1 byte, but the 7 following bytes are reserved, so it's okay
+#define VMCB_CTRL_NP_ENABLE 0x090
+#define VMCB_CTRL_NPT_ENABLE_BIT 0
+
+#define VMCB_CTRL_N_CR3 0x0b0
+
+// Guest State Area (starts at 0x400)
+#define VMCB_GUEST_ES_SEL 0x400
+#define VMCB_GUEST_ES_ATTR 0x402
+#define VMCB_GUEST_ES_LIM 0x404
+#define VMCB_GUEST_ES_BASE 0x408
+#define VMCB_GUEST_CS_SEL 0x410
+#define VMCB_GUEST_CS_ATTR 0x412
+#define VMCB_GUEST_CS_LIM 0x414
+#define VMCB_GUEST_CS_BASE 0x418
+#define VMCB_GUEST_SS_SEL 0x420
+#define VMCB_GUEST_SS_ATTR 0x422
+#define VMCB_GUEST_SS_LIM 0x424
+#define VMCB_GUEST_SS_BASE 0x428
+#define VMCB_GUEST_DS_SEL 0x430
+#define VMCB_GUEST_DS_ATTR 0x432
+#define VMCB_GUEST_DS_LIM 0x434
+#define VMCB_GUEST_DS_BASE 0x438
+#define VMCB_GUEST_FS_SEL 0x440
+#define VMCB_GUEST_FS_ATTR 0x442
+#define VMCB_GUEST_FS_LIM 0x444
+#define VMCB_GUEST_FS_BASE 0x448
+#define VMCB_GUEST_GS_SEL 0x450
+#define VMCB_GUEST_GS_ATTR 0x452
+#define VMCB_GUEST_GS_LIM 0x454
+#define VMCB_GUEST_GS_BASE 0x458
+
+#define VMCB_GUEST_IDTR_SEL 0x480
+#define VMCB_GUEST_IDTR_ATTR 0x482
+#define VMCB_GUEST_IDTR_LIM 0x484
+#define VMCB_GUEST_IDTR_BASE 0x488
+#define VMCB_GUEST_GDTR_SEL 0x460
+#define VMCB_GUEST_GDTR_ATTR 0x462
+#define VMCB_GUEST_GDTR_LIM 0x464
+#define VMCB_GUEST_GDTR_BASE 0x468
+#define VMCB_GUEST_LDTR_SEL 0x470
+#define VMCB_GUEST_LDTR_ATTR 0x472
+#define VMCB_GUEST_LDTR_LIM 0x474
+#define VMCB_GUEST_LDTR_BASE 0x478
+#define VMCB_GUEST_TR_SEL 0x490
+#define VMCB_GUEST_TR_ATTR 0x492
+#define VMCB_GUEST_TR_LIM 0x494
+#define VMCB_GUEST_TR_BASE 0x498
+
+#define VMCB_GUEST_EFER 0x4d0
+#define VMCB_GUEST_CR4 0x548
+#define VMCB_GUEST_CR3 0x550
+#define VMCB_GUEST_CR0 0x558
+#define VMCB_GUEST_DR7 0x560
+#define VMCB_GUEST_DR6 0x568
+#define VMCB_GUEST_RFLAGS 0x570
+#define VMCB_GUEST_RIP 0x578
+#define VMCB_GUEST_RSP 0x5d8
+#define VMCB_GUEST_PAT 0x668
+#define VMCB_GUEST_DEBUGCTL 0x670
+
+// SVM Segment Attribute Defines
+#define SVM_ATTR_G (1 << 15)
+#define SVM_ATTR_DB (1 << 14)
+#define SVM_ATTR_L (1 << 13)
+#define SVM_ATTR_P (1 << 7)
+#define SVM_ATTR_S (1 << 4)
+// Type bits.
+#define SVM_ATTR_TYPE_A (1 << 0)
+#define SVM_ATTR_TYPE_RW (1 << 1)
+#define SVM_ATTR_TYPE_E (1 << 3)
+
+// 64-bit Code Segment: P=1, S=1, Type=11 (E/R/A), L=1, G=1
+#define SVM_ATTR_64BIT_CODE \
+ (SVM_ATTR_P | SVM_ATTR_S | SVM_ATTR_TYPE_E | SVM_ATTR_TYPE_RW | \
+ SVM_ATTR_TYPE_A | SVM_ATTR_L | SVM_ATTR_G)
+
+// 64-bit Data Segment: P=1, S=1, Type=3 (RW/A), D/B=1, G=1
+#define SVM_ATTR_64BIT_DATA \
+ (SVM_ATTR_P | SVM_ATTR_S | SVM_ATTR_TYPE_RW | SVM_ATTR_TYPE_A | \
+ SVM_ATTR_DB | SVM_ATTR_G)
+
#define X86_NEXT_INSN $0xbadc0de
#define X86_PREFIX_SIZE 0xba1d
#endif // x86-specific definitions.
@@ -275,4 +528,4 @@
#endif // ARM64 SYZOS definitions
-#endif // EXECUTOR_KVM_H \ No newline at end of file
+#endif // EXECUTOR_KVM_H