Printing extended VMX errors
This commit is contained in:
parent
f374da687b
commit
3704e95c64
2 changed files with 67 additions and 6 deletions
|
|
@ -3,6 +3,8 @@
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define VMCS_INSTRUCTION_ERROR 0x4400
|
||||||
|
|
||||||
struct VMXON {
|
struct VMXON {
|
||||||
uint32_t revisionID;
|
uint32_t revisionID;
|
||||||
uint32_t abortIndicator;
|
uint32_t abortIndicator;
|
||||||
|
|
@ -70,10 +72,16 @@ vmclear(void *region)
|
||||||
return flags;
|
return flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline uint64_t
|
||||||
vmlaunch(void)
|
vmlaunch(void)
|
||||||
{
|
{
|
||||||
__asm__ volatile ("vmlaunch\n\t" ::);
|
uint64_t flags;
|
||||||
|
__asm__ volatile (
|
||||||
|
"vmlaunch \n\t"
|
||||||
|
"pushf \n\t"
|
||||||
|
"pop %0\n\t"
|
||||||
|
: "=r"(flags));
|
||||||
|
return flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
|
|
@ -82,16 +90,18 @@ vmresume(void)
|
||||||
__asm__ volatile ("vmresume\n\t" ::);
|
__asm__ volatile ("vmresume\n\t" ::);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline uint64_t
|
||||||
vmread()
|
vmread(uint64_t field)
|
||||||
{
|
{
|
||||||
__asm__ volatile ("vmread\n\t" ::);
|
uint64_t value;
|
||||||
|
__asm__ volatile ("vmread %0, %1\n\t" : "=rm"(value) : "r"(field));
|
||||||
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
vmwrite(uint64_t field, uint64_t value)
|
vmwrite(uint64_t field, uint64_t value)
|
||||||
{
|
{
|
||||||
__asm__ volatile ("vmwrite %1, %0\n\t" :: "r"(field), "rm"(value));
|
__asm__ volatile ("vmwrite %0, %1\n\t" :: "rm"(value), "r"(field));
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
|
|
@ -100,4 +110,46 @@ vmcall()
|
||||||
__asm__ volatile ("vmcall\n\t" ::);
|
__asm__ volatile ("vmcall\n\t" ::);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline const char *
|
||||||
|
vmx_describe_error(uint32_t error)
|
||||||
|
{
|
||||||
|
switch (error) {
|
||||||
|
default: return "Unknown VMX Error";
|
||||||
|
case 0: return NULL;
|
||||||
|
|
||||||
|
case 1: return "VMCALL executed in VMX root operation";
|
||||||
|
case 2: return "VMCLEAR with invalid physical address";
|
||||||
|
case 3: return "VMCLEAR with VMXON pointer";
|
||||||
|
case 4: return "VMLAUNCH with non-clear VMCS";
|
||||||
|
case 5: return "VMRESUME with non-launched VMCS";
|
||||||
|
case 6: return "VMRESUME after VMXOFF (VMXOFF and VMXON between VMLAUNCH and VMRESUME)";
|
||||||
|
case 7: return "VM entry with invalid control field(s)";
|
||||||
|
case 8: return "VM entry with invalid host-state field(s)";
|
||||||
|
case 9: return "VMPTRLD with invalid physical address";
|
||||||
|
case 10: return "VMPTRLD with VMXON pointer";
|
||||||
|
case 11: return "VMPTRLD with incorrect VMCS revision identifier";
|
||||||
|
case 12: return "VMREAD/VMWRITE from/to unsupported VMCS component";
|
||||||
|
case 13: return "VMWRITE to read-only VMCS component";
|
||||||
|
case 15: return "VMXON executed in VMX root operation";
|
||||||
|
case 16: return "VM entry with invalid executive-VMCS pointer";
|
||||||
|
case 17: return "VM entry with non-launched executive VMCS";
|
||||||
|
case 18: return "VM entry with executive-VMCS pointer not VMXON pointer (when attempting to deactivate the dual-monitor treatment of SMIs and SMM)";
|
||||||
|
case 19: return "VMCALL with non-clear VMCS (when attempting to activate the dual-monitor treatment of SMIs and SMM)";
|
||||||
|
case 20: return "VMCALL with invalid VM-exit control fields";
|
||||||
|
case 22: return "VMCALL with incorrect MSEG revision identifier (when attempting to activate the dual-monitor treatment of SMIs and SMM)";
|
||||||
|
case 23: return "VMXOFF under dual-monitor treatment of SMIs and SMM";
|
||||||
|
case 24: return "VMCALL with invalid SMM-monitor features (when attempting to activate the dual-monitor treatment of SMIs and SMM)";
|
||||||
|
case 25: return "VM entry with invalid VM-execution control fields in executive VMCS (when attempting to return from SMM)";
|
||||||
|
case 26: return "VM entry with events blocked by MOV SS";
|
||||||
|
case 28: return "Invalid operand to INVEPT/INVVPID";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline const char *
|
||||||
|
vmcs_describe_error(void)
|
||||||
|
{
|
||||||
|
uint32_t error = vmread(VMCS_INSTRUCTION_ERROR) & 0xffffffff;
|
||||||
|
return vmx_describe_error(error);
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -225,6 +225,15 @@ vintel_enable(void)
|
||||||
|
|
||||||
vintel_init_guest();
|
vintel_init_guest();
|
||||||
vintel_init_host();
|
vintel_init_host();
|
||||||
|
|
||||||
|
status = vmlaunch();
|
||||||
|
Print(L"VMLAUNCH Status: %p\n", (void *)status);
|
||||||
|
if (status & (1 << 0)) {
|
||||||
|
Print(L"Invalid VMCS Pointer\n");
|
||||||
|
}
|
||||||
|
if (status & (1 << 6)) {
|
||||||
|
AsciiPrint("%a\n", vmcs_describe_error());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct virt_vtable virt_vtable_intel = {
|
struct virt_vtable virt_vtable_intel = {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue