Calling VMXON

This commit is contained in:
Thomas Oltmann 2025-03-10 20:24:32 +01:00
parent ec58283e42
commit 64df03c230
6 changed files with 69 additions and 17 deletions

View file

@ -3,6 +3,8 @@
#include <stdint.h>
#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

View file

@ -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;
}

View file

@ -3,10 +3,14 @@
#include <stdint.h>
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

View file

@ -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 (;;) {}

View file

@ -1,10 +1,17 @@
#include <efi.h>
#include <efilib.h>
#include <efiapi.h>
#include <cpuid.h>
#include <x86/msr.h>
#include <x86/cr.h>
#include <x86/vmx.h>
#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,
};

View file

@ -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;