From 14fa1df99dd6a916d1567e711555a998cdff3222 Mon Sep 17 00:00:00 2001 From: Thomas Oltmann Date: Sat, 15 Mar 2025 15:05:51 +0100 Subject: [PATCH] Implemented a troubleshooting REPL to find out whats wrong with VMX --- src/efi.c | 123 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 122 insertions(+), 1 deletion(-) diff --git a/src/efi.c b/src/efi.c index b14c057..5a968d3 100644 --- a/src/efi.c +++ b/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; }