diff --git a/bluepill.sln b/bluepill.sln
index 8823095..c023079 100644
--- a/bluepill.sln
+++ b/bluepill.sln
@@ -5,18 +5,30 @@ VisualStudioVersion = 16.0.30621.155
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bluepill", "bluepill.vcxproj", "{881CCCA6-80EB-486F-8923-4F4B7DD41F9A}"
EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "demo", "demo\demo.vcxproj", "{A3D028D7-1650-4036-9FB0-4B8CC16268FE}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
Release|x64 = Release|x64
+ Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{881CCCA6-80EB-486F-8923-4F4B7DD41F9A}.Debug|x64.ActiveCfg = Debug|x64
{881CCCA6-80EB-486F-8923-4F4B7DD41F9A}.Debug|x64.Build.0 = Debug|x64
{881CCCA6-80EB-486F-8923-4F4B7DD41F9A}.Debug|x64.Deploy.0 = Debug|x64
+ {881CCCA6-80EB-486F-8923-4F4B7DD41F9A}.Debug|x86.ActiveCfg = Debug|x64
{881CCCA6-80EB-486F-8923-4F4B7DD41F9A}.Release|x64.ActiveCfg = Release|x64
{881CCCA6-80EB-486F-8923-4F4B7DD41F9A}.Release|x64.Build.0 = Release|x64
{881CCCA6-80EB-486F-8923-4F4B7DD41F9A}.Release|x64.Deploy.0 = Release|x64
+ {881CCCA6-80EB-486F-8923-4F4B7DD41F9A}.Release|x86.ActiveCfg = Release|x64
+ {A3D028D7-1650-4036-9FB0-4B8CC16268FE}.Debug|x64.ActiveCfg = Debug|x64
+ {A3D028D7-1650-4036-9FB0-4B8CC16268FE}.Debug|x64.Build.0 = Debug|x64
+ {A3D028D7-1650-4036-9FB0-4B8CC16268FE}.Debug|x86.ActiveCfg = Debug|x64
+ {A3D028D7-1650-4036-9FB0-4B8CC16268FE}.Release|x64.ActiveCfg = Release|x64
+ {A3D028D7-1650-4036-9FB0-4B8CC16268FE}.Release|x64.Build.0 = Release|x64
+ {A3D028D7-1650-4036-9FB0-4B8CC16268FE}.Release|x86.ActiveCfg = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/bluepill.vcxproj b/bluepill.vcxproj
index 94f6559..e716e20 100644
--- a/bluepill.vcxproj
+++ b/bluepill.vcxproj
@@ -85,6 +85,7 @@
+
@@ -92,6 +93,7 @@
+
diff --git a/bluepill.vcxproj.filters b/bluepill.vcxproj.filters
index 85c041b..cab2d58 100644
--- a/bluepill.vcxproj.filters
+++ b/bluepill.vcxproj.filters
@@ -29,6 +29,9 @@
Source Files
+
+ Source Files
+
@@ -52,6 +55,9 @@
Header Files
+
+ Header Files
+
diff --git a/demo/demo.vcxproj b/demo/demo.vcxproj
new file mode 100644
index 0000000..452255e
--- /dev/null
+++ b/demo/demo.vcxproj
@@ -0,0 +1,96 @@
+
+
+
+
+ Debug
+ x64
+
+
+ Release
+ x64
+
+
+
+ 16.0
+ Win32Proj
+ {a3d028d7-1650-4036-9fb0-4b8cc16268fe}
+ demo
+ 10.0
+
+
+
+ Application
+ true
+ v142
+ Unicode
+
+
+ Application
+ false
+ v142
+ true
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+
+
+ false
+
+
+
+ Level3
+ true
+ _DEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+
+
+ Console
+ true
+
+
+
+
+ Level3
+ true
+ true
+ true
+ NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+
+
+ Console
+ true
+ true
+ true
+
+
+
+
+
+
+
+ Document
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/demo/demo.vcxproj.filters b/demo/demo.vcxproj.filters
new file mode 100644
index 0000000..a921897
--- /dev/null
+++ b/demo/demo.vcxproj.filters
@@ -0,0 +1,28 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd
+
+
+
+
+ Source Files
+
+
+
+
+ Source Files
+
+
+
+
+ Header Files
+
+
+
\ No newline at end of file
diff --git a/demo/demo.vcxproj.user b/demo/demo.vcxproj.user
new file mode 100644
index 0000000..88a5509
--- /dev/null
+++ b/demo/demo.vcxproj.user
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/demo/hypercall.asm b/demo/hypercall.asm
new file mode 100644
index 0000000..8d1bb96
--- /dev/null
+++ b/demo/hypercall.asm
@@ -0,0 +1,6 @@
+.code
+hypercall proc
+ cpuid
+ ret
+hypercall endp
+end
\ No newline at end of file
diff --git a/demo/hypercall.h b/demo/hypercall.h
new file mode 100644
index 0000000..ce3a6f7
--- /dev/null
+++ b/demo/hypercall.h
@@ -0,0 +1,20 @@
+#pragma once
+#include
+#include
+
+using u8 = unsigned char;
+using u16 = unsigned short;
+using u32 = unsigned int;
+using u64 = unsigned long long;
+using u128 = __m128;
+
+using s8 = char;
+using s16 = short;
+using s32 = int;
+using s64 = long long;
+
+namespace bluepill
+{
+ constexpr auto key = 0xC0FFEE;
+ extern "C" u64 hypercall(u64 key);
+}
\ No newline at end of file
diff --git a/demo/main.cpp b/demo/main.cpp
new file mode 100644
index 0000000..44eb2c7
--- /dev/null
+++ b/demo/main.cpp
@@ -0,0 +1,8 @@
+#include
+#include "hypercall.h"
+
+int main()
+{
+ std::printf("hypercall result: 0x%x\n", bluepill::hypercall(bluepill::key));
+ std::getchar();
+}
\ No newline at end of file
diff --git a/entry.cpp b/entry.cpp
index 564ad15..e9dd4e9 100644
--- a/entry.cpp
+++ b/entry.cpp
@@ -4,34 +4,8 @@ auto driver_unload(
PDRIVER_OBJECT driver_object
) -> void
{
- // TODO vmcall and ask HV to vmxoff...
- KeIpiGenericCall(
- [](ULONG_PTR) -> ULONG_PTR
- {
- __vmx_off();
- hv::cr4_t cr4 = { __readcr4() };
- cr4.vmx_enable = false;
- __writecr4(cr4.flags);
-
- hv::ia32_feature_control_msr_t feature_msr = { __readmsr(IA32_FEATURE_CONTROL) };
- feature_msr.bits.vmxon_outside_smx = false;
- feature_msr.bits.lock = false;
- __writemsr(IA32_FEATURE_CONTROL, feature_msr.control);
- return NULL;
- }, NULL
- );
-
- for (auto idx = 0u; idx < vmxon::g_vmx_ctx->vcpu_num; ++idx)
- {
- MmFreeContiguousMemory(vmxon::g_vmx_ctx->vcpus[idx]->vmcs);
- MmFreeContiguousMemory(vmxon::g_vmx_ctx->vcpus[idx]->vmxon);
-
- ExFreePool((void*)vmxon::g_vmx_ctx->vcpus[idx]->host_stack);
- ExFreePool(vmxon::g_vmx_ctx->vcpus[idx]);
- }
-
- ExFreePool(vmxon::g_vmx_ctx->vcpus);
- ExFreePool(vmxon::g_vmx_ctx);
+ // test to see if invalid opcode happens...
+ __vmx_off();
}
auto driver_entry(
diff --git a/exit_handler.cpp b/exit_handler.cpp
index 18408ae..cceca94 100644
--- a/exit_handler.cpp
+++ b/exit_handler.cpp
@@ -4,23 +4,135 @@ auto exit_handler(hv::pguest_registers regs) -> void
{
u64 exit_reason;
__vmx_vmread(VMCS_EXIT_REASON, &exit_reason);
- __debugbreak();
switch (exit_reason)
{
case VMX_EXIT_REASON_EXECUTE_CPUID:
- case VMX_EXIT_REASON_EXECUTE_INVLPG:
+ {
+ if (regs->rcx == 0xC0FFEE)
+ {
+ regs->rax = 0xC0FFEE;
+ // just a demo...
+ }
+ else
+ {
+ int result[4];
+ __cpuid(result, regs->rax);
+ regs->rax = result[0];
+ regs->rbx = result[1];
+ regs->rcx = result[2];
+ regs->rdx = result[3];
+ }
+ break;
+ }
case VMX_EXIT_REASON_EXECUTE_XSETBV:
- case VMX_EXIT_REASON_EXECUTE_HLT:
- case VMX_EXIT_REASON_EXECUTE_VMCALL:
- case VMX_EXIT_REASON_EXECUTE_VMREAD:
+ {
+ hv::msr_split value;
+ value.high = regs->rdx;
+ value.low = regs->rax;
+
+ __try
+ {
+ /*
+ EXCEPTION WARNING!: (will need to handle SEH in my IDT)
+ #GP If the current privilege level is not 0.
+ If an invalid XCR is specified in ECX.
+ If the value in EDX:EAX sets bits that are reserved in the XCR specified by ECX.
+ If an attempt is made to clear bit 0 of XCR0.
+ If an attempt is made to set XCR0[2:1] to 10b.
+
+ #UD If CPUID.01H:ECX.XSAVE[bit 26] = 0.
+ If CR4.OSXSAVE[bit 18] = 0.
+ If the LOCK prefix is used.
+ */
+ _xsetbv(regs->rcx, value.value);
+ }
+ __except (EXCEPTION_EXECUTE_HANDLER)
+ {
+ vmentry_interrupt_information interrupt{};
+ interrupt.flags = interruption_type::software_interrupt;
+ interrupt.vector = EXCEPTION_GP_FAULT;
+ interrupt.valid = true;
+ __vmx_vmwrite(VMCS_CTRL_VMENTRY_INTERRUPTION_INFORMATION_FIELD, interrupt.flags);
+ }
+ break;
+ }
+ case VMX_EXIT_REASON_EXECUTE_RDMSR:
+ {
+ __try
+ {
+ /*
+ EXCEPTION WARNING!: (will need to handle SEH in my IDT)
+ #GP(0) If the current privilege level is not 0.
+ If the value in ECX specifies a reserved or unimplemented MSR address.
+ #UD If the LOCK prefix is used.
+ */
+ const auto result =
+ hv::msr_split{ __readmsr(regs->rcx) };
+
+ regs->rdx = result.high;
+ regs->rax = result.low;
+ }
+ __except (EXCEPTION_EXECUTE_HANDLER)
+ {
+ vmentry_interrupt_information interrupt{};
+ interrupt.flags = interruption_type::software_interrupt;
+ interrupt.vector = EXCEPTION_GP_FAULT;
+ interrupt.valid = true;
+ __vmx_vmwrite(VMCS_CTRL_VMENTRY_INTERRUPTION_INFORMATION_FIELD, interrupt.flags);
+ }
+ break;
+ }
+ case VMX_EXIT_REASON_EXECUTE_WRMSR:
+ {
+ hv::msr_split value;
+ value.low = regs->rax;
+ value.high = regs->rdx;
+
+ __try
+ {
+ __writemsr(regs->rcx, value.value);
+ }
+ __except (EXCEPTION_EXECUTE_HANDLER)
+ {
+ /*
+ EXCEPTION WARNING!: (will need to handle SEH in my IDT)
+ #GP(0) If the current privilege level is not 0.
+ If the value in ECX specifies a reserved or unimplemented MSR address.
+ #UD If the LOCK prefix is used.
+ */
+ vmentry_interrupt_information interrupt{};
+ interrupt.flags = interruption_type::software_interrupt;
+ interrupt.vector = EXCEPTION_GP_FAULT;
+ interrupt.valid = true;
+ __vmx_vmwrite(VMCS_CTRL_VMENTRY_INTERRUPTION_INFORMATION_FIELD, interrupt.flags);
+ }
+ break;
+ }
case VMX_EXIT_REASON_EXECUTE_VMWRITE:
- case VMX_EXIT_REASON_EXECUTE_VMPTRLD:
+ case VMX_EXIT_REASON_EXECUTE_VMREAD:
case VMX_EXIT_REASON_EXECUTE_VMPTRST:
+ case VMX_EXIT_REASON_EXECUTE_VMPTRLD:
case VMX_EXIT_REASON_EXECUTE_VMCLEAR:
- case VMX_EXIT_REASON_EXECUTE_VMLAUNCH:
- case VMX_EXIT_REASON_EXECUTE_RDTSC:
+ case VMX_EXIT_REASON_EXECUTE_VMXOFF:
+ case VMX_EXIT_REASON_EXECUTE_VMXON:
+ case VMX_EXIT_REASON_EXECUTE_VMCALL:
+ {
+ vmentry_interrupt_information interrupt{};
+ interrupt.flags = interruption_type::software_interrupt;
+ interrupt.vector = EXCEPTION_INVALID_OPCODE;
+ interrupt.valid = true;
+ __vmx_vmwrite(VMCS_CTRL_VMENTRY_INTERRUPTION_INFORMATION_FIELD, interrupt.flags);
+ break;
+ }
default:
+ // TODO: check out the vmexit reason and add support for it...
+ __debugbreak();
break;
}
+
+ size_t rip, exec_len;
+ __vmx_vmread(VMCS_GUEST_RIP, &rip);
+ __vmx_vmread(VMCS_VMEXIT_INSTRUCTION_LENGTH, &exec_len);
+ __vmx_vmwrite(VMCS_GUEST_RIP, rip + exec_len);
}
\ No newline at end of file
diff --git a/hv_types.hpp b/hv_types.hpp
index fb48330..c3e1edb 100644
--- a/hv_types.hpp
+++ b/hv_types.hpp
@@ -50,6 +50,8 @@ namespace hv
u128 xmm14;
u128 xmm15;
+ u64 padding_8b;
+
u64 r15;
u64 r14;
u64 r13;
@@ -63,9 +65,20 @@ namespace hv
u64 rsi;
u64 rdx;
u64 rcx;
+ u64 rbx;
u64 rax;
} guest_registers, * pguest_registers;
+ union msr_split
+ {
+ u64 value;
+ struct
+ {
+ u64 low : 32;
+ u64 high : 32;
+ };
+ };
+
union ia32_efer_t
{
unsigned __int64 control;
diff --git a/ia32.hpp b/ia32.hpp
index 52ba3e1..eb01a7b 100644
--- a/ia32.hpp
+++ b/ia32.hpp
@@ -251,6 +251,7 @@ typedef union
typedef union
{
+ uint64_t flags;
struct
{
uint64_t reserved1 : 3;
@@ -300,8 +301,6 @@ typedef union
#define CR3_ADDRESS_OF_PAGE_DIRECTORY(_) (((_) >> 12) & 0xFFFFFFFFF)
uint64_t reserved3 : 16;
};
-
- uint64_t flags;
} cr3;
typedef union
@@ -11518,6 +11517,7 @@ typedef union
#define IA32_VMX_TRUE_ENTRY_CTLS 0x00000490
typedef union
{
+ uint64_t flags;
struct
{
/**
@@ -11540,8 +11540,6 @@ typedef union
#define IA32_VMX_TRUE_CTLS_ALLOWED_1_SETTINGS_MASK 0xFFFFFFFF
#define IA32_VMX_TRUE_CTLS_ALLOWED_1_SETTINGS(_) (((_) >> 32) & 0xFFFFFFFF)
};
-
- uint64_t flags;
} ia32_vmx_true_ctls_register;
/**
@@ -20156,6 +20154,7 @@ typedef enum
*/
typedef union
{
+ uint32_t flags;
struct
{
/**
@@ -20204,8 +20203,6 @@ typedef union
#define VMENTRY_INTERRUPT_INFORMATION_VALID_MASK 0x01
#define VMENTRY_INTERRUPT_INFORMATION_VALID(_) (((_) >> 31) & 0x01)
};
-
- uint32_t flags;
} vmentry_interrupt_information;
/**
diff --git a/mm.cpp b/mm.cpp
new file mode 100644
index 0000000..b739c2f
--- /dev/null
+++ b/mm.cpp
@@ -0,0 +1,6 @@
+#include "mm.hpp"
+
+namespace mm
+{
+
+}
\ No newline at end of file
diff --git a/mm.hpp b/mm.hpp
new file mode 100644
index 0000000..c12bb4c
--- /dev/null
+++ b/mm.hpp
@@ -0,0 +1,125 @@
+#pragma once
+#include "hv_types.hpp"
+
+// the pml4 itself is inside of the HV...
+#pragma section(".pml4", read, write)
+
+namespace mm
+{
+ typedef union _virt_addr_t
+ {
+ void* value;
+ struct
+ {
+ u64 offset : 12;
+ u64 pt_index : 9;
+ u64 pd_index : 9;
+ u64 pdpt_index : 9;
+ u64 pml4_index : 9;
+ u64 reserved : 16;
+ };
+ } virt_addr_t, * pvirt_addr_t;
+
+ typedef union _pml4e
+ {
+ u64 value;
+ struct
+ {
+ u64 present : 1; // Must be 1, region invalid if 0.
+ u64 rw : 1; // If 0, writes not allowed.
+ u64 user_supervisor : 1; // If 0, user-mode accesses not allowed.
+ u64 PageWriteThrough : 1; // Determines the memory type used to access PDPT.
+ u64 page_cache : 1; // Determines the memory type used to access PDPT.
+ u64 accessed : 1; // If 0, this entry has not been used for translation.
+ u64 Ignored1 : 1;
+ u64 page_size : 1; // Must be 0 for PML4E.
+ u64 Ignored2 : 4;
+ u64 pfn : 36; // The page frame number of the PDPT of this PML4E.
+ u64 Reserved : 4;
+ u64 Ignored3 : 11;
+ u64 nx : 1; // If 1, instruction fetches not allowed.
+ };
+ } pml4e, * ppml4e;
+
+ typedef union _pdpte
+ {
+ u64 value;
+ struct
+ {
+ u64 present : 1; // Must be 1, region invalid if 0.
+ u64 rw : 1; // If 0, writes not allowed.
+ u64 user_supervisor : 1; // If 0, user-mode accesses not allowed.
+ u64 PageWriteThrough : 1; // Determines the memory type used to access PD.
+ u64 page_cache : 1; // Determines the memory type used to access PD.
+ u64 accessed : 1; // If 0, this entry has not been used for translation.
+ u64 Ignored1 : 1;
+ u64 page_size : 1; // If 1, this entry maps a 1GB page.
+ u64 Ignored2 : 4;
+ u64 pfn : 36; // The page frame number of the PD of this PDPTE.
+ u64 Reserved : 4;
+ u64 Ignored3 : 11;
+ u64 nx : 1; // If 1, instruction fetches not allowed.
+ };
+ } pdpte, * ppdpte;
+
+ typedef union _pde
+ {
+ u64 value;
+ struct
+ {
+ u64 present : 1; // Must be 1, region invalid if 0.
+ u64 rw : 1; // If 0, writes not allowed.
+ u64 user_supervisor : 1; // If 0, user-mode accesses not allowed.
+ u64 PageWriteThrough : 1; // Determines the memory type used to access PT.
+ u64 page_cache : 1; // Determines the memory type used to access PT.
+ u64 accessed : 1; // If 0, this entry has not been used for translation.
+ u64 Ignored1 : 1;
+ u64 page_size : 1; // If 1, this entry maps a 2MB page.
+ u64 Ignored2 : 4;
+ u64 pfn : 36; // The page frame number of the PT of this PDE.
+ u64 Reserved : 4;
+ u64 Ignored3 : 11;
+ u64 nx : 1; // If 1, instruction fetches not allowed.
+ };
+ } pde, * ppde;
+
+ typedef union _pte
+ {
+ u64 value;
+ struct
+ {
+ u64 present : 1; // Must be 1, region invalid if 0.
+ u64 rw : 1; // If 0, writes not allowed.
+ u64 user_supervisor : 1; // If 0, user-mode accesses not allowed.
+ u64 PageWriteThrough : 1; // Determines the memory type used to access the memory.
+ u64 page_cache : 1; // Determines the memory type used to access the memory.
+ u64 accessed : 1; // If 0, this entry has not been used for translation.
+ u64 Dirty : 1; // If 0, the memory backing this page has not been written to.
+ u64 PageAccessType : 1; // Determines the memory type used to access the memory.
+ u64 Global : 1; // If 1 and the PGE bit of CR4 is set, translations are global.
+ u64 Ignored2 : 3;
+ u64 pfn : 36; // The page frame number of the backing physical page.
+ u64 reserved : 4;
+ u64 Ignored3 : 7;
+ u64 ProtectionKey : 4; // If the PKE bit of CR4 is set, determines the protection key.
+ u64 nx : 1; // If 1, instruction fetches not allowed.
+ };
+ } pte, * ppte;
+
+ enum class map_type{ dest, src };
+
+ constexpr auto self_ref_index = 254;
+ inline const ppml4e vmxroot_pml4 = reinterpret_cast(0x7f0000000000);
+
+ // make sure this is 4kb aligned or you are going to be meeting allah...
+ __declspec(allocate(".pml4")) inline pml4e pml4[512];
+
+ // translate vmxroot address's...
+ auto translate(virt_addr_t virt_addr) -> u64;
+
+ // translate guest virtual addresses...
+ auto translate(virt_addr_t virt_addr, u64 pml4_phys, map_type type = map_type::src) -> u64;
+
+ // map a page into vmxroot address space...
+ auto map_page(u64 phys_addr, map_type type) -> u64;
+}
\ No newline at end of file
diff --git a/segment.cpp b/segment.cpp
index 0400074..6a6b564 100644
--- a/segment.cpp
+++ b/segment.cpp
@@ -21,8 +21,7 @@ namespace segment
auto get_info(const segment_descriptor_register_64& gdt_value, segment_selector selector) -> hv::segment_info_ctx
{
- hv::segment_info_ctx segment_info;
- memset(&segment_info, NULL, sizeof segment_info);
+ hv::segment_info_ctx segment_info{};
const auto segment_descriptor =
reinterpret_cast(
diff --git a/vmcs.cpp b/vmcs.cpp
index 89f9e78..53c6f3d 100644
--- a/vmcs.cpp
+++ b/vmcs.cpp
@@ -1,4 +1,5 @@
#include "vmcs.hpp"
+#include "mm.hpp"
namespace vmcs
{
@@ -10,17 +11,34 @@ namespace vmcs
__sidt(&idt_value);
_sgdt(&gdt_value);
- // use guest values for now... later on CR3 will be custom...
+ cr3 cr3_value;
+ cr3_value.flags = __readcr3();
+ cr3_value.address_of_page_directory =
+ (MmGetPhysicalAddress(mm::pml4).QuadPart >> 12);
+
+ memset(mm::pml4, NULL, sizeof mm::pml4);
+ mm::pml4[mm::self_ref_index].pfn = cr3_value.address_of_page_directory;
+ mm::pml4[mm::self_ref_index].present = true;
+ mm::pml4[mm::self_ref_index].rw = true;
+ mm::pml4[mm::self_ref_index].user_supervisor = false;
+
+ PHYSICAL_ADDRESS current_pml4;
+ current_pml4.QuadPart =
+ (cr3{ __readcr3() }.address_of_page_directory << 12);
+
+ const auto kernel_pml4 =
+ reinterpret_cast(
+ MmGetVirtualForPhysical(current_pml4));
+
+ // vmxroot will have the same "address space" as the current one being executed in...
+ memcpy(&mm::pml4[255], &kernel_pml4[255], sizeof(mm::pml4e) * 255);
+
__vmx_vmwrite(VMCS_HOST_CR0, __readcr0());
- __vmx_vmwrite(VMCS_HOST_CR3, __readcr3());
+ __vmx_vmwrite(VMCS_HOST_CR3, cr3_value.flags);
__vmx_vmwrite(VMCS_HOST_CR4, __readcr4());
- DBG_PRINT("host cr0: 0x%p\n", __readcr0());
- DBG_PRINT("host cr3: 0x%p\n", __readcr3());
- DBG_PRINT("host cr4: 0x%p\n", __readcr4());
-
// stack growns down...
- __vmx_vmwrite(VMCS_HOST_RSP, host_rsp + (PAGE_SIZE * HOST_STACK_PAGES) - 0x10);
+ __vmx_vmwrite(VMCS_HOST_RSP, host_rsp + (PAGE_SIZE * HOST_STACK_PAGES));
__vmx_vmwrite(VMCS_HOST_RIP, reinterpret_cast(host_rip));
__vmx_vmwrite(VMCS_HOST_GDTR_BASE, gdt_value.base_address);
@@ -80,49 +98,19 @@ namespace vmcs
__vmx_vmwrite(VMCS_GUEST_CR3, __readcr3());
__vmx_vmwrite(VMCS_GUEST_CR4, __readcr4());
- DBG_PRINT("guest cr0: 0x%p\n", __readcr0());
- DBG_PRINT("guest cr3: 0x%p\n", __readcr3());
- DBG_PRINT("guest cr4: 0x%p\n", __readcr4());
-
__vmx_vmwrite(VMCS_GUEST_VMCS_LINK_POINTER, ~0ULL);
__vmx_vmwrite(VMCS_GUEST_GDTR_BASE, gdt_value.base_address);
__vmx_vmwrite(VMCS_GUEST_GDTR_LIMIT, gdt_value.limit);
- DBG_PRINT("guest gdt base address: 0x%p\n", gdt_value.base_address);
- DBG_PRINT("guest gdt limit: 0x%x\n", gdt_value.limit);
-
__vmx_vmwrite(VMCS_GUEST_IDTR_BASE, idt_value.base_address);
__vmx_vmwrite(VMCS_GUEST_IDTR_LIMIT, idt_value.limit);
- DBG_PRINT("guest idt base address: 0x%p\n", idt_value.base_address);
- DBG_PRINT("guest idt limit: 0x%x\n", idt_value.limit);
-
__vmx_vmwrite(VMCS_GUEST_RFLAGS, __readeflags());
__vmx_vmwrite(VMCS_GUEST_DR7, __readdr(7));
- DBG_PRINT("guest rflags: 0x%p\n", __readeflags());
- DBG_PRINT("guest debug register 7: 0x%p\n", __readdr(7));
-
const auto [es_rights, es_limit, es_base] =
segment::get_info(gdt_value, segment_selector{ reades() });
- DBG_PRINT("es selector: 0x%p\n", reades());
- DBG_PRINT(" - es.index: %d\n", segment_selector{ reades() }.index);
- DBG_PRINT(" - es.request_privilege_level: %d\n", segment_selector{ reades() }.request_privilege_level);
- DBG_PRINT(" - es.table: %d\n", segment_selector{ reades() }.table);
- DBG_PRINT("es base address: 0x%p\n", es_base);
- DBG_PRINT("es limit: 0x%p\n", es_limit);
- DBG_PRINT("es rights: 0x%p\n", es_rights.flags);
- DBG_PRINT(" - es_rights.available_bit: %d\n", es_rights.available_bit);
- DBG_PRINT(" - es_rights.default_big: %d\n", es_rights.default_big);
- DBG_PRINT(" - es_rights.descriptor_privilege_level: %d\n", es_rights.descriptor_privilege_level);
- DBG_PRINT(" - es_rights.descriptor_type: %d\n", es_rights.descriptor_type);
- DBG_PRINT(" - es_rights.granularity: %d\n", es_rights.granularity);
- DBG_PRINT(" - es_rights.long_mode: %d\n", es_rights.long_mode);
- DBG_PRINT(" - es_rights.present: %d\n", es_rights.present);
- DBG_PRINT(" - es_rights.type: %d\n", es_rights.type);
- DBG_PRINT(" - es_rights.unusable: %d\n", es_rights.unusable);
-
__vmx_vmwrite(VMCS_GUEST_ES_BASE, es_base);
__vmx_vmwrite(VMCS_GUEST_ES_LIMIT, es_limit);
__vmx_vmwrite(VMCS_GUEST_ES_SELECTOR, reades());
@@ -131,23 +119,6 @@ namespace vmcs
const auto [fs_rights, fs_limit, fs_base] =
segment::get_info(gdt_value, segment_selector{ readfs() });
- DBG_PRINT("fs selector: 0x%p\n", readfs());
- DBG_PRINT(" - fs.index: %d\n", segment_selector{ readfs() }.index);
- DBG_PRINT(" - fs.request_privilege_level: %d\n", segment_selector{ readfs() }.request_privilege_level);
- DBG_PRINT(" - fs.table: %d\n", segment_selector{ readfs() }.table);
- DBG_PRINT("fs base address: 0x%p\n", fs_base);
- DBG_PRINT("fs limit: 0x%p\n", fs_limit);
- DBG_PRINT("fs rights: 0x%p\n", fs_rights.flags);
- DBG_PRINT(" - fs_rights.available_bit: %d\n", fs_rights.available_bit);
- DBG_PRINT(" - fs_rights.default_big: %d\n", fs_rights.default_big);
- DBG_PRINT(" - fs_rights.descriptor_privilege_level: %d\n", fs_rights.descriptor_privilege_level);
- DBG_PRINT(" - fs_rights.descriptor_type: %d\n", fs_rights.descriptor_type);
- DBG_PRINT(" - fs_rights.granularity: %d\n", fs_rights.granularity);
- DBG_PRINT(" - fs_rights.long_mode: %d\n", fs_rights.long_mode);
- DBG_PRINT(" - fs_rights.present: %d\n", fs_rights.present);
- DBG_PRINT(" - fs_rights.type: %d\n", fs_rights.type);
- DBG_PRINT(" - fs_rights.unusable: %d\n", fs_rights.unusable);
-
__vmx_vmwrite(VMCS_GUEST_FS_BASE, fs_base);
__vmx_vmwrite(VMCS_GUEST_FS_LIMIT, fs_limit);
__vmx_vmwrite(VMCS_GUEST_FS_SELECTOR, readfs());
@@ -156,23 +127,6 @@ namespace vmcs
const auto [gs_rights, gs_limit, gs_base] =
segment::get_info(gdt_value, segment_selector{ readgs() });
- DBG_PRINT("gs selector: 0x%p\n", readgs());
- DBG_PRINT(" - gs.index: %d\n", segment_selector{ readgs() }.index);
- DBG_PRINT(" - gs.request_privilege_level: %d\n", segment_selector{ readgs() }.request_privilege_level);
- DBG_PRINT(" - gs.table: %d\n", segment_selector{ readgs() }.table);
- DBG_PRINT("gs base address: 0x%p\n", gs_base);
- DBG_PRINT("gs limit: 0x%p\n", gs_limit);
- DBG_PRINT("gs rights: 0x%p\n", gs_rights.flags);
- DBG_PRINT(" - gs_rights.available_bit: %d\n", gs_rights.available_bit);
- DBG_PRINT(" - gs_rights.default_big: %d\n", gs_rights.default_big);
- DBG_PRINT(" - gs_rights.descriptor_privilege_level: %d\n", gs_rights.descriptor_privilege_level);
- DBG_PRINT(" - gs_rights.descriptor_type: %d\n", gs_rights.descriptor_type);
- DBG_PRINT(" - gs_rights.granularity: %d\n", gs_rights.granularity);
- DBG_PRINT(" - gs_rights.long_mode: %d\n", gs_rights.long_mode);
- DBG_PRINT(" - gs_rights.present: %d\n", gs_rights.present);
- DBG_PRINT(" - gs_rights.type: %d\n", gs_rights.type);
- DBG_PRINT(" - gs_rights.unusable: %d\n", gs_rights.unusable);
-
__vmx_vmwrite(VMCS_GUEST_GS_BASE, gs_base);
__vmx_vmwrite(VMCS_GUEST_GS_LIMIT, gs_limit);
__vmx_vmwrite(VMCS_GUEST_GS_SELECTOR, readgs());
@@ -181,23 +135,6 @@ namespace vmcs
const auto [ss_rights, ss_limit, ss_base] =
segment::get_info(gdt_value, segment_selector{ readss() });
- DBG_PRINT("ss selector: 0x%p\n", readss());
- DBG_PRINT(" - ss.index: %d\n", segment_selector{ readss() }.index);
- DBG_PRINT(" - ss.request_privilege_level: %d\n", segment_selector{ readss() }.request_privilege_level);
- DBG_PRINT(" - ss.table: %d\n", segment_selector{ readss() }.table);
- DBG_PRINT("ss base address: 0x%p\n", ss_base);
- DBG_PRINT("ss limit: 0x%p\n", ss_limit);
- DBG_PRINT("ss rights: 0x%p\n", ss_rights.flags);
- DBG_PRINT(" - ss_rights.available_bit: %d\n", ss_rights.available_bit);
- DBG_PRINT(" - ss_rights.default_big: %d\n", ss_rights.default_big);
- DBG_PRINT(" - ss_rights.descriptor_privilege_level: %d\n", ss_rights.descriptor_privilege_level);
- DBG_PRINT(" - ss_rights.descriptor_type: %d\n", ss_rights.descriptor_type);
- DBG_PRINT(" - ss_rights.granularity: %d\n", ss_rights.granularity);
- DBG_PRINT(" - ss_rights.long_mode: %d\n", ss_rights.long_mode);
- DBG_PRINT(" - ss_rights.present: %d\n", ss_rights.present);
- DBG_PRINT(" - ss_rights.type: %d\n", ss_rights.type);
- DBG_PRINT(" - ss_rights.unusable: %d\n", ss_rights.unusable);
-
__vmx_vmwrite(VMCS_GUEST_SS_BASE, ss_base);
__vmx_vmwrite(VMCS_GUEST_SS_LIMIT, ss_limit);
__vmx_vmwrite(VMCS_GUEST_SS_SELECTOR, readss());
@@ -206,23 +143,6 @@ namespace vmcs
const auto [cs_rights, cs_limit, cs_base] =
segment::get_info(gdt_value, segment_selector{ readcs() });
- DBG_PRINT("cs selector: 0x%p\n", readcs());
- DBG_PRINT(" - cs.index: %d\n", segment_selector{ readcs() }.index);
- DBG_PRINT(" - cs.request_privilege_level: %d\n", segment_selector{ readcs() }.request_privilege_level);
- DBG_PRINT(" - cs.table: %d\n", segment_selector{ readcs() }.table);
- DBG_PRINT("cs base address: 0x%p\n", cs_base);
- DBG_PRINT("cs limit: 0x%p\n", cs_limit);
- DBG_PRINT("cs rights: 0x%p\n", cs_rights.flags);
- DBG_PRINT(" - cs_rights.available_bit: %d\n", cs_rights.available_bit);
- DBG_PRINT(" - cs_rights.default_big: %d\n", cs_rights.default_big);
- DBG_PRINT(" - cs_rights.descriptor_privilege_level: %d\n", cs_rights.descriptor_privilege_level);
- DBG_PRINT(" - cs_rights.descriptor_type: %d\n", cs_rights.descriptor_type);
- DBG_PRINT(" - cs_rights.granularity: %d\n", cs_rights.granularity);
- DBG_PRINT(" - cs_rights.long_mode: %d\n", cs_rights.long_mode);
- DBG_PRINT(" - cs_rights.present: %d\n", cs_rights.present);
- DBG_PRINT(" - cs_rights.type: %d\n", cs_rights.type);
- DBG_PRINT(" - cs_rights.unusable: %d\n", cs_rights.unusable);
-
__vmx_vmwrite(VMCS_GUEST_CS_BASE, cs_base);
__vmx_vmwrite(VMCS_GUEST_CS_LIMIT, cs_limit);
__vmx_vmwrite(VMCS_GUEST_CS_SELECTOR, readcs());
@@ -231,23 +151,6 @@ namespace vmcs
const auto [ds_rights, ds_limit, ds_base] =
segment::get_info(gdt_value, segment_selector{ readds() });
- DBG_PRINT("ds selector: 0x%p\n", readds());
- DBG_PRINT(" - ds.index: %d\n", segment_selector{ readds() }.index);
- DBG_PRINT(" - ds.request_privilege_level: %d\n", segment_selector{ readds() }.request_privilege_level);
- DBG_PRINT(" - ds.table: %d\n", segment_selector{ readds() }.table);
- DBG_PRINT("ds base address: 0x%p\n", ds_base);
- DBG_PRINT("ds limit: 0x%p\n", ds_limit);
- DBG_PRINT("ds rights: 0x%p\n", ds_rights.flags);
- DBG_PRINT(" - ds_rights.available_bit: %d\n", ds_rights.available_bit);
- DBG_PRINT(" - ds_rights.default_big: %d\n", ds_rights.default_big);
- DBG_PRINT(" - ds_rights.descriptor_privilege_level: %d\n", ds_rights.descriptor_privilege_level);
- DBG_PRINT(" - ds_rights.descriptor_type: %d\n", ds_rights.descriptor_type);
- DBG_PRINT(" - ds_rights.granularity: %d\n", ds_rights.granularity);
- DBG_PRINT(" - ds_rights.long_mode: %d\n", ds_rights.long_mode);
- DBG_PRINT(" - ds_rights.present: %d\n", ds_rights.present);
- DBG_PRINT(" - ds_rights.type: %d\n", ds_rights.type);
- DBG_PRINT(" - ds_rights.unusable: %d\n", ds_rights.unusable);
-
__vmx_vmwrite(VMCS_GUEST_DS_BASE, ds_base);
__vmx_vmwrite(VMCS_GUEST_DS_LIMIT, ds_limit);
__vmx_vmwrite(VMCS_GUEST_DS_SELECTOR, readds());
@@ -256,23 +159,6 @@ namespace vmcs
const auto [tr_rights, tr_limit, tr_base] =
segment::get_info(gdt_value, segment_selector{ readtr() });
- DBG_PRINT("tr selector: 0x%p\n", readtr());
- DBG_PRINT(" - tr.index: %d\n", segment_selector{ readtr() }.index);
- DBG_PRINT(" - tr.request_privilege_level: %d\n", segment_selector{ readtr() }.request_privilege_level);
- DBG_PRINT(" - tr.table: %d\n", segment_selector{ readtr() }.table);
- DBG_PRINT("tr base address: 0x%p\n", tr_base);
- DBG_PRINT("tr limit: 0x%p\n", tr_limit);
- DBG_PRINT("tr rights: 0x%p\n", tr_rights.flags);
- DBG_PRINT(" - tr_rights.available_bit: %d\n", tr_rights.available_bit);
- DBG_PRINT(" - tr_rights.default_big: %d\n", tr_rights.default_big);
- DBG_PRINT(" - tr_rights.descriptor_privilege_level: %d\n", tr_rights.descriptor_privilege_level);
- DBG_PRINT(" - tr_rights.descriptor_type: %d\n", tr_rights.descriptor_type);
- DBG_PRINT(" - tr_rights.granularity: %d\n", tr_rights.granularity);
- DBG_PRINT(" - tr_rights.long_mode: %d\n", tr_rights.long_mode);
- DBG_PRINT(" - tr_rights.present: %d\n", tr_rights.present);
- DBG_PRINT(" - tr_rights.type: %d\n", tr_rights.type);
- DBG_PRINT(" - tr_rights.unusable: %d\n", tr_rights.unusable);
-
__vmx_vmwrite(VMCS_GUEST_TR_BASE, tr_base);
__vmx_vmwrite(VMCS_GUEST_TR_LIMIT, tr_limit);
__vmx_vmwrite(VMCS_GUEST_TR_SELECTOR, readtr());
@@ -281,34 +167,13 @@ namespace vmcs
const auto [ldt_rights, ldt_limit, ldt_base] =
segment::get_info(gdt_value, segment_selector{ readldt() });
- DBG_PRINT("ldt selector: 0x%p\n", readldt());
- DBG_PRINT(" - ldt.index: %d\n", segment_selector{ readldt() }.index);
- DBG_PRINT(" - ldt.request_privilege_level: %d\n", segment_selector{ readldt() }.request_privilege_level);
- DBG_PRINT(" - ldt.table: %d\n", segment_selector{ readldt() }.table);
- DBG_PRINT("ldt base address: 0x%p\n", tr_base);
- DBG_PRINT("ldt limit: 0x%p\n", tr_limit);
- DBG_PRINT("ldt rights: 0x%p\n", tr_rights.flags);
- DBG_PRINT(" - ldt_rights.available_bit: %d\n", tr_rights.available_bit);
- DBG_PRINT(" - ldt_rights.default_big: %d\n", tr_rights.default_big);
- DBG_PRINT(" - ldt_rights.descriptor_privilege_level: %d\n", tr_rights.descriptor_privilege_level);
- DBG_PRINT(" - ldt_rights.descriptor_type: %d\n", tr_rights.descriptor_type);
- DBG_PRINT(" - ldt_rights.granularity: %d\n", tr_rights.granularity);
- DBG_PRINT(" - ldt_rights.long_mode: %d\n", tr_rights.long_mode);
- DBG_PRINT(" - ldt_rights.present: %d\n", tr_rights.present);
- DBG_PRINT(" - ldt_rights.type: %d\n", tr_rights.type);
- DBG_PRINT(" - ldt_rights.unusable: %d\n", tr_rights.unusable);
-
__vmx_vmwrite(VMCS_GUEST_LDTR_BASE, ldt_base);
__vmx_vmwrite(VMCS_GUEST_LDTR_LIMIT, ldt_limit);
__vmx_vmwrite(VMCS_GUEST_LDTR_SELECTOR, readldt());
__vmx_vmwrite(VMCS_GUEST_LDTR_ACCESS_RIGHTS, ldt_rights.flags);
- __vmx_vmwrite(VMCS_GUEST_GS_BASE, __readmsr(IA32_GS_BASE));
- DBG_PRINT("guest gs base (from readmsr): 0x%p\n", __readmsr(IA32_GS_BASE));
-
__vmx_vmwrite(VMCS_GUEST_ACTIVITY_STATE, 0);
- __vmx_vmwrite(VMCS_GUEST_INTERRUPTIBILITY_STATE, 0);
- __vmx_vmwrite(VMCS_GUEST_PENDING_DEBUG_EXCEPTIONS, 0);
+ __vmx_vmwrite(VMCS_GUEST_GS_BASE, __readmsr(IA32_GS_BASE));
}
auto setup_controls() -> void
@@ -335,48 +200,12 @@ namespace vmcs
pinbased_ctls.flags |= msr_fix_value.allowed_0_settings;
__vmx_vmwrite(VMCS_CTRL_PIN_BASED_VM_EXECUTION_CONTROLS, pinbased_ctls.flags);
- DBG_PRINT("============================== pinbased vm-exit controls ==============================\n");
- DBG_PRINT(" - pinbased_ctls.activate_vmx_preemption_timer: %d\n", pinbased_ctls.activate_vmx_preemption_timer);
- DBG_PRINT(" - pinbased_ctls.external_interrupt_exiting: %d\n", pinbased_ctls.external_interrupt_exiting);
- DBG_PRINT(" - pinbased_ctls.nmi_exiting: %d\n", pinbased_ctls.nmi_exiting);
- DBG_PRINT(" - pinbased_ctls.process_posted_interrupts: %d\n", pinbased_ctls.process_posted_interrupts);
- DBG_PRINT(" - pinbased_ctls.virtual_nmi: %d\n", pinbased_ctls.virtual_nmi);
- DBG_PRINT(" - pinbased_ctls.flags: 0x%x\n", pinbased_ctls.flags);
- DBG_PRINT(" - IA32_VMX_TRUE_PINBASED_CTLS high bits mask: 0x%x\n", msr_fix_value.allowed_1_settings);
- DBG_PRINT(" - IA32_VMX_TRUE_PINBASED_CTLS low bits mask: 0x%x\n", msr_fix_value.allowed_0_settings);
-
msr_fix_value.flags = __readmsr(IA32_VMX_TRUE_PROCBASED_CTLS);
procbased_ctls.activate_secondary_controls = true;
procbased_ctls.flags &= msr_fix_value.allowed_1_settings;
procbased_ctls.flags |= msr_fix_value.allowed_0_settings;
__vmx_vmwrite(VMCS_CTRL_PROCESSOR_BASED_VM_EXECUTION_CONTROLS, procbased_ctls.flags);
- DBG_PRINT("============================== processor based vm-exit controls ==============================\n");
- DBG_PRINT(" - procbased_ctls.activate_secondary_controls: %d\n", procbased_ctls.activate_secondary_controls);
- DBG_PRINT(" - procbased_ctls.cr3_load_exiting: %d\n", procbased_ctls.cr3_load_exiting);
- DBG_PRINT(" - procbased_ctls.cr3_store_exiting: %d\n", procbased_ctls.cr3_store_exiting);
- DBG_PRINT(" - procbased_ctls.cr8_load_exiting: %d\n", procbased_ctls.cr8_load_exiting);
- DBG_PRINT(" - procbased_ctls.cr8_store_exiting: %d\n", procbased_ctls.cr8_store_exiting);
- DBG_PRINT(" - procbased_ctls.hlt_exiting: %d\n", procbased_ctls.hlt_exiting);
- DBG_PRINT(" - procbased_ctls.interrupt_window_exiting: %d\n", procbased_ctls.interrupt_window_exiting);
- DBG_PRINT(" - procbased_ctls.invlpg_exiting: %d\n", procbased_ctls.invlpg_exiting);
- DBG_PRINT(" - procbased_ctls.monitor_exiting: %d\n", procbased_ctls.monitor_exiting);
- DBG_PRINT(" - procbased_ctls.monitor_trap_flag: %d\n", procbased_ctls.monitor_trap_flag);
- DBG_PRINT(" - procbased_ctls.mov_dr_exiting: %d\n", procbased_ctls.mov_dr_exiting);
- DBG_PRINT(" - procbased_ctls.mwait_exiting: %d\n", procbased_ctls.mwait_exiting);
- DBG_PRINT(" - procbased_ctls.nmi_window_exiting: %d\n", procbased_ctls.nmi_window_exiting);
- DBG_PRINT(" - procbased_ctls.pause_exiting: %d\n", procbased_ctls.pause_exiting);
- DBG_PRINT(" - procbased_ctls.rdpmc_exiting: %d\n", procbased_ctls.rdpmc_exiting);
- DBG_PRINT(" - procbased_ctls.rdtsc_exiting: %d\n", procbased_ctls.rdtsc_exiting);
- DBG_PRINT(" - procbased_ctls.unconditional_io_exiting: %d\n", procbased_ctls.unconditional_io_exiting);
- DBG_PRINT(" - procbased_ctls.use_io_bitmaps: %d\n", procbased_ctls.use_io_bitmaps);
- DBG_PRINT(" - procbased_ctls.use_msr_bitmaps: %d\n", procbased_ctls.use_msr_bitmaps);
- DBG_PRINT(" - procbased_ctls.use_tpr_shadow: %d\n", procbased_ctls.use_tpr_shadow);
- DBG_PRINT(" - procbased_ctls.use_tsc_offsetting: %d\n", procbased_ctls.use_tsc_offsetting);
- DBG_PRINT(" - procbased_ctls.flags: 0x%x\n", procbased_ctls.flags);
- DBG_PRINT(" - IA32_VMX_TRUE_PROCBASED_CTLS high bits mask: 0x%x\n", msr_fix_value.allowed_1_settings);
- DBG_PRINT(" - IA32_VMX_TRUE_PROCBASED_CTLS low bits mask: 0x%x\n", msr_fix_value.allowed_0_settings);
-
msr_fix_value.flags = __readmsr(IA32_VMX_TRUE_ENTRY_CTLS);
entry_ctls.ia32e_mode_guest = true;
entry_ctls.conceal_vmx_from_pt = true;
@@ -384,43 +213,11 @@ namespace vmcs
entry_ctls.flags |= msr_fix_value.allowed_0_settings;
__vmx_vmwrite(VMCS_CTRL_VMENTRY_CONTROLS, entry_ctls.flags);
- DBG_PRINT("============================== vm-entry controls ==============================\n");
- DBG_PRINT(" - entry_ctls.conceal_vmx_from_pt: %d\n", entry_ctls.conceal_vmx_from_pt);
- DBG_PRINT(" - entry_ctls.deactivate_dual_monitor_treatment: %d\n", entry_ctls.deactivate_dual_monitor_treatment);
- DBG_PRINT(" - entry_ctls.entry_to_smm: %d\n", entry_ctls.entry_to_smm);
- DBG_PRINT(" - entry_ctls.ia32e_mode_guest: %d\n", entry_ctls.ia32e_mode_guest);
- DBG_PRINT(" - entry_ctls.load_cet_state: %d\n", entry_ctls.load_cet_state);
- DBG_PRINT(" - entry_ctls.load_debug_controls: %d\n", entry_ctls.load_debug_controls);
- DBG_PRINT(" - entry_ctls.load_ia32_bndcfgs: %d\n", entry_ctls.load_ia32_bndcfgs);
- DBG_PRINT(" - entry_ctls.load_ia32_efer: %d\n", entry_ctls.load_ia32_efer);
- DBG_PRINT(" - entry_ctls.load_ia32_pat: %d\n", entry_ctls.load_ia32_pat);
- DBG_PRINT(" - entry_ctls.load_ia32_perf_global_ctrl: %d\n", entry_ctls.load_ia32_perf_global_ctrl);
- DBG_PRINT(" - entry_ctls.load_ia32_rtit_ctl: %d\n", entry_ctls.load_ia32_rtit_ctl);
- DBG_PRINT(" - entry_ctls.flags: 0x%x\n", entry_ctls.flags);
- DBG_PRINT(" - IA32_VMX_TRUE_ENTRY_CTLS high bits mask: 0x%x\n", msr_fix_value.allowed_1_settings);
- DBG_PRINT(" - IA32_VMX_TRUE_ENTRY_CTLS low bits mask: 0x%x\n", msr_fix_value.allowed_0_settings);
-
msr_fix_value.flags = __readmsr(IA32_VMX_TRUE_EXIT_CTLS);
exit_ctls.host_address_space_size = true;
exit_ctls.flags &= msr_fix_value.allowed_1_settings;
exit_ctls.flags |= msr_fix_value.allowed_0_settings;
__vmx_vmwrite(VMCS_CTRL_VMEXIT_CONTROLS, exit_ctls.flags);
-
- DBG_PRINT("============================== vm-exit controls ==============================\n");
- DBG_PRINT(" - exit_ctls.acknowledge_interrupt_on_exit: %d\n", exit_ctls.acknowledge_interrupt_on_exit);
- DBG_PRINT(" - exit_ctls.clear_ia32_bndcfgs: %d\n", exit_ctls.clear_ia32_bndcfgs);
- DBG_PRINT(" - exit_ctls.conceal_vmx_from_pt: %d\n", exit_ctls.conceal_vmx_from_pt);
- DBG_PRINT(" - exit_ctls.host_address_space_size: %d\n", exit_ctls.host_address_space_size);
- DBG_PRINT(" - exit_ctls.load_ia32_efer: %d\n", exit_ctls.load_ia32_efer);
- DBG_PRINT(" - exit_ctls.load_ia32_pat: %d\n", exit_ctls.load_ia32_pat);
- DBG_PRINT(" - exit_ctls.load_ia32_perf_global_ctrl: %d\n", exit_ctls.load_ia32_perf_global_ctrl);
- DBG_PRINT(" - exit_ctls.save_debug_controls: %d\n", exit_ctls.save_debug_controls);
- DBG_PRINT(" - exit_ctls.save_ia32_efer: %d\n", exit_ctls.save_ia32_efer);
- DBG_PRINT(" - exit_ctls.save_ia32_pat: %d\n", exit_ctls.save_ia32_pat);
- DBG_PRINT(" - exit_ctls.save_vmx_preemption_timer_value: %d\n", exit_ctls.save_vmx_preemption_timer_value);
- DBG_PRINT(" - exit_ctls.flags: 0x%x\n", exit_ctls.flags);
- DBG_PRINT(" - IA32_VMX_TRUE_EXIT_CTLS high bits mask: 0x%x\n", msr_fix_value.allowed_1_settings);
- DBG_PRINT(" - IA32_VMX_TRUE_EXIT_CTLS low bits mask: 0x%x\n", msr_fix_value.allowed_0_settings);
}
else
{
@@ -429,48 +226,12 @@ namespace vmcs
pinbased_ctls.flags |= msr_fix_value.allowed_0_settings;
__vmx_vmwrite(VMCS_CTRL_PIN_BASED_VM_EXECUTION_CONTROLS, pinbased_ctls.flags);
- DBG_PRINT("============================== pinbased vm-exit controls ==============================\n");
- DBG_PRINT(" - pinbased_ctls.activate_vmx_preemption_timer: %d\n", pinbased_ctls.activate_vmx_preemption_timer);
- DBG_PRINT(" - pinbased_ctls.external_interrupt_exiting: %d\n", pinbased_ctls.external_interrupt_exiting);
- DBG_PRINT(" - pinbased_ctls.nmi_exiting: %d\n", pinbased_ctls.nmi_exiting);
- DBG_PRINT(" - pinbased_ctls.process_posted_interrupts: %d\n", pinbased_ctls.process_posted_interrupts);
- DBG_PRINT(" - pinbased_ctls.virtual_nmi: %d\n", pinbased_ctls.virtual_nmi);
- DBG_PRINT(" - pinbased_ctls.flags: 0x%x\n", pinbased_ctls.flags);
- DBG_PRINT(" - IA32_VMX_PINBASED_CTLS high bits mask: 0x%x\n", msr_fix_value.allowed_1_settings);
- DBG_PRINT(" - IA32_VMX_PINBASED_CTLS low bits mask: 0x%x\n", msr_fix_value.allowed_0_settings);
-
msr_fix_value.flags = __readmsr(IA32_VMX_PROCBASED_CTLS);
procbased_ctls.activate_secondary_controls = true;
procbased_ctls.flags &= msr_fix_value.allowed_1_settings;
procbased_ctls.flags |= msr_fix_value.allowed_0_settings;
__vmx_vmwrite(VMCS_CTRL_PROCESSOR_BASED_VM_EXECUTION_CONTROLS, procbased_ctls.flags);
- DBG_PRINT("============================== processor based vm-exit controls ==============================\n");
- DBG_PRINT(" - procbased_ctls.activate_secondary_controls: %d\n", procbased_ctls.activate_secondary_controls);
- DBG_PRINT(" - procbased_ctls.cr3_load_exiting: %d\n", procbased_ctls.cr3_load_exiting);
- DBG_PRINT(" - procbased_ctls.cr3_store_exiting: %d\n", procbased_ctls.cr3_store_exiting);
- DBG_PRINT(" - procbased_ctls.cr8_load_exiting: %d\n", procbased_ctls.cr8_load_exiting);
- DBG_PRINT(" - procbased_ctls.cr8_store_exiting: %d\n", procbased_ctls.cr8_store_exiting);
- DBG_PRINT(" - procbased_ctls.hlt_exiting: %d\n", procbased_ctls.hlt_exiting);
- DBG_PRINT(" - procbased_ctls.interrupt_window_exiting: %d\n", procbased_ctls.interrupt_window_exiting);
- DBG_PRINT(" - procbased_ctls.invlpg_exiting: %d\n", procbased_ctls.invlpg_exiting);
- DBG_PRINT(" - procbased_ctls.monitor_exiting: %d\n", procbased_ctls.monitor_exiting);
- DBG_PRINT(" - procbased_ctls.monitor_trap_flag: %d\n", procbased_ctls.monitor_trap_flag);
- DBG_PRINT(" - procbased_ctls.mov_dr_exiting: %d\n", procbased_ctls.mov_dr_exiting);
- DBG_PRINT(" - procbased_ctls.mwait_exiting: %d\n", procbased_ctls.mwait_exiting);
- DBG_PRINT(" - procbased_ctls.nmi_window_exiting: %d\n", procbased_ctls.nmi_window_exiting);
- DBG_PRINT(" - procbased_ctls.pause_exiting: %d\n", procbased_ctls.pause_exiting);
- DBG_PRINT(" - procbased_ctls.rdpmc_exiting: %d\n", procbased_ctls.rdpmc_exiting);
- DBG_PRINT(" - procbased_ctls.rdtsc_exiting: %d\n", procbased_ctls.rdtsc_exiting);
- DBG_PRINT(" - procbased_ctls.unconditional_io_exiting: %d\n", procbased_ctls.unconditional_io_exiting);
- DBG_PRINT(" - procbased_ctls.use_io_bitmaps: %d\n", procbased_ctls.use_io_bitmaps);
- DBG_PRINT(" - procbased_ctls.use_msr_bitmaps: %d\n", procbased_ctls.use_msr_bitmaps);
- DBG_PRINT(" - procbased_ctls.use_tpr_shadow: %d\n", procbased_ctls.use_tpr_shadow);
- DBG_PRINT(" - procbased_ctls.use_tsc_offsetting: %d\n", procbased_ctls.use_tsc_offsetting);
- DBG_PRINT(" - procbased_ctls.flags: 0x%x\n", procbased_ctls.flags);
- DBG_PRINT(" - IA32_VMX_PROCBASED_CTLS high bits mask: 0x%x\n", msr_fix_value.allowed_1_settings);
- DBG_PRINT(" - IA32_VMX_PROCBASED_CTLS low bits mask: 0x%x\n", msr_fix_value.allowed_0_settings);
-
msr_fix_value.flags = __readmsr(IA32_VMX_ENTRY_CTLS);
entry_ctls.ia32e_mode_guest = true;
entry_ctls.conceal_vmx_from_pt = true;
@@ -478,80 +239,20 @@ namespace vmcs
entry_ctls.flags |= msr_fix_value.allowed_0_settings;
__vmx_vmwrite(VMCS_CTRL_VMENTRY_CONTROLS, entry_ctls.flags);
- DBG_PRINT("============================== vm-entry controls ==============================\n");
- DBG_PRINT(" - entry_ctls.conceal_vmx_from_pt: %d\n", entry_ctls.conceal_vmx_from_pt);
- DBG_PRINT(" - entry_ctls.deactivate_dual_monitor_treatment: %d\n", entry_ctls.deactivate_dual_monitor_treatment);
- DBG_PRINT(" - entry_ctls.entry_to_smm: %d\n", entry_ctls.entry_to_smm);
- DBG_PRINT(" - entry_ctls.ia32e_mode_guest: %d\n", entry_ctls.ia32e_mode_guest);
- DBG_PRINT(" - entry_ctls.load_cet_state: %d\n", entry_ctls.load_cet_state);
- DBG_PRINT(" - entry_ctls.load_debug_controls: %d\n", entry_ctls.load_debug_controls);
- DBG_PRINT(" - entry_ctls.load_ia32_bndcfgs: %d\n", entry_ctls.load_ia32_bndcfgs);
- DBG_PRINT(" - entry_ctls.load_ia32_efer: %d\n", entry_ctls.load_ia32_efer);
- DBG_PRINT(" - entry_ctls.load_ia32_pat: %d\n", entry_ctls.load_ia32_pat);
- DBG_PRINT(" - entry_ctls.load_ia32_perf_global_ctrl: %d\n", entry_ctls.load_ia32_perf_global_ctrl);
- DBG_PRINT(" - entry_ctls.load_ia32_rtit_ctl: %d\n", entry_ctls.load_ia32_rtit_ctl);
- DBG_PRINT(" - entry_ctls.flags: 0x%x\n", entry_ctls.flags);
- DBG_PRINT(" - IA32_VMX_ENTRY_CTLS high bits mask: 0x%x\n", msr_fix_value.allowed_1_settings);
- DBG_PRINT(" - IA32_VMX_ENTRY_CTLS low bits mask: 0x%x\n", msr_fix_value.allowed_0_settings);
-
msr_fix_value.flags = __readmsr(IA32_VMX_EXIT_CTLS);
exit_ctls.host_address_space_size = true;
exit_ctls.conceal_vmx_from_pt = true;
exit_ctls.flags &= msr_fix_value.allowed_1_settings;
exit_ctls.flags |= msr_fix_value.allowed_0_settings;
__vmx_vmwrite(VMCS_CTRL_VMEXIT_CONTROLS, exit_ctls.flags);
-
- DBG_PRINT("============================== vm-exit controls ==============================\n");
- DBG_PRINT(" - exit_ctls.acknowledge_interrupt_on_exit: %d\n", exit_ctls.acknowledge_interrupt_on_exit);
- DBG_PRINT(" - exit_ctls.clear_ia32_bndcfgs: %d\n", exit_ctls.clear_ia32_bndcfgs);
- DBG_PRINT(" - exit_ctls.conceal_vmx_from_pt: %d\n", exit_ctls.conceal_vmx_from_pt);
- DBG_PRINT(" - exit_ctls.host_address_space_size: %d\n", exit_ctls.host_address_space_size);
- DBG_PRINT(" - exit_ctls.load_ia32_efer: %d\n", exit_ctls.load_ia32_efer);
- DBG_PRINT(" - exit_ctls.load_ia32_pat: %d\n", exit_ctls.load_ia32_pat);
- DBG_PRINT(" - exit_ctls.load_ia32_perf_global_ctrl: %d\n", exit_ctls.load_ia32_perf_global_ctrl);
- DBG_PRINT(" - exit_ctls.save_debug_controls: %d\n", exit_ctls.save_debug_controls);
- DBG_PRINT(" - exit_ctls.save_ia32_efer: %d\n", exit_ctls.save_ia32_efer);
- DBG_PRINT(" - exit_ctls.save_ia32_pat: %d\n", exit_ctls.save_ia32_pat);
- DBG_PRINT(" - exit_ctls.save_vmx_preemption_timer_value: %d\n", exit_ctls.save_vmx_preemption_timer_value);
- DBG_PRINT(" - exit_ctls.flags: 0x%x\n", exit_ctls.flags);
- DBG_PRINT(" - IA32_VMX_EXIT_CTLS high bits mask: 0x%x\n", msr_fix_value.allowed_1_settings);
- DBG_PRINT(" - IA32_VMX_EXIT_CTLS low bits mask: 0x%x\n", msr_fix_value.allowed_0_settings);
}
msr_fix_value.flags = __readmsr(IA32_VMX_PROCBASED_CTLS2);
procbased_ctls2.enable_rdtscp = true;
- procbased_ctls2.enable_xsaves = true;
+ procbased_ctls2.enable_xsaves = true;
procbased_ctls2.conceal_vmx_from_pt = true;
procbased_ctls2.flags &= msr_fix_value.allowed_1_settings;
procbased_ctls2.flags |= msr_fix_value.allowed_0_settings;
__vmx_vmwrite(VMCS_CTRL_SECONDARY_PROCESSOR_BASED_VM_EXECUTION_CONTROLS, procbased_ctls2.flags);
-
- DBG_PRINT("============================== secondary processor based vm-exec controls ==============================\n");
- DBG_PRINT(" - procbased_ctls2.apic_register_virtualization: %d\n", procbased_ctls2.apic_register_virtualization);
- DBG_PRINT(" - procbased_ctls2.conceal_vmx_from_pt: %d\n", procbased_ctls2.conceal_vmx_from_pt);
- DBG_PRINT(" - procbased_ctls2.descriptor_table_exiting: %d\n", procbased_ctls2.descriptor_table_exiting);
- DBG_PRINT(" - procbased_ctls2.enable_encls_exiting: %d\n", procbased_ctls2.enable_encls_exiting);
- DBG_PRINT(" - procbased_ctls2.enable_ept: %d\n", procbased_ctls2.enable_ept);
- DBG_PRINT(" - procbased_ctls2.enable_invpcid: %d\n", procbased_ctls2.enable_invpcid);
- DBG_PRINT(" - procbased_ctls2.enable_pml: %d\n", procbased_ctls2.enable_pml);
- DBG_PRINT(" - procbased_ctls2.enable_rdtscp: %d\n", procbased_ctls2.enable_rdtscp);
- DBG_PRINT(" - procbased_ctls2.enable_vm_functions: %d\n", procbased_ctls2.enable_vm_functions);
- DBG_PRINT(" - procbased_ctls2.enable_vpid: %d\n", procbased_ctls2.enable_vpid);
- DBG_PRINT(" - procbased_ctls2.enable_xsaves: %d\n", procbased_ctls2.enable_xsaves);
- DBG_PRINT(" - procbased_ctls2.ept_violation: %d\n", procbased_ctls2.ept_violation);
- DBG_PRINT(" - procbased_ctls2.mode_based_execute_control_for_ept: %d\n", procbased_ctls2.mode_based_execute_control_for_ept);
- DBG_PRINT(" - procbased_ctls2.pause_loop_exiting: %d\n", procbased_ctls2.pause_loop_exiting);
- DBG_PRINT(" - procbased_ctls2.rdrand_exiting: %d\n", procbased_ctls2.rdrand_exiting);
- DBG_PRINT(" - procbased_ctls2.rdseed_exiting: %d\n", procbased_ctls2.rdseed_exiting);
- DBG_PRINT(" - procbased_ctls2.unrestricted_guest: %d\n", procbased_ctls2.unrestricted_guest);
- DBG_PRINT(" - procbased_ctls2.use_tsc_scaling: %d\n", procbased_ctls2.use_tsc_scaling);
- DBG_PRINT(" - procbased_ctls2.virtualize_apic_accesses: %d\n", procbased_ctls2.virtualize_apic_accesses);
- DBG_PRINT(" - procbased_ctls2.virtualize_x2apic_mode: %d\n", procbased_ctls2.virtualize_x2apic_mode);
- DBG_PRINT(" - procbased_ctls2.virtual_interrupt_delivery: %d\n", procbased_ctls2.virtual_interrupt_delivery);
- DBG_PRINT(" - procbased_ctls2.vmcs_shadowing: %d\n", procbased_ctls2.vmcs_shadowing);
- DBG_PRINT(" - procbased_ctls2.wbinvd_exiting: %d\n", procbased_ctls2.wbinvd_exiting);
- DBG_PRINT(" - procbased_ctls2.flags: 0x%x\n", procbased_ctls2.flags);
- DBG_PRINT(" - IA32_VMX_PROCBASED_CTLS2 high bits mask: 0x%x\n", msr_fix_value.allowed_1_settings);
- DBG_PRINT(" - IA32_VMX_PROCBASED_CTLS2 low bits mask: 0x%x\n", msr_fix_value.allowed_0_settings);
}
}
\ No newline at end of file
diff --git a/vmxexit_handler.asm b/vmxexit_handler.asm
index fb44c2d..6fb97ec 100644
--- a/vmxexit_handler.asm
+++ b/vmxexit_handler.asm
@@ -64,22 +64,22 @@ vmxexit_handler proc
call exit_handler
add rsp, 20h
- movaps xmm0, [rsp]
- movaps xmm1, [rsp + 010h]
- movaps xmm2, [rsp + 020h]
- movaps xmm3, [rsp + 030h]
- movaps xmm4, [rsp + 040h]
- movaps xmm5, [rsp + 050h]
- movaps xmm6, [rsp + 060h]
- movaps xmm7, [rsp + 070h]
- movaps xmm8, [rsp + 080h]
- movaps xmm9, [rsp + 090h]
- movaps xmm10, [rsp + 0A0h]
- movaps xmm11, [rsp + 0B0h]
- movaps xmm12, [rsp + 0C0h]
- movaps xmm13, [rsp + 0D0h]
- movaps xmm14, [rsp + 0E0h]
- movaps xmm15, [rsp + 0F0h]
+ movups xmm0, [rsp]
+ movups xmm1, [rsp + 010h]
+ movups xmm2, [rsp + 020h]
+ movups xmm3, [rsp + 030h]
+ movups xmm4, [rsp + 040h]
+ movups xmm5, [rsp + 050h]
+ movups xmm6, [rsp + 060h]
+ movups xmm7, [rsp + 070h]
+ movups xmm8, [rsp + 080h]
+ movups xmm9, [rsp + 090h]
+ movups xmm10, [rsp + 0A0h]
+ movups xmm11, [rsp + 0B0h]
+ movups xmm12, [rsp + 0C0h]
+ movups xmm13, [rsp + 0D0h]
+ movups xmm14, [rsp + 0E0h]
+ movups xmm15, [rsp + 0F0h]
add rsp, 0108h ; 16 xmm registers... and +8 bytes for alignment...
pop r15
@@ -95,6 +95,7 @@ vmxexit_handler proc
pop rsi
pop rdx
pop rcx
+ pop rbx
pop rax
vmresume