Setting even more execution control fields

This commit is contained in:
Thomas Oltmann 2025-03-12 03:25:50 +01:00
parent ba33c4bf8d
commit 1cf6571671
2 changed files with 36 additions and 10 deletions

View file

@ -19,6 +19,8 @@
#define IA32_VMX_CR4_FIXED1 0x489 #define IA32_VMX_CR4_FIXED1 0x489
#define IA32_VMX_TRUE_ENTRY_CTLS 0x490 #define IA32_VMX_TRUE_ENTRY_CTLS 0x490
#define IA32_VMX_VMCS_ENUM 0x48A #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_EFER 0xC0000080
#define IA32_FS_BASE 0xC0000100 #define IA32_FS_BASE 0xC0000100

View file

@ -90,6 +90,33 @@ vintel_fix_cr_bits(void)
#define GUEST_GDTR_BASE 0x6816 #define GUEST_GDTR_BASE 0x6816
#define GUEST_IDTR_BASE 0x6818 #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 // HACK
char guest_stack[4096]; char guest_stack[4096];
@ -273,22 +300,19 @@ vintel_enable(void)
status = vmptrld(vmcs_region); status = vmptrld(vmcs_region);
Print(L"VMPTRLD Status: %lx\n", status); Print(L"VMPTRLD Status: %lx\n", status);
vmx_init_execution_controls();
vintel_init_guest(); vintel_init_guest();
vintel_init_host(); vintel_init_host();
{ {
AsciiPrint("* Initializing VMX Entry Controls\n"); AsciiPrint("* Initializing VMX Entry Controls\n");
uint64_t vmxBasic = readmsr64(IA32_VMX_BASIC); uint64_t vmxBasic = readmsr64(IA32_VMX_BASIC);
uint64_t mask; uint32_t msr = ((vmxBasic >> 55) & 1) ? IA32_VMX_TRUE_ENTRY_CTLS : IA32_VMX_ENTRY_CTLS;
if (vmxBasic & (1ul << 55)) { uint64_t entryControls = vmx_adjust_controls(0x200, msr); // 0x200 enables IA-32e mode
mask = readmsr64(IA32_VMX_TRUE_ENTRY_CTLS); vmwrite(VM_ENTRY_CONTROLS, entryControls);
} else {
mask = readmsr64(IA32_VMX_ENTRY_CTLS); vmwrite(VM_ENTRY_MSR_LOAD_COUNT, 0);
} vmwrite(VM_ENTRY_INTR_INFO_FIELD, 0);
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);
} }
status = vmlaunch(); status = vmlaunch();