vmxlaunch is working... still some issues with host stack i think, need

to handle vmexits and shit now...
merge-requests/1/head
_xeroxz 4 years ago
parent 92915937de
commit c587c20e3f

@ -7,9 +7,13 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bluepill", "bluepill.vcxpro
EndProject EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
Release|x64 = Release|x64 Release|x64 = Release|x64
EndGlobalSection EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution 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}.Release|x64.ActiveCfg = Release|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.Build.0 = Release|x64
{881CCCA6-80EB-486F-8923-4F4B7DD41F9A}.Release|x64.Deploy.0 = Release|x64 {881CCCA6-80EB-486F-8923-4F4B7DD41F9A}.Release|x64.Deploy.0 = Release|x64

@ -1,6 +1,10 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations"> <ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64"> <ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration> <Configuration>Release</Configuration>
<Platform>x64</Platform> <Platform>x64</Platform>
@ -28,6 +32,16 @@
<Driver_SpectreMitigation>false</Driver_SpectreMitigation> <Driver_SpectreMitigation>false</Driver_SpectreMitigation>
<SpectreMitigation>false</SpectreMitigation> <SpectreMitigation>false</SpectreMitigation>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>Driver</ConfigurationType>
<DriverType>KMDF</DriverType>
<DriverTargetPlatform>Universal</DriverTargetPlatform>
<Driver_SpectreMitigation>false</Driver_SpectreMitigation>
<SpectreMitigation>false</SpectreMitigation>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings"> <ImportGroup Label="ExtensionSettings">
</ImportGroup> </ImportGroup>
@ -40,6 +54,10 @@
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor> <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
<EnableInf2cat>false</EnableInf2cat> <EnableInf2cat>false</EnableInf2cat>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
<EnableInf2cat>false</EnableInf2cat>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Link> <Link>
<TreatLinkerWarningAsErrors>false</TreatLinkerWarningAsErrors> <TreatLinkerWarningAsErrors>false</TreatLinkerWarningAsErrors>
@ -50,6 +68,17 @@
<TreatWarningAsError>false</TreatWarningAsError> <TreatWarningAsError>false</TreatWarningAsError>
</ClCompile> </ClCompile>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Link>
<TreatLinkerWarningAsErrors>false</TreatLinkerWarningAsErrors>
<EntryPointSymbol>driver_entry</EntryPointSymbol>
</Link>
<ClCompile>
<LanguageStandard>stdcpp17</LanguageStandard>
<TreatWarningAsError>false</TreatWarningAsError>
<PreprocessorDefinitions>DBG_PRINT_BOOL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
</ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
<FilesToPackage Include="$(TargetPath)" /> <FilesToPackage Include="$(TargetPath)" />
</ItemGroup> </ItemGroup>

@ -3,4 +3,7 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<SignMode>Off</SignMode> <SignMode>Off</SignMode>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<SignMode>Off</SignMode>
</PropertyGroup>
</Project> </Project>

@ -18,29 +18,18 @@ using s64 = long long;
extern "C" void _sgdt(void*); extern "C" void _sgdt(void*);
#pragma intrinsic(_sgdt); #pragma intrinsic(_sgdt);
#ifdef DBG_PRINT_BOOL
#define DBG_PRINT(format, ...) DbgPrintEx( DPFLTR_SYSTEM_ID, DPFLTR_ERROR_LEVEL, "[hv [core number = %d]]" format, KeGetCurrentProcessorNumber(), __VA_ARGS__)
#else
#define DBG_PRINT(format, ...)
#endif
#define DBG_PRINT(...) DbgPrintEx( DPFLTR_SYSTEM_ID, DPFLTR_ERROR_LEVEL, "[hv]" __VA_ARGS__)
#define HOST_STACK_PAGES 6 #define HOST_STACK_PAGES 6
namespace hv namespace hv
{ {
typedef struct _guest_registers typedef struct _guest_registers
{ {
u64 r15;
u64 r14;
u64 r13;
u64 r12;
u64 r11;
u64 r10;
u64 r9;
u64 r8;
u64 rbp;
u64 rdi;
u64 rsi;
u64 rdx;
u64 rcx;
u64 rax;
u128 xmm0; u128 xmm0;
u128 xmm1; u128 xmm1;
u128 xmm2; u128 xmm2;
@ -57,6 +46,21 @@ namespace hv
u128 xmm13; u128 xmm13;
u128 xmm14; u128 xmm14;
u128 xmm15; u128 xmm15;
u64 r15;
u64 r14;
u64 r13;
u64 r12;
u64 r11;
u64 r10;
u64 r9;
u64 r8;
u64 rbp;
u64 rdi;
u64 rsi;
u64 rdx;
u64 rcx;
u64 rax;
} guest_registers, * pguest_registers; } guest_registers, * pguest_registers;
union ia32_efer_t union ia32_efer_t

@ -18,20 +18,38 @@ namespace segment
auto get_info(segment_descriptor_register_64 gdt_value, segment_selector segment_selector) -> hv::segment_info_ctx auto get_info(segment_descriptor_register_64 gdt_value, segment_selector segment_selector) -> hv::segment_info_ctx
{ {
hv::segment_info_ctx segment_info; hv::segment_info_ctx segment_info;
// GDT->BaseAddress + (segment index << 3)
// gives us a pointer to the segment descriptor...
const auto segment_descriptor = const auto segment_descriptor =
reinterpret_cast<segment_descriptor_64*>( reinterpret_cast<segment_descriptor_64*>(
gdt_value.base_address + (segment_selector.index << SEGMENT_SELECTOR_INDEX_BIT)); gdt_value.base_address + (segment_selector.index << SEGMENT_SELECTOR_INDEX_BIT));
// access rights are spread out over the segment
// descriptor so those need to picked out and assigned
// to the vmx segment access rights variable...
segment_info.limit = __segmentlimit(segment_selector.flags); segment_info.limit = __segmentlimit(segment_selector.flags);
segment_info.rights = get_access_rights(segment_descriptor); segment_info.rights = get_access_rights(segment_descriptor);
segment_info.base_addr = (u32)((segment_descriptor->base_address_high << SEGMENT__BASE_ADDRESS_HIGH_BIT) | // base address of a segment is spread over the segment descriptor in 3 places. 2 parts of the
(segment_descriptor->base_address_middle << SEGMENT__BASE_ADDRESS_MIDDLE_BIT) | // address are 8 bits each (1 byte each) and the lowest part of the address is 2 bytes (4 bytes in total)...
// by shifting the values to the correct bit offset and adding them all together we get the address...
segment_info.base_addr = (u32)((segment_descriptor->base_address_high << SEGMENT__BASE_ADDRESS_HIGH_BIT) +
(segment_descriptor->base_address_middle << SEGMENT__BASE_ADDRESS_MIDDLE_BIT) +
(segment_descriptor->base_address_low)); (segment_descriptor->base_address_low));
segment_info.base_addr &= 0xFFFFFFFF; // Example:
// - high bits: 0b1111 0000 0000 0000
// - middle bits: 0b0000 1111 0000 0000
// - low bits: 0b0000 0000 1011 1000
// --------------------- +
// 0b1111 1111 1011 1000 <==== full address...
// if you add all of these together you will get the full address...
// if the base address is 64bits then go ahead
// and add the top 32bits onto the address..
if (!segment_descriptor->descriptor_type) if (!segment_descriptor->descriptor_type)
segment_info.base_addr |= ((u64)segment_descriptor->base_address_upper << SEGMENT__BASE_ADDRESS_SHIFT); segment_info.base_addr += ((u64)segment_descriptor->base_address_upper << SEGMENT__BASE_ADDRESS_SHIFT);
return segment_info; return segment_info;
} }

@ -10,12 +10,14 @@ namespace vmcs
__sidt(&idt_value); __sidt(&idt_value);
_sgdt(&gdt_value); _sgdt(&gdt_value);
// use guest values for now... later on CR3 will be custom...
__vmx_vmwrite(VMCS_HOST_CR0, __readcr0()); __vmx_vmwrite(VMCS_HOST_CR0, __readcr0());
__vmx_vmwrite(VMCS_HOST_CR3, __readcr3()); __vmx_vmwrite(VMCS_HOST_CR3, __readcr3());
__vmx_vmwrite(VMCS_HOST_CR4, __readcr4()); __vmx_vmwrite(VMCS_HOST_CR4, __readcr4());
// stack growns down...
__vmx_vmwrite(VMCS_HOST_RSP, host_rsp + (PAGE_SIZE * HOST_STACK_PAGES) - 8);
__vmx_vmwrite(VMCS_HOST_RIP, reinterpret_cast<u64>(host_rip)); __vmx_vmwrite(VMCS_HOST_RIP, reinterpret_cast<u64>(host_rip));
__vmx_vmwrite(VMCS_HOST_RSP, host_rsp);
__vmx_vmwrite(VMCS_HOST_SYSENTER_CS, __readmsr(IA32_SYSENTER_CS)); __vmx_vmwrite(VMCS_HOST_SYSENTER_CS, __readmsr(IA32_SYSENTER_CS));
__vmx_vmwrite(VMCS_HOST_SYSENTER_EIP, __readmsr(IA32_SYSENTER_EIP)); __vmx_vmwrite(VMCS_HOST_SYSENTER_EIP, __readmsr(IA32_SYSENTER_EIP));
@ -24,13 +26,43 @@ namespace vmcs
__vmx_vmwrite(VMCS_HOST_GDTR_BASE, gdt_value.base_address); __vmx_vmwrite(VMCS_HOST_GDTR_BASE, gdt_value.base_address);
__vmx_vmwrite(VMCS_HOST_IDTR_BASE, idt_value.base_address); __vmx_vmwrite(VMCS_HOST_IDTR_BASE, idt_value.base_address);
__vmx_vmwrite(VMCS_HOST_ES_SELECTOR, reades()); // manual says that the priv level must be 0 and
__vmx_vmwrite(VMCS_HOST_CS_SELECTOR, readcs()); // that the table flag also needs to be 0 so it uses the GDT...
__vmx_vmwrite(VMCS_HOST_DS_SELECTOR, readds()); segment_selector es{ reades() };
__vmx_vmwrite(VMCS_HOST_FS_SELECTOR, readfs()); es.request_privilege_level = NULL;
__vmx_vmwrite(VMCS_HOST_GS_SELECTOR, readgs()); es.table = NULL;
__vmx_vmwrite(VMCS_HOST_SS_SELECTOR, readss());
__vmx_vmwrite(VMCS_HOST_TR_SELECTOR, readtr()); segment_selector cs{ readcs() };
cs.request_privilege_level = NULL;
cs.table = NULL;
segment_selector ds{ readds() };
ds.request_privilege_level = NULL;
ds.table = NULL;
segment_selector fs{ readfs() };
fs.request_privilege_level = NULL;
fs.table = NULL;
segment_selector gs{ readgs() };
gs.request_privilege_level = NULL;
gs.table = NULL;
segment_selector ss{ readss() };
ss.request_privilege_level = NULL;
ss.table = NULL;
segment_selector tr{ readtr() };
tr.request_privilege_level = NULL;
tr.table = NULL;
__vmx_vmwrite(VMCS_HOST_ES_SELECTOR, es.flags);
__vmx_vmwrite(VMCS_HOST_CS_SELECTOR, cs.flags);
__vmx_vmwrite(VMCS_HOST_DS_SELECTOR, ds.flags);
__vmx_vmwrite(VMCS_HOST_FS_SELECTOR, fs.flags);
__vmx_vmwrite(VMCS_HOST_GS_SELECTOR, gs.flags);
__vmx_vmwrite(VMCS_HOST_SS_SELECTOR, ss.flags);
__vmx_vmwrite(VMCS_HOST_TR_SELECTOR, tr.flags);
__vmx_vmwrite(VMCS_HOST_GS_BASE, __readmsr(IA32_GS_BASE)); __vmx_vmwrite(VMCS_HOST_GS_BASE, __readmsr(IA32_GS_BASE));
__vmx_vmwrite(VMCS_HOST_FS_BASE, __readmsr(IA32_FS_BASE)); __vmx_vmwrite(VMCS_HOST_FS_BASE, __readmsr(IA32_FS_BASE));
@ -157,25 +189,91 @@ namespace vmcs
pinbased_ctls.flags |= msr_fix_value.allowed_0_settings; pinbased_ctls.flags |= msr_fix_value.allowed_0_settings;
__vmx_vmwrite(VMCS_CTRL_PIN_BASED_VM_EXECUTION_CONTROLS, pinbased_ctls.flags); __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); 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_1_settings;
procbased_ctls.flags |= msr_fix_value.allowed_0_settings; procbased_ctls.flags |= msr_fix_value.allowed_0_settings;
procbased_ctls.activate_secondary_controls = true;
__vmx_vmwrite(VMCS_CTRL_PROCESSOR_BASED_VM_EXECUTION_CONTROLS, procbased_ctls.flags); __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); msr_fix_value.flags = __readmsr(IA32_VMX_TRUE_ENTRY_CTLS);
entry_ctls.ia32e_mode_guest = true;
entry_ctls.flags &= msr_fix_value.allowed_1_settings; entry_ctls.flags &= msr_fix_value.allowed_1_settings;
entry_ctls.flags |= msr_fix_value.allowed_0_settings; entry_ctls.flags |= msr_fix_value.allowed_0_settings;
entry_ctls.ia32e_mode_guest = true;
entry_ctls.conceal_vmx_from_pt = true;
__vmx_vmwrite(VMCS_CTRL_VMENTRY_CONTROLS, entry_ctls.flags); __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); 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_1_settings;
exit_ctls.flags |= msr_fix_value.allowed_0_settings; exit_ctls.flags |= msr_fix_value.allowed_0_settings;
exit_ctls.host_address_space_size = true;
exit_ctls.conceal_vmx_from_pt = true;
__vmx_vmwrite(VMCS_CTRL_VMEXIT_CONTROLS, exit_ctls.flags); __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 else
{ {
@ -184,33 +282,129 @@ namespace vmcs
pinbased_ctls.flags |= msr_fix_value.allowed_0_settings; pinbased_ctls.flags |= msr_fix_value.allowed_0_settings;
__vmx_vmwrite(VMCS_CTRL_PIN_BASED_VM_EXECUTION_CONTROLS, pinbased_ctls.flags); __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); 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_1_settings;
procbased_ctls.flags |= msr_fix_value.allowed_0_settings; procbased_ctls.flags |= msr_fix_value.allowed_0_settings;
procbased_ctls.activate_secondary_controls = true;
__vmx_vmwrite(VMCS_CTRL_PROCESSOR_BASED_VM_EXECUTION_CONTROLS, procbased_ctls.flags); __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); msr_fix_value.flags = __readmsr(IA32_VMX_ENTRY_CTLS);
entry_ctls.flags &= msr_fix_value.allowed_1_settings;
entry_ctls.flags |= msr_fix_value.allowed_0_settings;
entry_ctls.ia32e_mode_guest = true; entry_ctls.ia32e_mode_guest = true;
entry_ctls.conceal_vmx_from_pt = true; entry_ctls.conceal_vmx_from_pt = true;
entry_ctls.flags &= msr_fix_value.allowed_1_settings;
entry_ctls.flags |= msr_fix_value.allowed_0_settings;
__vmx_vmwrite(VMCS_CTRL_VMENTRY_CONTROLS, entry_ctls.flags); __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); msr_fix_value.flags = __readmsr(IA32_VMX_EXIT_CTLS);
exit_ctls.flags &= msr_fix_value.allowed_1_settings;
exit_ctls.flags |= msr_fix_value.allowed_0_settings;
exit_ctls.host_address_space_size = true; exit_ctls.host_address_space_size = true;
exit_ctls.conceal_vmx_from_pt = 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); __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); msr_fix_value.flags = __readmsr(IA32_VMX_PROCBASED_CTLS2);
procbased_ctls2.enable_rdtscp = true;
procbased_ctls2.enable_xsaves = true; // although my xeons dont support xsave... other cpus do!
procbased_ctls2.conceal_vmx_from_pt = true; // although my xeons dont support processor tracing... other cpus do!
procbased_ctls2.flags &= msr_fix_value.allowed_1_settings; procbased_ctls2.flags &= msr_fix_value.allowed_1_settings;
procbased_ctls2.flags |= msr_fix_value.allowed_0_settings; procbased_ctls2.flags |= msr_fix_value.allowed_0_settings;
procbased_ctls2.enable_rdtscp = true;
procbased_ctls2.enable_xsaves = true;
procbased_ctls2.conceal_vmx_from_pt = true;
__vmx_vmwrite(VMCS_CTRL_SECONDARY_PROCESSOR_BASED_VM_EXECUTION_CONTROLS, procbased_ctls2.flags); __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);
} }
} }

