Calling VMXON
This commit is contained in:
parent
ec58283e42
commit
64df03c230
6 changed files with 69 additions and 17 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 (;;) {}
|
||||
|
|
|
|||
48
src/vintel.c
48
src/vintel.c
|
|
@ -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;
|
||||
}
|
||||
|
||||
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,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue