VMCLEAR & VMPTRLD

This commit is contained in:
Thomas Oltmann 2025-03-10 20:41:09 +01:00
parent 64df03c230
commit 56d72e41f2
2 changed files with 37 additions and 10 deletions

View file

@ -10,7 +10,7 @@ struct VMXON {
}; };
struct VMCS { struct VMCS {
int _placeholder; uint32_t revisionID;
/* Guest-state area */ /* Guest-state area */
/* Host-state area */ /* Host-state area */
/* VM-execution control fields */ /* VM-execution control fields */
@ -25,9 +25,9 @@ vmxon(void *region)
uint64_t regionpa = (uint64_t)region; uint64_t regionpa = (uint64_t)region;
uint64_t flags; uint64_t flags;
__asm__ volatile ( __asm__ volatile (
"vmxon %1\n\t" "vmxon %1\n\t"
"pushf \n\t" "pushf \n\t"
"pop %0\n\t" "pop %0\n\t"
: "=r"(flags) : "m"(regionpa)); : "=r"(flags) : "m"(regionpa));
return flags; return flags;
} }
@ -38,10 +38,17 @@ vmxoff(void)
__asm__ volatile ("vmxoff\n\t" ::); __asm__ volatile ("vmxoff\n\t" ::);
} }
static inline void static inline uint64_t
vmptrld(void *region) 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 static inline void
@ -50,10 +57,17 @@ vmptrst(void *arg)
__asm__ volatile ("vmptrst\n\t" ::); __asm__ volatile ("vmptrst\n\t" ::);
} }
static inline void static inline uint64_t
vmclear(void *region) 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 static inline void

View file

@ -11,6 +11,7 @@
#include "std.h" #include "std.h"
static struct VMXON *vmxon_region; static struct VMXON *vmxon_region;
static struct VMCS *vmcs_region;
static bool static bool
vintel_has_bios_support(void) vintel_has_bios_support(void)
@ -59,9 +60,8 @@ vintel_enable(void)
Print(L"Allocating VMXON Page\n"); Print(L"Allocating VMXON Page\n");
uefi_call_wrapper(BS->AllocatePages, 4, AllocateAnyPages, EfiRuntimeServicesData, 1, &vmxon_region); 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); vmxon_region->revisionID = rdmsr32(IA32_VMX_BASIC);
Print(L"Set Revision ID.\n");
uint64_t status = vmxon(vmxon_region); uint64_t status = vmxon(vmxon_region);
Print(L"VMXON Status: %p\n", (void *)status); Print(L"VMXON Status: %p\n", (void *)status);
@ -71,6 +71,19 @@ vintel_enable(void)
if (status & (1 << 6)) { if (status & (1 << 6)) {
Print(L"Extended VMX Error\n"); 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 = { struct virt_vtable virt_vtable_intel = {