@ -10,7 +10,6 @@ vmxexit_handler proc
push rsi push rsi
push rdi push rdi
push rbp push rbp
push rbp ; gotta keep the stack aligned...
push r8 push r8
push r9 push r9
push r10 push r10
@ -69,7 +68,6 @@ vmxexit_handler proc
pop r10 pop r10
pop r9 pop r9
pop r8 pop r8
pop rbp ; gotta keep the stack aligned...
pop rbp pop rbp
pop rdi pop rdi
pop rsi pop rsi

@ -72,11 +72,17 @@ namespace vmxon
reinterpret_cast<hv::pvcpu_ctx>( reinterpret_cast<hv::pvcpu_ctx>(
ExAllocatePool(NonPagedPool, sizeof hv::vcpu_ctx)); ExAllocatePool(NonPagedPool, sizeof hv::vcpu_ctx));
// allocate host stack...
vmx_ctx->vcpus[idx]->host_stack = vmx_ctx->vcpus[idx]->host_stack =
reinterpret_cast<u64>( reinterpret_cast<u64>(
ExAllocatePool(NonPagedPool, ExAllocatePool(NonPagedPool,
PAGE_SIZE * HOST_STACK_PAGES)); PAGE_SIZE * HOST_STACK_PAGES));
// zero host stack...
RtlZeroMemory(reinterpret_cast<void*>(
vmx_ctx->vcpus[idx]->host_stack), PAGE_SIZE * HOST_STACK_PAGES);
// setup VMCS and VMXON region...
create_vmxon_region(vmx_ctx->vcpus[idx]); create_vmxon_region(vmx_ctx->vcpus[idx]);
create_vmcs(vmx_ctx->vcpus[idx]); create_vmcs(vmx_ctx->vcpus[idx]);
@ -85,6 +91,7 @@ namespace vmxon
DBG_PRINT(" - vmxon region (physical): 0x%p\n", vmx_ctx->vcpus[idx]->vmxon_phys); DBG_PRINT(" - vmxon region (physical): 0x%p\n", vmx_ctx->vcpus[idx]->vmxon_phys);
DBG_PRINT(" - vmcs (virtual): 0x%p\n", vmx_ctx->vcpus[idx]->vmcs); DBG_PRINT(" - vmcs (virtual): 0x%p\n", vmx_ctx->vcpus[idx]->vmcs);
DBG_PRINT(" - vmcs (physical): 0x%p\n", vmx_ctx->vcpus[idx]->vmcs_phys); DBG_PRINT(" - vmcs (physical): 0x%p\n", vmx_ctx->vcpus[idx]->vmcs_phys);
DBG_PRINT(" - host stack: 0x%p\n", vmx_ctx->vcpus[idx]->host_stack);
} }
} }
@ -95,7 +102,7 @@ namespace vmxon
hv::cr0_t cr0 = { 0 }; hv::cr0_t cr0 = { 0 };
hv::cr4_t cr4 = { 0 }; hv::cr4_t cr4 = { 0 };
// should check to see if this is locked or not... // TODO: should check to see if this is locked or not...
feature_msr.control = __readmsr(IA32_FEATURE_CONTROL); feature_msr.control = __readmsr(IA32_FEATURE_CONTROL);
feature_msr.bits.vmxon_outside_smx = true; feature_msr.bits.vmxon_outside_smx = true;
feature_msr.bits.lock = true; feature_msr.bits.lock = true;
@ -117,14 +124,17 @@ namespace vmxon
cr4.flags &= cr_fixed.split.low; cr4.flags &= cr_fixed.split.low;
__writecr4(cr4.flags); __writecr4(cr4.flags);
// enable vmx instructions on this core...
cr4.flags = __readcr4(); cr4.flags = __readcr4();
cr4.vmx_enable = true; cr4.vmx_enable = true;
__writecr4(cr4.flags); __writecr4(cr4.flags);
DBG_PRINT("vmxon for processor: %d\n", KeGetCurrentProcessorNumber()); const auto vmxon_result =
DBG_PRINT(" - vmxon result (0 == success): %d\n",
__vmx_on((unsigned long long*) __vmx_on((unsigned long long*)
&vmxon::g_vmx_ctx->vcpus[ &vmxon::g_vmx_ctx->vcpus[
KeGetCurrentProcessorNumber()]->vmxon_phys)); KeGetCurrentProcessorNumber()]->vmxon_phys);
DBG_PRINT("vmxon for processor: %d\n", KeGetCurrentProcessorNumber());
DBG_PRINT(" - vmxon result (0 == success): %d\n", vmxon_result);
} }
} }
Loading…
Cancel
Save