2025-03-10 20:24:32 +01:00
|
|
|
#include <efi.h>
|
|
|
|
|
#include <efilib.h>
|
|
|
|
|
#include <efiapi.h>
|
|
|
|
|
|
2025-03-10 19:19:53 +01:00
|
|
|
#include <cpuid.h>
|
|
|
|
|
#include <x86/msr.h>
|
|
|
|
|
#include <x86/cr.h>
|
2025-03-10 20:24:32 +01:00
|
|
|
#include <x86/vmx.h>
|
2025-03-10 19:19:53 +01:00
|
|
|
|
|
|
|
|
#include "virt.h"
|
|
|
|
|
#include "std.h"
|
|
|
|
|
|
2025-03-10 20:24:32 +01:00
|
|
|
static struct VMXON *vmxon_region;
|
|
|
|
|
|
2025-03-10 19:19:53 +01:00
|
|
|
static bool
|
|
|
|
|
vintel_has_bios_support(void)
|
|
|
|
|
{
|
|
|
|
|
uint64_t value = rdmsr64(IA32_FEATURE_CONTROL);
|
|
|
|
|
return (value & 0x5) == 0x5;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool
|
|
|
|
|
vintel_has_cpu_support(void)
|
|
|
|
|
{
|
|
|
|
|
unsigned info[4];
|
|
|
|
|
__get_cpuid(0x1, &info[0], &info[1], &info[2], &info[3]);
|
|
|
|
|
return (info[2] & (1 << 5)) != 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
|
vintel_has_support(char *err, size_t errmax)
|
|
|
|
|
{
|
|
|
|
|
if (!vintel_has_cpu_support()) {
|
|
|
|
|
strlcpy(err, "CPU does not support VT-x.", errmax);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!vintel_has_bios_support()) {
|
|
|
|
|
strlcpy(err, "VT-x support is not enabled in BIOS.", errmax);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2025-03-10 20:24:32 +01:00
|
|
|
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");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-03-10 19:19:53 +01:00
|
|
|
struct virt_vtable virt_vtable_intel = {
|
|
|
|
|
.has_support = vintel_has_support,
|
2025-03-10 20:24:32 +01:00
|
|
|
.enable = vintel_enable,
|
2025-03-10 19:19:53 +01:00
|
|
|
};
|