Implemented a troubleshooting REPL to find out whats wrong with VMX
This commit is contained in:
parent
c226f85b5f
commit
14fa1df99d
1 changed files with 122 additions and 1 deletions
123
src/efi.c
123
src/efi.c
|
|
@ -7,6 +7,9 @@
|
|||
#include "bootstrap.h"
|
||||
#include "procvisor.h"
|
||||
|
||||
#include "x86/msr.h"
|
||||
#include "x86/vmx.h"
|
||||
|
||||
struct virt_vtable *virt = &virt_vtable_intel;
|
||||
|
||||
static char virt_err[100];
|
||||
|
|
@ -20,6 +23,123 @@ bs_alloc(size_t size)
|
|||
return ptr;
|
||||
}
|
||||
|
||||
/* Troubleshooting REPL */
|
||||
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 CHAR16 ts_cmd[200];
|
||||
|
||||
static void
|
||||
ts_skipws(CHAR16 **ptr)
|
||||
{
|
||||
CHAR16 *cur = *ptr;
|
||||
while (*cur == ' ' || *cur == '\t') cur++;
|
||||
*ptr = cur;
|
||||
}
|
||||
|
||||
static inline int
|
||||
hexvalue(int chr)
|
||||
{
|
||||
if (chr >= '0' && chr <= '9') return chr - '0';
|
||||
if (chr >= 'A' && chr <= 'Z') return chr - 'A' + 10;
|
||||
if (chr >= 'a' && chr <= 'z') return chr - 'a' + 10;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static bool
|
||||
ts_parsehex(CHAR16 **ptr, uint64_t *value)
|
||||
{
|
||||
*value = 0;
|
||||
|
||||
CHAR16 *cur = *ptr;
|
||||
if (hexvalue(*cur) < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int ndigits = 0;
|
||||
while (hexvalue(*cur) >= 0) {
|
||||
if (ndigits >= 16) {
|
||||
return false;
|
||||
}
|
||||
*value <<= 4;
|
||||
*value |= hexvalue(*cur);
|
||||
ndigits++;
|
||||
cur++;
|
||||
}
|
||||
|
||||
*ptr = cur;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
ts_repl(void)
|
||||
{
|
||||
for (;;) {
|
||||
Input(L"> ", ts_cmd, sizeof ts_cmd);
|
||||
Print(L"\n");
|
||||
|
||||
uint64_t index, value, status;
|
||||
|
||||
CHAR16 *cur = ts_cmd;
|
||||
ts_skipws(&cur);
|
||||
switch (*cur++) {
|
||||
|
||||
case 0:
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
ts_skipws(&cur);
|
||||
if (!ts_parsehex(&cur, &index)) goto huh;
|
||||
if (*cur) {
|
||||
if (!ts_parsehex(&cur, &value)) goto huh;
|
||||
writemsr64(index, value);
|
||||
} else {
|
||||
value = readmsr64(index);
|
||||
}
|
||||
if (*cur) goto huh;
|
||||
AsciiPrint("MSR %lx = %lx\n", index, value);
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
ts_skipws(&cur);
|
||||
if (!ts_parsehex(&cur, &index)) goto huh;
|
||||
if (*cur) {
|
||||
if (!ts_parsehex(&cur, &value)) goto huh;
|
||||
checked_vmwrite(index, value);
|
||||
} else {
|
||||
value = vmread(index);
|
||||
}
|
||||
if (*cur) goto huh;
|
||||
AsciiPrint("VMCS FIELD %lx = %lx\n", index, value);
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
AsciiPrint("VMLAUNCH\n");
|
||||
status = vmlaunch();
|
||||
if (status & (1 << 0)) {
|
||||
Print(L"Invalid VMCS Pointer\n");
|
||||
}
|
||||
if (status & (1 << 6)) {
|
||||
AsciiPrint("%a\n", vmcs_describe_error());
|
||||
}
|
||||
break;
|
||||
|
||||
huh: default:
|
||||
AsciiPrint("?\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EFIAPI
|
||||
EFI_STATUS
|
||||
efi_main(EFI_HANDLE imageHandle, EFI_SYSTEM_TABLE *systemTable)
|
||||
|
|
@ -43,7 +163,8 @@ efi_main(EFI_HANDLE imageHandle, EFI_SYSTEM_TABLE *systemTable)
|
|||
AsciiPrint("* VT-x enabled!\n");
|
||||
}
|
||||
|
||||
for (;;) {}
|
||||
//for (;;) {}
|
||||
ts_repl();
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue