From 64df03c2303bfe47a259e397aad54ee301c390d5 Mon Sep 17 00:00:00 2001 From: Thomas Oltmann Date: Mon, 10 Mar 2025 20:24:32 +0100 Subject: [PATCH] Calling VMXON --- include/x86/cr.h | 8 ++++++++ include/x86/msr.h | 2 +- include/x86/vmx.h | 19 ++++++++++++++---- src/efi.c | 6 ++++++ src/vintel.c | 50 +++++++++++++++++++++++++++++++++++------------ src/virt.h | 1 + 6 files changed, 69 insertions(+), 17 deletions(-) diff --git a/include/x86/cr.h b/include/x86/cr.h index e14a77e..83b3bf2 100644 --- a/include/x86/cr.h +++ b/include/x86/cr.h @@ -3,6 +3,8 @@ #include +#define CR4_VMXE (1 << 13) + static inline uint64_t readcr0(void) { @@ -27,4 +29,10 @@ readcr4(void) return v; } +static inline void +writecr4(uint64_t v) +{ + __asm__ ("mov %0, %%cr4\n\t" :: "a"(v)); +} + #endif diff --git a/include/x86/msr.h b/include/x86/msr.h index 21a6f69..a889613 100644 --- a/include/x86/msr.h +++ b/include/x86/msr.h @@ -21,7 +21,7 @@ static inline uint32_t rdmsr32(uint32_t msr) { uint32_t value; - __asm__ ("rdmsr\n\t" : "=a"(value) : "c"(msr) : "d"); + __asm__ ("rdmsr\n\t" : "=a"(value) : "c"(msr) : "edx"); return value; } diff --git a/include/x86/vmx.h b/include/x86/vmx.h index 83a909b..1d358c0 100644 --- a/include/x86/vmx.h +++ b/include/x86/vmx.h @@ -3,10 +3,14 @@ #include -struct VMCS { - /* VMCS Header */ +struct VMXON { uint32_t revisionID; uint32_t abortIndicator; + char vmcsData[]; +}; + +struct VMCS { + int _placeholder; /* Guest-state area */ /* Host-state area */ /* VM-execution control fields */ @@ -15,10 +19,17 @@ struct VMCS { /* VM-exit information fields */ }; -static inline void +static inline uint64_t vmxon(void *region) { - __asm__ volatile ("vmxon %0\n\t" :: "r"(region)); + uint64_t regionpa = (uint64_t)region; + uint64_t flags; + __asm__ volatile ( + "vmxon %1\n\t" + "pushf \n\t" + "pop %0\n\t" + : "=r"(flags) : "m"(regionpa)); + return flags; } static inline void diff --git a/src/efi.c b/src/efi.c index f79b36d..8d93257 100644 --- a/src/efi.c +++ b/src/efi.c @@ -14,10 +14,16 @@ EFI_STATUS efi_main(EFI_HANDLE imageHandle, EFI_SYSTEM_TABLE *systemTable) { InitializeLib(imageHandle, systemTable); + Print(L"Hello, World!\n"); + AsciiPrint("* Checking for VT-x Support\n"); if (!virt->has_support(virt_err, sizeof virt_err)) { AsciiPrint(virt_err); + } else { + AsciiPrint("* Enabling VT-x\n"); + virt->enable(); + AsciiPrint("* VT-x enabled!\n"); } for (;;) {} diff --git a/src/vintel.c b/src/vintel.c index 91772f8..f556a55 100644 --- a/src/vintel.c +++ b/src/vintel.c @@ -1,10 +1,17 @@ +#include +#include +#include + #include #include #include +#include #include "virt.h" #include "std.h" +static struct VMXON *vmxon_region; + static bool vintel_has_bios_support(void) { @@ -20,13 +27,6 @@ vintel_has_cpu_support(void) return (info[2] & (1 << 5)) != 0; } -static bool -vintel_has_cr4_support(void) -{ - uint64_t value = readcr4(); - return (value & (1 << 13)) != 0; -} - bool vintel_has_support(char *err, size_t errmax) { @@ -40,14 +40,40 @@ vintel_has_support(char *err, size_t errmax) return false; } - if (!vintel_has_cr4_support()) { - strlcpy(err, "VT-x enable bit is not set in CR4.", errmax); - return false; - } - return true; } +void +vintel_enable(void) +{ + Print(L"Set CR4 Bit\n"); + writecr4(readcr4() | CR4_VMXE); + +#if 0 + Print(L"Enable in Feature Control\n"); + uint64_t fctl = rdmsr64(IA32_FEATURE_CONTROL); + fctl |= (1 << 0); + wrmsr64(IA32_FEATURE_CONTROL, fctl); +#endif + + Print(L"Allocating VMXON Page\n"); + uefi_call_wrapper(BS->AllocatePages, 4, AllocateAnyPages, EfiRuntimeServicesData, 1, &vmxon_region); + + Print(L"VMCS: %p\n", vmxon_region); + vmxon_region->revisionID = rdmsr32(IA32_VMX_BASIC); + Print(L"Set Revision ID.\n"); + + uint64_t status = vmxon(vmxon_region); + Print(L"VMXON Status: %p\n", (void *)status); + if (status & (1 << 0)) { + Print(L"Invalid VMCS Pointer\n"); + } + if (status & (1 << 6)) { + Print(L"Extended VMX Error\n"); + } +} + struct virt_vtable virt_vtable_intel = { .has_support = vintel_has_support, + .enable = vintel_enable, }; diff --git a/src/virt.h b/src/virt.h index 542aec9..6d0ee7e 100644 --- a/src/virt.h +++ b/src/virt.h @@ -6,6 +6,7 @@ struct virt_vtable { bool (*has_support)(char *err, size_t errmax); + void (*enable)(void); }; extern struct virt_vtable virt_vtable_intel;