From 56d72e41f24f181e244b7f91ed90c248d388d5fa Mon Sep 17 00:00:00 2001 From: Thomas Oltmann Date: Mon, 10 Mar 2025 20:41:09 +0100 Subject: [PATCH] VMCLEAR & VMPTRLD --- include/x86/vmx.h | 30 ++++++++++++++++++++++-------- src/vintel.c | 17 +++++++++++++++-- 2 files changed, 37 insertions(+), 10 deletions(-) diff --git a/include/x86/vmx.h b/include/x86/vmx.h index 1d358c0..729f746 100644 --- a/include/x86/vmx.h +++ b/include/x86/vmx.h @@ -10,7 +10,7 @@ struct VMXON { }; struct VMCS { - int _placeholder; + uint32_t revisionID; /* Guest-state area */ /* Host-state area */ /* VM-execution control fields */ @@ -25,9 +25,9 @@ vmxon(void *region) uint64_t regionpa = (uint64_t)region; uint64_t flags; __asm__ volatile ( - "vmxon %1\n\t" - "pushf \n\t" - "pop %0\n\t" + "vmxon %1\n\t" + "pushf \n\t" + "pop %0\n\t" : "=r"(flags) : "m"(regionpa)); return flags; } @@ -38,10 +38,17 @@ vmxoff(void) __asm__ volatile ("vmxoff\n\t" ::); } -static inline void +static inline uint64_t vmptrld(void *region) { - __asm__ volatile ("vmptrld %0\n\t" :: "r"(region)); + uint64_t regionpa = (uint64_t)region; + uint64_t flags; + __asm__ volatile ( + "vmptrld %1\n\t" + "pushf \n\t" + "pop %0\n\t" + : "=r"(flags) : "m"(regionpa)); + return flags; } static inline void @@ -50,10 +57,17 @@ vmptrst(void *arg) __asm__ volatile ("vmptrst\n\t" ::); } -static inline void +static inline uint64_t vmclear(void *region) { - __asm__ volatile ("vmclear %0\n\t" :: "r"(region)); + uint64_t regionpa = (uint64_t)region; + uint64_t flags; + __asm__ volatile ( + "vmclear %1\n\t" + "pushf \n\t" + "pop %0\n\t" + : "=r"(flags) : "m"(regionpa)); + return flags; } static inline void diff --git a/src/vintel.c b/src/vintel.c index f556a55..c52bc71 100644 --- a/src/vintel.c +++ b/src/vintel.c @@ -11,6 +11,7 @@ #include "std.h" static struct VMXON *vmxon_region; +static struct VMCS *vmcs_region; static bool vintel_has_bios_support(void) @@ -59,9 +60,8 @@ vintel_enable(void) Print(L"Allocating VMXON Page\n"); uefi_call_wrapper(BS->AllocatePages, 4, AllocateAnyPages, EfiRuntimeServicesData, 1, &vmxon_region); - Print(L"VMCS: %p\n", vmxon_region); + Print(L"VMXON: %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); @@ -71,6 +71,19 @@ vintel_enable(void) if (status & (1 << 6)) { Print(L"Extended VMX Error\n"); } + + + Print(L"Allocating VMCS Page\n"); + uefi_call_wrapper(BS->AllocatePages, 4, AllocateAnyPages, EfiRuntimeServicesData, 1, &vmcs_region); + + Print(L"VMCS: %p\n", vmcs_region); + vmcs_region->revisionID = rdmsr32(IA32_VMX_BASIC); + + status = vmclear(vmcs_region); + Print(L"VMCLEAR Status: %p\n", (void *)status); + + status = vmptrld(vmcs_region); + Print(L"VMPTRLD Status: %p\n", (void *)status); } struct virt_vtable virt_vtable_intel = {