Bug fixes, more state setup
This commit is contained in:
parent
4965c38de9
commit
e1ba08bbc0
5 changed files with 108 additions and 65 deletions
|
|
@ -3,26 +3,27 @@
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#define IA32_FEATURE_CONTROL 0x03A
|
#define IA32_FEATURE_CONTROL 0x03A
|
||||||
#define IA32_DEBUGCTL 0x1D9
|
#define IA32_DEBUGCTL 0x1D9
|
||||||
#define IA32_PAT 0x277
|
#define IA32_PAT 0x277
|
||||||
|
|
||||||
#define IA32_VMX_BASIC 0x480
|
#define IA32_VMX_BASIC 0x480
|
||||||
#define IA32_VMX_PINBASED_CTLS 0x481
|
#define IA32_VMX_PINBASED_CTLS 0x481
|
||||||
#define IA32_VMX_PROCBASED_CTLS 0x482
|
#define IA32_VMX_PROCBASED_CTLS 0x482
|
||||||
#define IA32_VMX_EXIT_CTLS 0x483
|
#define IA32_VMX_EXIT_CTLS 0x483
|
||||||
#define IA32_VMX_ENTRY_CTLS 0x484
|
#define IA32_VMX_ENTRY_CTLS 0x484
|
||||||
#define IA32_VMX_MISC 0x485
|
#define IA32_VMX_MISC 0x485
|
||||||
#define IA32_VMX_CR0_FIXED0 0x486
|
#define IA32_VMX_CR0_FIXED0 0x486
|
||||||
#define IA32_VMX_CR0_FIXED1 0x487
|
#define IA32_VMX_CR0_FIXED1 0x487
|
||||||
#define IA32_VMX_CR4_FIXED0 0x488
|
#define IA32_VMX_CR4_FIXED0 0x488
|
||||||
#define IA32_VMX_CR4_FIXED1 0x489
|
#define IA32_VMX_CR4_FIXED1 0x489
|
||||||
#define IA32_VMX_VMCS_ENUM 0x48A
|
#define IA32_VMX_TRUE_ENTRY_CTLS 0x490
|
||||||
|
#define IA32_VMX_VMCS_ENUM 0x48A
|
||||||
|
|
||||||
#define IA32_EFER 0xC0000080
|
#define IA32_EFER 0xC0000080
|
||||||
#define IA32_FS_BASE 0xC0000100
|
#define IA32_FS_BASE 0xC0000100
|
||||||
#define IA32_GS_BASE 0xC0000101
|
#define IA32_GS_BASE 0xC0000101
|
||||||
#define IA32_KERNEL_GS_BASE 0xC0000102
|
#define IA32_KERNEL_GS_BASE 0xC0000102
|
||||||
|
|
||||||
static inline uint32_t
|
static inline uint32_t
|
||||||
readmsr32(uint32_t msr)
|
readmsr32(uint32_t msr)
|
||||||
|
|
@ -35,22 +36,23 @@ readmsr32(uint32_t msr)
|
||||||
static inline uint64_t
|
static inline uint64_t
|
||||||
readmsr64(uint32_t msr)
|
readmsr64(uint32_t msr)
|
||||||
{
|
{
|
||||||
uint64_t value;
|
uint32_t lo, hi;
|
||||||
__asm__ ("rdmsr\n\t" : "=A"(value) : "c"(msr));
|
__asm__ ("rdmsr\n\t" : "=a"(lo), "=d"(hi) : "c"(msr));
|
||||||
return value;
|
return lo | ((uint64_t)hi << 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
writemsr32(uint32_t msr, uint32_t value)
|
writemsr32(uint32_t msr, uint32_t value)
|
||||||
{
|
{
|
||||||
uint32_t high = 0;
|
uint32_t hi = 0;
|
||||||
__asm__ ("wrmsr\n\t" :: "c"(msr), "a"(value), "d"(high));
|
__asm__ ("wrmsr\n\t" :: "c"(msr), "a"(value), "d"(hi));
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
writemsr64(uint32_t msr, uint64_t value)
|
writemsr64(uint32_t msr, uint64_t value)
|
||||||
{
|
{
|
||||||
__asm__ ("wrmsr\n\t" :: "c"(msr), "A"(value));
|
uint32_t lo = value, hi = value >> 32;
|
||||||
|
__asm__ ("wrmsr\n\t" :: "c"(msr), "a"(lo), "d"(hi));
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define VM_ENTRY_CONTROLS 0x4012
|
||||||
#define VMCS_INSTRUCTION_ERROR 0x4400
|
#define VMCS_INSTRUCTION_ERROR 0x4400
|
||||||
|
|
||||||
struct VMXON {
|
struct VMXON {
|
||||||
|
|
|
||||||
2
run.sh
2
run.sh
|
|
@ -1,3 +1,3 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
OVMF_BLOB=/usr/share/OVMF/x64/OVMF.fd
|
OVMF_BLOB=/usr/share/OVMF/x64/OVMF.fd
|
||||||
uefi-run -d -b "$OVMF_BLOB" build/visor -- -enable-kvm -cpu host "$@"
|
uefi-run -d -b "$OVMF_BLOB" build/visor -- -enable-kvm -cpu kvm64,+vmx "$@"
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,10 @@ efi_main(EFI_HANDLE imageHandle, EFI_SYSTEM_TABLE *systemTable)
|
||||||
{
|
{
|
||||||
InitializeLib(imageHandle, systemTable);
|
InitializeLib(imageHandle, systemTable);
|
||||||
|
|
||||||
|
AsciiPrint("Pointer Size: %d\n", (int)sizeof(void *));
|
||||||
|
|
||||||
|
AsciiPrint("efi_main: %p\n", (void *)efi_main);
|
||||||
|
|
||||||
AsciiPrint("* Setting up processor structures\n");
|
AsciiPrint("* Setting up processor structures\n");
|
||||||
struct procvisor *pv = proc_setup();
|
struct procvisor *pv = proc_setup();
|
||||||
(void)pv;
|
(void)pv;
|
||||||
|
|
|
||||||
116
src/vintel.c
116
src/vintel.c
|
|
@ -11,6 +11,7 @@
|
||||||
|
|
||||||
#include "virt.h"
|
#include "virt.h"
|
||||||
#include "std.h"
|
#include "std.h"
|
||||||
|
#include "procvisor.h"
|
||||||
|
|
||||||
static struct VMXON *vmxon_region;
|
static struct VMXON *vmxon_region;
|
||||||
static struct VMCS *vmcs_region;
|
static struct VMCS *vmcs_region;
|
||||||
|
|
@ -75,15 +76,46 @@ vintel_fix_cr_bits(void)
|
||||||
#define GUEST_SYSENTER_ESP 0x6824
|
#define GUEST_SYSENTER_ESP 0x6824
|
||||||
#define GUEST_SYSENTER_EIP 0x6826
|
#define GUEST_SYSENTER_EIP 0x6826
|
||||||
|
|
||||||
|
#define GUEST_ES_SELECTOR 0x0800
|
||||||
|
#define GUEST_CS_SELECTOR 0x0802
|
||||||
|
#define GUEST_SS_SELECTOR 0x0804
|
||||||
|
#define GUEST_DS_SELECTOR 0x0806
|
||||||
|
#define GUEST_FS_SELECTOR 0x0808
|
||||||
|
#define GUEST_GS_SELECTOR 0x080A
|
||||||
|
|
||||||
|
#define GUEST_GDTR_BASE 0x6816
|
||||||
|
#define GUEST_IDTR_BASE 0x6818
|
||||||
|
|
||||||
|
// HACK
|
||||||
|
char guest_stack[4096];
|
||||||
|
|
||||||
|
void
|
||||||
|
guest_main(void)
|
||||||
|
{
|
||||||
|
AsciiPrint("Hello from guest!\n");
|
||||||
|
|
||||||
|
for (;;) {}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
vintel_init_guest(void)
|
vintel_init_guest(void)
|
||||||
{
|
{
|
||||||
uint64_t guestSP = 0x0;
|
uint64_t guestSP = (uintptr_t)guest_stack + 4096;
|
||||||
uint64_t guestIP = 0x0;
|
uint64_t guestIP = (uintptr_t)(void *)guest_main;
|
||||||
|
|
||||||
|
// Set segment selectors
|
||||||
|
vmwrite(GUEST_ES_SELECTOR, reades() & 0xfff8);
|
||||||
|
vmwrite(GUEST_CS_SELECTOR, readcs() & 0xfff8);
|
||||||
|
vmwrite(GUEST_SS_SELECTOR, readss() & 0xfff8);
|
||||||
|
vmwrite(GUEST_DS_SELECTOR, readds() & 0xfff8);
|
||||||
|
vmwrite(GUEST_FS_SELECTOR, readfs() & 0xfff8);
|
||||||
|
vmwrite(GUEST_GS_SELECTOR, readgs() & 0xfff8);
|
||||||
|
|
||||||
|
// Set control registers
|
||||||
|
vmwrite(GUEST_CR0, readcr0());
|
||||||
|
vmwrite(GUEST_CR3, readcr3());
|
||||||
|
vmwrite(GUEST_CR4, readcr4());
|
||||||
|
|
||||||
vmwrite(GUEST_CR0, readcr0());
|
|
||||||
vmwrite(GUEST_CR3, readcr3());
|
|
||||||
vmwrite(GUEST_CR4, readcr4());
|
|
||||||
vmwrite(GUEST_DR7, readdr7());
|
vmwrite(GUEST_DR7, readdr7());
|
||||||
vmwrite(GUEST_RFLAGS, readflags());
|
vmwrite(GUEST_RFLAGS, readflags());
|
||||||
vmwrite(GUEST_RSP, guestSP);
|
vmwrite(GUEST_RSP, guestSP);
|
||||||
|
|
@ -97,6 +129,12 @@ vintel_init_guest(void)
|
||||||
vmwrite(GUEST_SYSENTER_CS, readmsr64(0x174));
|
vmwrite(GUEST_SYSENTER_CS, readmsr64(0x174));
|
||||||
vmwrite(GUEST_SYSENTER_ESP, readmsr64(0x175));
|
vmwrite(GUEST_SYSENTER_ESP, readmsr64(0x175));
|
||||||
vmwrite(GUEST_SYSENTER_EIP, readmsr64(0x176));
|
vmwrite(GUEST_SYSENTER_EIP, readmsr64(0x176));
|
||||||
|
|
||||||
|
// Set GDT and IDT
|
||||||
|
struct GDTR gdtr = storegdt();
|
||||||
|
struct IDTR idtr = storeidt();
|
||||||
|
vmwrite(GUEST_GDTR_BASE, gdtr.base);
|
||||||
|
vmwrite(GUEST_IDTR_BASE, idtr.base);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define HOST_ES_SELECTOR 0xC00
|
#define HOST_ES_SELECTOR 0xC00
|
||||||
|
|
@ -128,32 +166,21 @@ vintel_init_guest(void)
|
||||||
#define HOST_GDTR_BASE 0x6C0C
|
#define HOST_GDTR_BASE 0x6C0C
|
||||||
#define HOST_IDTR_BASE 0x6C0E
|
#define HOST_IDTR_BASE 0x6C0E
|
||||||
|
|
||||||
#if 1
|
|
||||||
static void
|
static void
|
||||||
vintel_init_host(void)
|
vintel_init_host(void)
|
||||||
{
|
{
|
||||||
#if 0
|
struct procvisor *pv = myprocvisor();
|
||||||
// Read TR
|
|
||||||
trBase.LowPart = ((trItem[0] >> 16) & 0xFFFF) | ((trItem[1] & 0xFF) << 16) | ((trItem[1] & 0xFF000000) >> 8);
|
|
||||||
trBase.HighPart = trItem[2];
|
|
||||||
#endif
|
|
||||||
|
|
||||||
uint64_t trBase = 0x0;
|
uint64_t hostSP = (uintptr_t)pv->host_stack;
|
||||||
uint64_t trSelector = 0x0;
|
|
||||||
uint64_t hostSP = 0x0;
|
|
||||||
uint64_t hostIP = 0x0;
|
uint64_t hostIP = 0x0;
|
||||||
|
|
||||||
// Set TR
|
|
||||||
vmwrite(HOST_TR_BASE, trBase);
|
|
||||||
vmwrite(HOST_TR_SELECTOR, trSelector);
|
|
||||||
|
|
||||||
// Set segment selectors
|
// Set segment selectors
|
||||||
vmwrite(HOST_ES_SELECTOR, reades() & 0xfff8);
|
vmwrite(HOST_ES_SELECTOR, 0x10);
|
||||||
vmwrite(HOST_CS_SELECTOR, readcs() & 0xfff8);
|
vmwrite(HOST_CS_SELECTOR, 0x08);
|
||||||
vmwrite(HOST_SS_SELECTOR, readss() & 0xfff8);
|
vmwrite(HOST_SS_SELECTOR, 0x10);
|
||||||
vmwrite(HOST_DS_SELECTOR, readds() & 0xfff8);
|
vmwrite(HOST_DS_SELECTOR, 0x10);
|
||||||
vmwrite(HOST_FS_SELECTOR, readfs() & 0xfff8);
|
vmwrite(HOST_FS_SELECTOR, 0x00);
|
||||||
vmwrite(HOST_GS_SELECTOR, readgs() & 0xfff8);
|
vmwrite(HOST_GS_SELECTOR, 0x00);
|
||||||
|
|
||||||
// Set control registers
|
// Set control registers
|
||||||
vmwrite(HOST_CR0, readcr0());
|
vmwrite(HOST_CR0, readcr0());
|
||||||
|
|
@ -167,19 +194,11 @@ vintel_init_host(void)
|
||||||
// Set MSRs
|
// Set MSRs
|
||||||
vmwrite(HOST_IA32_PAT, readmsr64(IA32_PAT));
|
vmwrite(HOST_IA32_PAT, readmsr64(IA32_PAT));
|
||||||
vmwrite(HOST_IA32_EFER, readmsr64(IA32_EFER));
|
vmwrite(HOST_IA32_EFER, readmsr64(IA32_EFER));
|
||||||
vmwrite(HOST_FS_BASE, readmsr64(IA32_FS_BASE));
|
|
||||||
vmwrite(HOST_GS_BASE, readmsr64(IA32_KERNEL_GS_BASE));
|
|
||||||
vmwrite(HOST_SYSENTER_CS, readmsr64(0x174));
|
|
||||||
vmwrite(HOST_SYSENTER_ESP, readmsr64(0x175));
|
|
||||||
vmwrite(HOST_SYSENTER_EIP, readmsr64(0x176));
|
|
||||||
|
|
||||||
// Set GDT and IDT
|
// Set GDT and IDT
|
||||||
struct GDTR gdtr = storegdt();
|
vmwrite(HOST_GDTR_BASE, pv->host_gdtr.base);
|
||||||
struct IDTR idtr = storeidt();
|
vmwrite(HOST_IDTR_BASE, pv->host_idtr.base);
|
||||||
vmwrite(HOST_GDTR_BASE, gdtr.base);
|
|
||||||
vmwrite(HOST_IDTR_BASE, idtr.base);
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
void
|
void
|
||||||
vintel_enable(void)
|
vintel_enable(void)
|
||||||
|
|
@ -196,16 +215,18 @@ vintel_enable(void)
|
||||||
|
|
||||||
vintel_fix_cr_bits();
|
vintel_fix_cr_bits();
|
||||||
|
|
||||||
|
AsciiPrint("VMX_BASIC = %lx\n", readmsr64(IA32_VMX_BASIC));
|
||||||
|
|
||||||
Print(L"Allocating VMXON Page\n");
|
Print(L"Allocating VMXON Page\n");
|
||||||
uefi_call_wrapper(BS->AllocatePages, 4, AllocateAnyPages, EfiRuntimeServicesData, 1, &vmxon_region);
|
uefi_call_wrapper(BS->AllocatePages, 4, AllocateAnyPages, EfiRuntimeServicesData, 1, &vmxon_region);
|
||||||
|
|
||||||
Print(L"VMXON: %p\n", vmxon_region);
|
Print(L"VMXON: %p\n", vmxon_region);
|
||||||
vmxon_region->revisionID = readmsr32(IA32_VMX_BASIC);
|
vmxon_region->revisionID = readmsr64(IA32_VMX_BASIC) & 0xffffffff;
|
||||||
|
|
||||||
uint64_t status = vmxon(vmxon_region);
|
uint64_t status = vmxon(vmxon_region);
|
||||||
Print(L"VMXON Status: %p\n", (void *)status);
|
Print(L"VMXON Status: %lx\n", status);
|
||||||
if (status & (1 << 0)) {
|
if (status & (1 << 0)) {
|
||||||
Print(L"Invalid VMCS Pointer\n");
|
Print(L"Invalid VMXON Pointer\n");
|
||||||
}
|
}
|
||||||
if (status & (1 << 6)) {
|
if (status & (1 << 6)) {
|
||||||
Print(L"Extended VMX Error\n");
|
Print(L"Extended VMX Error\n");
|
||||||
|
|
@ -216,17 +237,32 @@ vintel_enable(void)
|
||||||
uefi_call_wrapper(BS->AllocatePages, 4, AllocateAnyPages, EfiRuntimeServicesData, 1, &vmcs_region);
|
uefi_call_wrapper(BS->AllocatePages, 4, AllocateAnyPages, EfiRuntimeServicesData, 1, &vmcs_region);
|
||||||
|
|
||||||
Print(L"VMCS: %p\n", vmcs_region);
|
Print(L"VMCS: %p\n", vmcs_region);
|
||||||
vmcs_region->revisionID = readmsr32(IA32_VMX_BASIC);
|
vmcs_region->revisionID = readmsr64(IA32_VMX_BASIC) & 0xffffffff;
|
||||||
|
|
||||||
status = vmclear(vmcs_region);
|
status = vmclear(vmcs_region);
|
||||||
Print(L"VMCLEAR Status: %p\n", (void *)status);
|
Print(L"VMCLEAR Status: %lx\n", status);
|
||||||
|
|
||||||
status = vmptrld(vmcs_region);
|
status = vmptrld(vmcs_region);
|
||||||
Print(L"VMPTRLD Status: %p\n", (void *)status);
|
Print(L"VMPTRLD Status: %lx\n", status);
|
||||||
|
|
||||||
vintel_init_guest();
|
vintel_init_guest();
|
||||||
vintel_init_host();
|
vintel_init_host();
|
||||||
|
|
||||||
|
{
|
||||||
|
AsciiPrint("* Initializing VMX Entry Controls\n");
|
||||||
|
uint64_t vmxBasic = readmsr64(IA32_VMX_BASIC);
|
||||||
|
uint64_t mask;
|
||||||
|
if (vmxBasic & (1ul << 55)) {
|
||||||
|
mask = readmsr64(IA32_VMX_TRUE_ENTRY_CTLS);
|
||||||
|
} else {
|
||||||
|
mask = readmsr64(IA32_VMX_ENTRY_CTLS);
|
||||||
|
}
|
||||||
|
AsciiPrint("Entry Controls Mask: %lx\n", mask);
|
||||||
|
uint64_t entryCtls = (0x200 | (mask & 0xffffffff)) & (mask >> 32);
|
||||||
|
AsciiPrint("Entry Controls: %lx\n", entryCtls);
|
||||||
|
vmwrite(VM_ENTRY_CONTROLS, entryCtls);
|
||||||
|
}
|
||||||
|
|
||||||
status = vmlaunch();
|
status = vmlaunch();
|
||||||
Print(L"VMLAUNCH Status: %p\n", (void *)status);
|
Print(L"VMLAUNCH Status: %p\n", (void *)status);
|
||||||
if (status & (1 << 0)) {
|
if (status & (1 << 0)) {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue