#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) { 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; } 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, };