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>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define CR4_VMXE (1 << 13)
|
||||||
|
|
||||||
static inline uint64_t
|
static inline uint64_t
|
||||||
readcr0(void)
|
readcr0(void)
|
||||||
{
|
{
|
||||||
|
|
@ -27,4 +29,10 @@ readcr4(void)
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
writecr4(uint64_t v)
|
||||||
|
{
|
||||||
|
__asm__ ("mov %0, %%cr4\n\t" :: "a"(v));
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ static inline uint32_t
|
||||||
rdmsr32(uint32_t msr)
|
rdmsr32(uint32_t msr)
|
||||||
{
|
{
|
||||||
uint32_t value;
|
uint32_t value;
|
||||||
__asm__ ("rdmsr\n\t" : "=a"(value) : "c"(msr) : "d");
|
__asm__ ("rdmsr\n\t" : "=a"(value) : "c"(msr) : "edx");
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,10 +3,14 @@
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
struct VMCS {
|
struct VMXON {
|
||||||
/* VMCS Header */
|
|
||||||
uint32_t revisionID;
|
uint32_t revisionID;
|
||||||
uint32_t abortIndicator;
|
uint32_t abortIndicator;
|
||||||
|
char vmcsData[];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct VMCS {
|
||||||
|
int _placeholder;
|
||||||
/* Guest-state area */
|
/* Guest-state area */
|
||||||
/* Host-state area */
|
/* Host-state area */
|
||||||
/* VM-execution control fields */
|
/* VM-execution control fields */
|
||||||
|
|
@ -15,10 +19,17 @@ struct VMCS {
|
||||||
/* VM-exit information fields */
|
/* VM-exit information fields */
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline void
|
static inline uint64_t
|
||||||
vmxon(void *region)
|
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
|
static inline void
|
||||||
|
|
|
||||||
|
|
@ -14,10 +14,16 @@ EFI_STATUS
|
||||||
efi_main(EFI_HANDLE imageHandle, EFI_SYSTEM_TABLE *systemTable)
|
efi_main(EFI_HANDLE imageHandle, EFI_SYSTEM_TABLE *systemTable)
|
||||||
{
|
{
|
||||||
InitializeLib(imageHandle, systemTable);
|
InitializeLib(imageHandle, systemTable);
|
||||||
|
|
||||||
Print(L"Hello, World!\n");
|
Print(L"Hello, World!\n");
|
||||||
|
|
||||||
|
AsciiPrint("* Checking for VT-x Support\n");
|
||||||
if (!virt->has_support(virt_err, sizeof virt_err)) {
|
if (!virt->has_support(virt_err, sizeof virt_err)) {
|
||||||
AsciiPrint(virt_err);
|
AsciiPrint(virt_err);
|
||||||
|
} else {
|
||||||
|
AsciiPrint("* Enabling VT-x\n");
|
||||||
|
virt->enable();
|
||||||
|
AsciiPrint("* VT-x enabled!\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
for (;;) {}
|
for (;;) {}
|
||||||
|
|
|
||||||
50
src/vintel.c
50
src/vintel.c
|
|
@ -1,10 +1,17 @@
|
||||||
|
#include <efi.h>
|
||||||
|
#include <efilib.h>
|
||||||
|
#include <efiapi.h>
|
||||||
|
|
||||||
#include <cpuid.h>
|
#include <cpuid.h>
|
||||||
#include <x86/msr.h>
|
#include <x86/msr.h>
|
||||||
#include <x86/cr.h>
|
#include <x86/cr.h>
|
||||||
|
#include <x86/vmx.h>
|
||||||
|
|
||||||
#include "virt.h"
|
#include "virt.h"
|
||||||
#include "std.h"
|
#include "std.h"
|
||||||
|
|
||||||
|
static struct VMXON *vmxon_region;
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
vintel_has_bios_support(void)
|
vintel_has_bios_support(void)
|
||||||
{
|
{
|
||||||
|
|
@ -20,13 +27,6 @@ vintel_has_cpu_support(void)
|
||||||
return (info[2] & (1 << 5)) != 0;
|
return (info[2] & (1 << 5)) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
|
||||||
vintel_has_cr4_support(void)
|
|
||||||
{
|
|
||||||
uint64_t value = readcr4();
|
|
||||||
return (value & (1 << 13)) != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
vintel_has_support(char *err, size_t errmax)
|
vintel_has_support(char *err, size_t errmax)
|
||||||
{
|
{
|
||||||
|
|
@ -40,14 +40,40 @@ vintel_has_support(char *err, size_t errmax)
|
||||||
return false;
|
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 = {
|
struct virt_vtable virt_vtable_intel = {
|
||||||
.has_support = vintel_has_support,
|
.has_support = vintel_has_support,
|
||||||
|
.enable = vintel_enable,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
struct virt_vtable {
|
struct virt_vtable {
|
||||||
bool (*has_support)(char *err, size_t errmax);
|
bool (*has_support)(char *err, size_t errmax);
|
||||||
|
void (*enable)(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct virt_vtable virt_vtable_intel;
|
extern struct virt_vtable virt_vtable_intel;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue