Implemented a troubleshooting REPL to find out whats wrong with VMX

This commit is contained in:
Thomas Oltmann 2025-03-15 15:05:51 +01:00
parent c226f85b5f
commit 14fa1df99d

123
src/efi.c
View file

@ -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;
}