From 1cf657167126883be8e97ddf1a5b80d7e2934c53 Mon Sep 17 00:00:00 2001 From: Thomas Oltmann Date: Wed, 12 Mar 2025 03:25:50 +0100 Subject: [PATCH] Setting even more execution control fields --- include/x86/msr.h | 2 ++ src/vintel.c | 44 ++++++++++++++++++++++++++++++++++---------- 2 files changed, 36 insertions(+), 10 deletions(-) diff --git a/include/x86/msr.h b/include/x86/msr.h index a1b5550..2a7290e 100644 --- a/include/x86/msr.h +++ b/include/x86/msr.h @@ -19,6 +19,8 @@ #define IA32_VMX_CR4_FIXED1 0x489 #define IA32_VMX_TRUE_ENTRY_CTLS 0x490 #define IA32_VMX_VMCS_ENUM 0x48A +#define IA32_VMX_TRUE_PINBASED_CTLS 0x48D +#define IA32_VMX_TRUE_PROCBASED_CTLS 0x48E #define IA32_EFER 0xC0000080 #define IA32_FS_BASE 0xC0000100 diff --git a/src/vintel.c b/src/vintel.c index 8ca188e..e163656 100644 --- a/src/vintel.c +++ b/src/vintel.c @@ -90,6 +90,33 @@ vintel_fix_cr_bits(void) #define GUEST_GDTR_BASE 0x6816 #define GUEST_IDTR_BASE 0x6818 +#define PIN_BASED_VM_EXEC_CONTROL 0x4000 +#define CPU_BASED_VM_EXEC_CONTROL 0x4002 +#define VM_ENTRY_MSR_LOAD_COUNT 0x4014 +#define VM_ENTRY_INTR_INFO_FIELD 0x4016 + +static uint64_t +vmx_adjust_controls(uint64_t value, uint32_t msr) +{ + uint64_t msrValue = readmsr64(msr); + value = ((msrValue & 0xffffffff) | value) & (msrValue >> 32); + return value; +} + +static void +vmx_init_execution_controls(void) +{ + uint64_t vmxBasic = readmsr64(IA32_VMX_BASIC); + uint64_t pinBasedMsr = ((vmxBasic >> 55) & 1) ? IA32_VMX_TRUE_PINBASED_CTLS : IA32_VMX_PINBASED_CTLS; + uint64_t procBasedMsr = ((vmxBasic >> 55) & 1) ? IA32_VMX_TRUE_PROCBASED_CTLS : IA32_VMX_PROCBASED_CTLS; + + uint64_t pinBasedControls = vmx_adjust_controls(0, pinBasedMsr); + uint64_t procBasedControls = vmx_adjust_controls(0, procBasedMsr); + + vmwrite(PIN_BASED_VM_EXEC_CONTROL, pinBasedControls); + vmwrite(CPU_BASED_VM_EXEC_CONTROL, procBasedControls); +} + // HACK char guest_stack[4096]; @@ -273,22 +300,19 @@ vintel_enable(void) status = vmptrld(vmcs_region); Print(L"VMPTRLD Status: %lx\n", status); + vmx_init_execution_controls(); vintel_init_guest(); vintel_init_host(); { AsciiPrint("* Initializing VMX Entry Controls\n"); uint64_t vmxBasic = readmsr64(IA32_VMX_BASIC); - uint64_t mask; - if (vmxBasic & (1ul << 55)) { - mask = readmsr64(IA32_VMX_TRUE_ENTRY_CTLS); - } else { - mask = readmsr64(IA32_VMX_ENTRY_CTLS); - } - AsciiPrint("Entry Controls Mask: %lx\n", mask); - uint64_t entryCtls = (0x200 | (mask & 0xffffffff)) & (mask >> 32); - AsciiPrint("Entry Controls: %lx\n", entryCtls); - vmwrite(VM_ENTRY_CONTROLS, entryCtls); + uint32_t msr = ((vmxBasic >> 55) & 1) ? IA32_VMX_TRUE_ENTRY_CTLS : IA32_VMX_ENTRY_CTLS; + uint64_t entryControls = vmx_adjust_controls(0x200, msr); // 0x200 enables IA-32e mode + vmwrite(VM_ENTRY_CONTROLS, entryControls); + + vmwrite(VM_ENTRY_MSR_LOAD_COUNT, 0); + vmwrite(VM_ENTRY_INTR_INFO_FIELD, 0); } status = vmlaunch();