More checks & setup out of desperation
This commit is contained in:
parent
1cf6571671
commit
4e110312e9
3 changed files with 91 additions and 49 deletions
|
|
@ -19,8 +19,10 @@
|
||||||
#define IA32_VMX_CR4_FIXED1 0x489
|
#define IA32_VMX_CR4_FIXED1 0x489
|
||||||
#define IA32_VMX_TRUE_ENTRY_CTLS 0x490
|
#define IA32_VMX_TRUE_ENTRY_CTLS 0x490
|
||||||
#define IA32_VMX_VMCS_ENUM 0x48A
|
#define IA32_VMX_VMCS_ENUM 0x48A
|
||||||
|
#define IA32_VMX_PROCBASED_CTLS2 0x48B
|
||||||
#define IA32_VMX_TRUE_PINBASED_CTLS 0x48D
|
#define IA32_VMX_TRUE_PINBASED_CTLS 0x48D
|
||||||
#define IA32_VMX_TRUE_PROCBASED_CTLS 0x48E
|
#define IA32_VMX_TRUE_PROCBASED_CTLS 0x48E
|
||||||
|
#define IA32_VMX_TRUE_EXIT_CTLS 0x48F
|
||||||
|
|
||||||
#define IA32_EFER 0xC0000080
|
#define IA32_EFER 0xC0000080
|
||||||
#define IA32_FS_BASE 0xC0000100
|
#define IA32_FS_BASE 0xC0000100
|
||||||
|
|
|
||||||
|
|
@ -99,10 +99,16 @@ vmread(uint64_t field)
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline uint64_t
|
||||||
vmwrite(uint64_t field, uint64_t value)
|
vmwrite(uint64_t field, uint64_t value)
|
||||||
{
|
{
|
||||||
__asm__ volatile ("vmwrite %0, %1\n\t" :: "rm"(value), "r"(field));
|
uint64_t flags;
|
||||||
|
__asm__ volatile (
|
||||||
|
"vmwrite %1, %2\n\t"
|
||||||
|
"pushf \n\t"
|
||||||
|
"pop %0 \n\t"
|
||||||
|
: "=r"(flags) : "rm"(value), "r"(field));
|
||||||
|
return flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
|
|
|
||||||
128
src/vintel.c
128
src/vintel.c
|
|
@ -94,6 +94,19 @@ vintel_fix_cr_bits(void)
|
||||||
#define CPU_BASED_VM_EXEC_CONTROL 0x4002
|
#define CPU_BASED_VM_EXEC_CONTROL 0x4002
|
||||||
#define VM_ENTRY_MSR_LOAD_COUNT 0x4014
|
#define VM_ENTRY_MSR_LOAD_COUNT 0x4014
|
||||||
#define VM_ENTRY_INTR_INFO_FIELD 0x4016
|
#define VM_ENTRY_INTR_INFO_FIELD 0x4016
|
||||||
|
#define CPU_BASED_VM_EXEC_CONTROL2 0x401E
|
||||||
|
|
||||||
|
static void
|
||||||
|
checked_vmwrite(uint64_t field, uint64_t value)
|
||||||
|
{
|
||||||
|
uint64_t status = vmwrite(field, value);
|
||||||
|
if (status & (1 << 0)) {
|
||||||
|
AsciiPrint("vmwrite(%lx): Invalid VMCS Pointer\n", field);
|
||||||
|
}
|
||||||
|
if (status & (1 << 6)) {
|
||||||
|
AsciiPrint("vmwrite(%lx): %a\n", vmcs_describe_error());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static uint64_t
|
static uint64_t
|
||||||
vmx_adjust_controls(uint64_t value, uint32_t msr)
|
vmx_adjust_controls(uint64_t value, uint32_t msr)
|
||||||
|
|
@ -109,12 +122,19 @@ vmx_init_execution_controls(void)
|
||||||
uint64_t vmxBasic = readmsr64(IA32_VMX_BASIC);
|
uint64_t vmxBasic = readmsr64(IA32_VMX_BASIC);
|
||||||
uint64_t pinBasedMsr = ((vmxBasic >> 55) & 1) ? IA32_VMX_TRUE_PINBASED_CTLS : IA32_VMX_PINBASED_CTLS;
|
uint64_t pinBasedMsr = ((vmxBasic >> 55) & 1) ? IA32_VMX_TRUE_PINBASED_CTLS : IA32_VMX_PINBASED_CTLS;
|
||||||
uint64_t procBasedMsr = ((vmxBasic >> 55) & 1) ? IA32_VMX_TRUE_PROCBASED_CTLS : IA32_VMX_PROCBASED_CTLS;
|
uint64_t procBasedMsr = ((vmxBasic >> 55) & 1) ? IA32_VMX_TRUE_PROCBASED_CTLS : IA32_VMX_PROCBASED_CTLS;
|
||||||
|
uint64_t procBasedMsr2 = IA32_VMX_PROCBASED_CTLS2;
|
||||||
|
|
||||||
uint64_t pinBasedControls = vmx_adjust_controls(0, pinBasedMsr);
|
uint64_t pinBasedControls = vmx_adjust_controls(0, pinBasedMsr);
|
||||||
uint64_t procBasedControls = vmx_adjust_controls(0, procBasedMsr);
|
uint64_t procBasedControls = vmx_adjust_controls(0, procBasedMsr);
|
||||||
|
uint64_t procBasedControls2 = vmx_adjust_controls(0, procBasedMsr2);
|
||||||
|
|
||||||
vmwrite(PIN_BASED_VM_EXEC_CONTROL, pinBasedControls);
|
checked_vmwrite(PIN_BASED_VM_EXEC_CONTROL, pinBasedControls);
|
||||||
vmwrite(CPU_BASED_VM_EXEC_CONTROL, procBasedControls);
|
checked_vmwrite(CPU_BASED_VM_EXEC_CONTROL, procBasedControls);
|
||||||
|
checked_vmwrite(CPU_BASED_VM_EXEC_CONTROL2, procBasedControls2);
|
||||||
|
|
||||||
|
AsciiPrint("PIN_BASED_VM_EXEC_CONTROL: %lx\n", pinBasedControls);
|
||||||
|
AsciiPrint("CPU_BASED_VM_EXEC_CONTROL: %lx\n", procBasedControls);
|
||||||
|
AsciiPrint("CPU_BASED_VM_EXEC_CONTROL2: %lx\n", procBasedControls2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// HACK
|
// HACK
|
||||||
|
|
@ -133,10 +153,10 @@ vintel_write_guest_segment(struct GDTR gdtr, int reg, int ss, uint32_t hibase)
|
||||||
{
|
{
|
||||||
struct segdescr *descr = &gdtr.base[ss >> 3];
|
struct segdescr *descr = &gdtr.base[ss >> 3];
|
||||||
|
|
||||||
vmwrite(GUEST_ES_SELECTOR + 2 * reg, ss & 0xfff8);
|
checked_vmwrite(GUEST_ES_SELECTOR + 2 * reg, ss & 0xfff8);
|
||||||
vmwrite(GUEST_ES_BASE + 2 * reg, getsegbase(descr) | ((uint64_t)hibase << 32));
|
checked_vmwrite(GUEST_ES_BASE + 2 * reg, getsegbase(descr) | ((uint64_t)hibase << 32));
|
||||||
vmwrite(GUEST_ES_LIMIT + 2 * reg, getseglimit(descr));
|
checked_vmwrite(GUEST_ES_LIMIT + 2 * reg, getseglimit(descr));
|
||||||
vmwrite(GUEST_ES_ACCESS + 2 * reg, getsegaccess(descr, false));
|
checked_vmwrite(GUEST_ES_ACCESS + 2 * reg, getsegaccess(descr, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
@ -162,33 +182,33 @@ vintel_init_guest(void)
|
||||||
* Then later reload the GDT to make the shadow registers consistent again.
|
* Then later reload the GDT to make the shadow registers consistent again.
|
||||||
* Sigh.
|
* Sigh.
|
||||||
*/
|
*/
|
||||||
vmwrite(GUEST_ES_SELECTOR + 2 * 7, readtr() & 0xfff8);
|
checked_vmwrite(GUEST_ES_SELECTOR + 2 * 7, readtr() & 0xfff8);
|
||||||
vmwrite(GUEST_ES_BASE + 2 * 7, (uintptr_t)myprocvisor()->host_tss); // just abuse the host's TSS for this
|
checked_vmwrite(GUEST_ES_BASE + 2 * 7, (uintptr_t)myprocvisor()->host_tss); // just abuse the host's TSS for this
|
||||||
vmwrite(GUEST_ES_LIMIT + 2 * 7, sizeof (struct TSS) - 1);
|
checked_vmwrite(GUEST_ES_LIMIT + 2 * 7, sizeof (struct TSS) - 1);
|
||||||
vmwrite(GUEST_ES_ACCESS + 2 * 7, 0x00000089);
|
checked_vmwrite(GUEST_ES_ACCESS + 2 * 7, 0x00000089);
|
||||||
|
|
||||||
// Set control registers
|
// Set control registers
|
||||||
vmwrite(GUEST_CR0, readcr0());
|
checked_vmwrite(GUEST_CR0, readcr0());
|
||||||
vmwrite(GUEST_CR3, readcr3());
|
checked_vmwrite(GUEST_CR3, readcr3());
|
||||||
vmwrite(GUEST_CR4, readcr4());
|
checked_vmwrite(GUEST_CR4, readcr4());
|
||||||
|
|
||||||
vmwrite(GUEST_DR7, readdr7());
|
checked_vmwrite(GUEST_DR7, readdr7());
|
||||||
vmwrite(GUEST_RFLAGS, readflags());
|
checked_vmwrite(GUEST_RFLAGS, readflags());
|
||||||
vmwrite(GUEST_RSP, guestSP);
|
checked_vmwrite(GUEST_RSP, guestSP);
|
||||||
vmwrite(GUEST_RIP, guestIP);
|
checked_vmwrite(GUEST_RIP, guestIP);
|
||||||
vmwrite(VMCS_LINK_POINTER, -1LL);
|
checked_vmwrite(VMCS_LINK_POINTER, -1LL);
|
||||||
vmwrite(GUEST_IA32_DEBUGCTL, readmsr64(IA32_DEBUGCTL));
|
checked_vmwrite(GUEST_IA32_DEBUGCTL, readmsr64(IA32_DEBUGCTL));
|
||||||
vmwrite(GUEST_IA32_PAT, readmsr64(IA32_PAT));
|
checked_vmwrite(GUEST_IA32_PAT, readmsr64(IA32_PAT));
|
||||||
vmwrite(GUEST_IA32_EFER, readmsr64(IA32_EFER));
|
checked_vmwrite(GUEST_IA32_EFER, readmsr64(IA32_EFER));
|
||||||
vmwrite(GUEST_FS_BASE, readmsr64(IA32_FS_BASE));
|
checked_vmwrite(GUEST_FS_BASE, readmsr64(IA32_FS_BASE));
|
||||||
vmwrite(GUEST_GS_BASE, readmsr64(IA32_GS_BASE));
|
checked_vmwrite(GUEST_GS_BASE, readmsr64(IA32_GS_BASE));
|
||||||
vmwrite(GUEST_SYSENTER_CS, readmsr64(0x174));
|
checked_vmwrite(GUEST_SYSENTER_CS, readmsr64(0x174));
|
||||||
vmwrite(GUEST_SYSENTER_ESP, readmsr64(0x175));
|
checked_vmwrite(GUEST_SYSENTER_ESP, readmsr64(0x175));
|
||||||
vmwrite(GUEST_SYSENTER_EIP, readmsr64(0x176));
|
checked_vmwrite(GUEST_SYSENTER_EIP, readmsr64(0x176));
|
||||||
|
|
||||||
// Set GDT and IDT
|
// Set GDT and IDT
|
||||||
vmwrite(GUEST_GDTR_BASE, (uintptr_t)gdtr.base);
|
checked_vmwrite(GUEST_GDTR_BASE, (uintptr_t)gdtr.base);
|
||||||
vmwrite(GUEST_IDTR_BASE, (uintptr_t)idtr.base);
|
checked_vmwrite(GUEST_IDTR_BASE, (uintptr_t)idtr.base);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define HOST_ES_SELECTOR 0xC00
|
#define HOST_ES_SELECTOR 0xC00
|
||||||
|
|
@ -220,6 +240,11 @@ vintel_init_guest(void)
|
||||||
#define HOST_GDTR_BASE 0x6C0C
|
#define HOST_GDTR_BASE 0x6C0C
|
||||||
#define HOST_IDTR_BASE 0x6C0E
|
#define HOST_IDTR_BASE 0x6C0E
|
||||||
|
|
||||||
|
#define CR3_TARGET_COUNT 0x400A
|
||||||
|
#define VM_EXIT_CONTROLS 0x400C
|
||||||
|
|
||||||
|
#define EXCEPTION_BITMAP 0x4004
|
||||||
|
|
||||||
static void
|
static void
|
||||||
vintel_init_host(void)
|
vintel_init_host(void)
|
||||||
{
|
{
|
||||||
|
|
@ -229,30 +254,30 @@ vintel_init_host(void)
|
||||||
uint64_t hostIP = 0x0;
|
uint64_t hostIP = 0x0;
|
||||||
|
|
||||||
// Set segment selectors
|
// Set segment selectors
|
||||||
vmwrite(HOST_ES_SELECTOR, 0x10);
|
checked_vmwrite(HOST_ES_SELECTOR, 0x10);
|
||||||
vmwrite(HOST_CS_SELECTOR, 0x08);
|
checked_vmwrite(HOST_CS_SELECTOR, 0x08);
|
||||||
vmwrite(HOST_SS_SELECTOR, 0x10);
|
checked_vmwrite(HOST_SS_SELECTOR, 0x10);
|
||||||
vmwrite(HOST_DS_SELECTOR, 0x10);
|
checked_vmwrite(HOST_DS_SELECTOR, 0x10);
|
||||||
vmwrite(HOST_FS_SELECTOR, 0x00);
|
checked_vmwrite(HOST_FS_SELECTOR, 0x00);
|
||||||
vmwrite(HOST_GS_SELECTOR, 0x00);
|
checked_vmwrite(HOST_GS_SELECTOR, 0x00);
|
||||||
vmwrite(HOST_TR_SELECTOR, 0x18);
|
checked_vmwrite(HOST_TR_SELECTOR, 0x18);
|
||||||
|
|
||||||
// Set control registers
|
// Set control registers
|
||||||
vmwrite(HOST_CR0, readcr0());
|
checked_vmwrite(HOST_CR0, readcr0());
|
||||||
vmwrite(HOST_CR3, readcr3());
|
checked_vmwrite(HOST_CR3, readcr3());
|
||||||
vmwrite(HOST_CR4, readcr4());
|
checked_vmwrite(HOST_CR4, readcr4());
|
||||||
|
|
||||||
// Set RSP and RIP
|
// Set RSP and RIP
|
||||||
vmwrite(HOST_RSP, hostSP);
|
checked_vmwrite(HOST_RSP, hostSP);
|
||||||
vmwrite(HOST_RIP, hostIP);
|
checked_vmwrite(HOST_RIP, hostIP);
|
||||||
|
|
||||||
// Set MSRs
|
// Set MSRs
|
||||||
vmwrite(HOST_IA32_PAT, readmsr64(IA32_PAT));
|
checked_vmwrite(HOST_IA32_PAT, readmsr64(IA32_PAT));
|
||||||
vmwrite(HOST_IA32_EFER, readmsr64(IA32_EFER));
|
checked_vmwrite(HOST_IA32_EFER, readmsr64(IA32_EFER));
|
||||||
|
|
||||||
// Set GDT and IDT
|
// Set GDT and IDT
|
||||||
vmwrite(HOST_GDTR_BASE, (uintptr_t)pv->host_gdtr.base);
|
checked_vmwrite(HOST_GDTR_BASE, (uintptr_t)pv->host_gdtr.base);
|
||||||
vmwrite(HOST_IDTR_BASE, (uintptr_t)pv->host_idtr.base);
|
checked_vmwrite(HOST_IDTR_BASE, (uintptr_t)pv->host_idtr.base);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -309,10 +334,19 @@ vintel_enable(void)
|
||||||
uint64_t vmxBasic = readmsr64(IA32_VMX_BASIC);
|
uint64_t vmxBasic = readmsr64(IA32_VMX_BASIC);
|
||||||
uint32_t msr = ((vmxBasic >> 55) & 1) ? IA32_VMX_TRUE_ENTRY_CTLS : IA32_VMX_ENTRY_CTLS;
|
uint32_t msr = ((vmxBasic >> 55) & 1) ? IA32_VMX_TRUE_ENTRY_CTLS : IA32_VMX_ENTRY_CTLS;
|
||||||
uint64_t entryControls = vmx_adjust_controls(0x200, msr); // 0x200 enables IA-32e mode
|
uint64_t entryControls = vmx_adjust_controls(0x200, msr); // 0x200 enables IA-32e mode
|
||||||
vmwrite(VM_ENTRY_CONTROLS, entryControls);
|
checked_vmwrite(VM_ENTRY_CONTROLS, entryControls);
|
||||||
|
AsciiPrint("VM_ENTRY_CONTROLS: %lx\n", entryControls);
|
||||||
|
|
||||||
vmwrite(VM_ENTRY_MSR_LOAD_COUNT, 0);
|
uint32_t exitMsr = ((vmxBasic >> 55) & 1) ? IA32_VMX_TRUE_EXIT_CTLS : IA32_VMX_EXIT_CTLS;
|
||||||
vmwrite(VM_ENTRY_INTR_INFO_FIELD, 0);
|
uint64_t exitControls = vmx_adjust_controls(0x0, exitMsr);
|
||||||
|
checked_vmwrite(VM_EXIT_CONTROLS, exitControls);
|
||||||
|
AsciiPrint("VM_EXIT_CONTROLS: %lx\n", exitControls);
|
||||||
|
|
||||||
|
checked_vmwrite(VM_ENTRY_MSR_LOAD_COUNT, 0);
|
||||||
|
checked_vmwrite(VM_ENTRY_INTR_INFO_FIELD, 0);
|
||||||
|
checked_vmwrite(CR3_TARGET_COUNT, 0);
|
||||||
|
|
||||||
|
checked_vmwrite(EXCEPTION_BITMAP, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
status = vmlaunch();
|
status = vmlaunch();
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue