diff --git a/exit_handler.cpp b/exit_handler.cpp index fbb7f5d..db2eb4b 100644 --- a/exit_handler.cpp +++ b/exit_handler.cpp @@ -68,7 +68,9 @@ auto exit_handler(hv::pguest_registers regs) -> void interrupt.flags = interruption_type::hardware_exception; interrupt.vector = EXCEPTION_GP_FAULT; interrupt.valid = true; + __vmx_vmwrite(VMCS_CTRL_VMENTRY_INTERRUPTION_INFORMATION_FIELD, interrupt.flags); + __vmx_vmwrite(VMCS_VMEXIT_INTERRUPTION_ERROR_CODE, g_vcpu->error_code); } return; // dont advance rip... } @@ -95,7 +97,9 @@ auto exit_handler(hv::pguest_registers regs) -> void interrupt.flags = interruption_type::hardware_exception; interrupt.vector = EXCEPTION_GP_FAULT; interrupt.valid = true; + __vmx_vmwrite(VMCS_CTRL_VMENTRY_INTERRUPTION_INFORMATION_FIELD, interrupt.flags); + __vmx_vmwrite(VMCS_VMEXIT_INTERRUPTION_ERROR_CODE, g_vcpu->error_code); } return; // dont advance rip... } @@ -122,7 +126,9 @@ auto exit_handler(hv::pguest_registers regs) -> void interrupt.flags = interruption_type::hardware_exception; interrupt.vector = EXCEPTION_GP_FAULT; interrupt.valid = true; + __vmx_vmwrite(VMCS_CTRL_VMENTRY_INTERRUPTION_INFORMATION_FIELD, interrupt.flags); + __vmx_vmwrite(VMCS_VMEXIT_INTERRUPTION_ERROR_CODE, g_vcpu->error_code); } return; // dont advance rip... } @@ -210,7 +216,10 @@ auto exit_handler(hv::pguest_registers regs) -> void interrupt.flags = interruption_type::hardware_exception; interrupt.vector = EXCEPTION_INVALID_OPCODE; interrupt.valid = true; + __vmx_vmwrite(VMCS_CTRL_VMENTRY_INTERRUPTION_INFORMATION_FIELD, interrupt.flags); + __vmx_vmwrite(VMCS_VMEXIT_INTERRUPTION_ERROR_CODE, NULL); + return; // dont advance rip... } break; } @@ -226,7 +235,10 @@ auto exit_handler(hv::pguest_registers regs) -> void interrupt.flags = interruption_type::hardware_exception; interrupt.vector = EXCEPTION_INVALID_OPCODE; interrupt.valid = true; + __vmx_vmwrite(VMCS_CTRL_VMENTRY_INTERRUPTION_INFORMATION_FIELD, interrupt.flags); + // manual says there will never be an error code... so just put null... + __vmx_vmwrite(VMCS_VMEXIT_INTERRUPTION_ERROR_CODE, NULL); return; // dont advance rip... } default: diff --git a/hv_types.hpp b/hv_types.hpp index 145f03e..44783ca 100644 --- a/hv_types.hpp +++ b/hv_types.hpp @@ -657,7 +657,7 @@ namespace hv u64 vmcs_phys; u64 vmxon_phys; u64 host_stack; - + u64 error_code; tss64 tss; segment_descriptor_64* gdt; } vcpu_ctx, * pvcpu_ctx; diff --git a/idt.cpp b/idt.cpp index 3a90c56..753a0fa 100644 --- a/idt.cpp +++ b/idt.cpp @@ -2,6 +2,7 @@ auto seh_handler(hv::pidt_regs_t regs) -> void { + g_vcpu->error_code = regs->error_code; const auto rva = regs->rip - reinterpret_cast(idt::image_base); const auto nt_headers = reinterpret_cast( reinterpret_cast(idt::image_base) + diff --git a/idt.hpp b/idt.hpp index 8b60ac1..c296567 100644 --- a/idt.hpp +++ b/idt.hpp @@ -2,6 +2,7 @@ #include "hv_types.hpp" #include "segment_intrin.h" #include "debug.hpp" +#include "vmxon.hpp" #pragma section(".idt", read, write) extern "C" void __gp_handler(void); diff --git a/vmcs.cpp b/vmcs.cpp index 6bc8697..cce725f 100644 --- a/vmcs.cpp +++ b/vmcs.cpp @@ -33,7 +33,7 @@ namespace vmcs fs.request_privilege_level = NULL; fs.table = NULL; __vmx_vmwrite(VMCS_HOST_FS_SELECTOR, fs.flags); - __vmx_vmwrite(VMCS_HOST_GS_BASE, __readmsr(IA32_FS_BASE)); + __vmx_vmwrite(VMCS_HOST_FS_BASE, __readmsr(IA32_FS_BASE)); segment_selector gs{ readgs() }; gs.request_privilege_level = NULL; diff --git a/vmxexit_handler.h b/vmxexit_handler.h index 1cae8af..7dc8978 100644 --- a/vmxexit_handler.h +++ b/vmxexit_handler.h @@ -3,6 +3,7 @@ #include "debug.hpp" #include "invd.hpp" #include "mm.hpp" +#include "vmxon.hpp" enum class vmcall_option { diff --git a/vmxon.hpp b/vmxon.hpp index 7eff8e1..5304a40 100644 --- a/vmxon.hpp +++ b/vmxon.hpp @@ -1,6 +1,19 @@ #pragma once #include "hv_types.hpp" +inline auto get_cpu_num() -> u32 +{ + cpuid_eax_01 cpuid_value; + __cpuid((int*)&cpuid_value, 1); + + return cpuid_value + .cpuid_additional_information + .initial_apic_id; +} + +#define g_vcpu \ + vmxon::g_vmx_ctx->vcpus[get_cpu_num()] + namespace vmxon { auto create_vmxon_region(hv::pvcpu_ctx vcpu_ctx) -> void;