diff options
author | ionescu007 <aionescu+git@gmail.com> | 2016-08-29 23:51:13 +0300 |
---|---|---|
committer | ionescu007 <aionescu+git@gmail.com> | 2016-08-29 23:51:13 +0300 |
commit | 2bc0a27d447902930ed725269a35a96a3d32f562 (patch) | |
tree | d770592451aafabe2f130a0855c087cf58890bf0 | |
parent | f35f5b35bf3dfda2b65b92ccf47a2e7953351563 (diff) |
Move to what should be much more portable types. Fix straggler NT-specific APIs.
SimpleVisor no longer builds with NT headers -- instead, ntint.h
provides the necessary NT"isms" and compiler definitions.
Create a bridge header (shv_x.h) between the OS layer and SimpleVisor
layer.
ShvOs.c builds with the NT Headers, and don't use ntint.h, importing
only shv_x.h
-rw-r--r-- | ntint.h | 176 | ||||
-rw-r--r-- | shv.c | 10 | ||||
-rw-r--r-- | shv.h | 113 | ||||
-rw-r--r-- | shv.vcxproj | 1 | ||||
-rw-r--r-- | shv_x.h | 106 | ||||
-rw-r--r-- | shvos.c | 94 | ||||
-rw-r--r-- | shvutil.c | 12 | ||||
-rw-r--r-- | shvvmx.c | 22 | ||||
-rw-r--r-- | shvvmxhv.c | 14 | ||||
-rw-r--r-- | shvvp.c | 24 | ||||
-rw-r--r-- | vmx.h | 114 |
11 files changed, 473 insertions, 213 deletions
@@ -22,9 +22,6 @@ Environment: #pragma once -// -// Definitions from ntosp.h -// #define DPL_USER 3 #define DPL_SYSTEM 0 #define KGDT64_NULL 0x00 @@ -41,52 +38,171 @@ Environment: #define RPL_MASK 3 #define MTRR_TYPE_WB 6 #define EFLAGS_ALIGN_CHECK 0x40000 +#define PAGE_SIZE 4096 +#define KERNEL_STACK_SIZE 24 * 1024 + +#define VOID void +#define DECLSPEC_ALIGN(x) __declspec(align(x)) +#define DECLSPEC_NORETURN __declspec(noreturn) +#define FORCEINLINE __forceinline +#define C_ASSERT(x) static_assert(x, "Error") +#define FIELD_OFFSET offsetof +#define TRUE 1 +#define FALSE 0 +#define UNREFERENCED_PARAMETER(x) (x) -// -// Structures from ntosp.h -// typedef struct _KDESCRIPTOR { - USHORT Pad[3]; - USHORT Limit; - PVOID Base; + UINT16 Pad[3]; + UINT16 Limit; + void* Base; } KDESCRIPTOR, *PKDESCRIPTOR; typedef union _KGDTENTRY64 { struct { - USHORT LimitLow; - USHORT BaseLow; + UINT16 LimitLow; + UINT16 BaseLow; union { struct { - UCHAR BaseMiddle; - UCHAR Flags1; - UCHAR Flags2; - UCHAR BaseHigh; + UINT8 BaseMiddle; + UINT8 Flags1; + UINT8 Flags2; + UINT8 BaseHigh; } Bytes; struct { - ULONG BaseMiddle : 8; - ULONG Type : 5; - ULONG Dpl : 2; - ULONG Present : 1; - ULONG LimitHigh : 4; - ULONG System : 1; - ULONG LongMode : 1; - ULONG DefaultBig : 1; - ULONG Granularity : 1; - ULONG BaseHigh : 8; + UINT32 BaseMiddle : 8; + UINT32 Type : 5; + UINT32 Dpl : 2; + UINT32 Present : 1; + UINT32 LimitHigh : 4; + UINT32 System : 1; + UINT32 LongMode : 1; + UINT32 DefaultBig : 1; + UINT32 Granularity : 1; + UINT32 BaseHigh : 8; } Bits; }; - ULONG BaseUpper; - ULONG MustBeZero; + UINT32 BaseUpper; + UINT32 MustBeZero; }; struct { - LONG64 DataLow; - LONG64 DataHigh; + INT64 DataLow; + INT64 DataHigh; }; - } KGDTENTRY64, *PKGDTENTRY64; + +typedef struct DECLSPEC_ALIGN(16) _M128A +{ + UINT64 Low; + INT64 High; +} M128A, *PM128A; + +typedef struct DECLSPEC_ALIGN(16) _XSAVE_FORMAT +{ + UINT16 ControlWord; + UINT16 StatusWord; + UINT8 TagWord; + UINT8 Reserved1; + UINT16 ErrorOpcode; + UINT32 ErrorOffset; + UINT16 ErrorSelector; + UINT16 Reserved2; + UINT32 DataOffset; + UINT16 DataSelector; + UINT16 Reserved3; + UINT32 MxCsr; + UINT32 MxCsr_Mask; + M128A FloatRegisters[8]; + M128A XmmRegisters[16]; + UINT8 Reserved4[96]; +} XSAVE_FORMAT, *PXSAVE_FORMAT; +typedef XSAVE_FORMAT XMM_SAVE_AREA32, *PXMM_SAVE_AREA32; + +typedef struct DECLSPEC_ALIGN(16) _CONTEXT +{ + UINT64 P1Home; + UINT64 P2Home; + UINT64 P3Home; + UINT64 P4Home; + UINT64 P5Home; + UINT64 P6Home; + UINT32 ContextFlags; + UINT32 MxCsr; + UINT16 SegCs; + UINT16 SegDs; + UINT16 SegEs; + UINT16 SegFs; + UINT16 SegGs; + UINT16 SegSs; + UINT32 EFlags; + UINT64 Dr0; + UINT64 Dr1; + UINT64 Dr2; + UINT64 Dr3; + UINT64 Dr6; + UINT64 Dr7; + UINT64 Rax; + UINT64 Rcx; + UINT64 Rdx; + UINT64 Rbx; + UINT64 Rsp; + UINT64 Rbp; + UINT64 Rsi; + UINT64 Rdi; + UINT64 R8; + UINT64 R9; + UINT64 R10; + UINT64 R11; + UINT64 R12; + UINT64 R13; + UINT64 R14; + UINT64 R15; + UINT64 Rip; + union + { + XMM_SAVE_AREA32 FltSave; + struct + { + M128A Header[2]; + M128A Legacy[8]; + M128A Xmm0; + M128A Xmm1; + M128A Xmm2; + M128A Xmm3; + M128A Xmm4; + M128A Xmm5; + M128A Xmm6; + M128A Xmm7; + M128A Xmm8; + M128A Xmm9; + M128A Xmm10; + M128A Xmm11; + M128A Xmm12; + M128A Xmm13; + M128A Xmm14; + M128A Xmm15; + }; + }; + M128A VectorRegister[26]; + ULONG64 VectorControl; + ULONG64 DebugControl; + ULONG64 LastBranchToRip; + ULONG64 LastBranchFromRip; + ULONG64 LastExceptionToRip; + ULONG64 LastExceptionFromRip; +} CONTEXT, *PCONTEXT; + +typedef union _LARGE_INTEGER +{ + struct + { + UINT32 LowPart; + INT32 HighPart; + }; + UINT64 QuadPart; +} LARGE_INTEGER, *PLARGE_INTEGER; @@ -43,13 +43,12 @@ ShvUnload ( ShvOsDebugPrint("The SHV has been uninstalled.\n"); } -NTSTATUS +INT32 ShvLoad ( VOID ) { SHV_CALLBACK_CONTEXT callbackContext; - ULONG cpuCount; // // Attempt to enter VMX root mode on all logical processors. This will @@ -59,7 +58,7 @@ ShvLoad ( // should be executing in. // callbackContext.Cr3 = __readcr3(); - callbackContext.FailureStatus = STATUS_SUCCESS; + callbackContext.FailureStatus = SHV_STATUS_SUCCESS; callbackContext.FailedCpu = -1; callbackContext.InitCount = 0; ShvOsRunCallbackOnProcessors(ShvVpLoadCallback, &callbackContext); @@ -70,8 +69,7 @@ ShvLoad ( // // Note that each VP is responsible for freeing its VP data on failure. // - cpuCount = KeQueryActiveProcessorCountEx(ALL_PROCESSOR_GROUPS); - if (callbackContext.InitCount != cpuCount) + if (callbackContext.InitCount != ShvOsGetActiveProcessorCount()) { ShvOsDebugPrint("The SHV failed to initialize (0x%lX) Failed CPU: %d\n", callbackContext.FailureStatus, callbackContext.FailedCpu); @@ -82,5 +80,5 @@ ShvLoad ( // Indicate success. // ShvOsDebugPrint("The SHV has been installed.\n"); - return STATUS_SUCCESS; + return SHV_STATUS_SUCCESS; } @@ -12,7 +12,7 @@ Abstract: Author: - Alex Ionescu (@aionescu) 16-Mar-2016 - Initial version + Alex Ionescu (@aionescu) 14-Mar-2016 - Initial version Environment: @@ -23,21 +23,23 @@ Environment: #pragma once #pragma warning(disable:4201) #pragma warning(disable:4214) -#include <ntifs.h> + #include <intrin.h> +#include <basetsd.h> #include "ntint.h" #include "vmx.h" +#include "shv_x.h" typedef struct _SHV_SPECIAL_REGISTERS { - ULONG64 Cr0; - ULONG64 Cr3; - ULONG64 Cr4; - ULONG64 MsrGsBase; - USHORT Tr; - USHORT Ldtr; - ULONG64 DebugControl; - ULONG64 KernelDr7; + UINT64 Cr0; + UINT64 Cr3; + UINT64 Cr4; + UINT64 MsrGsBase; + UINT16 Tr; + UINT16 Ldtr; + UINT64 DebugControl; + UINT64 KernelDr7; KDESCRIPTOR Idtr; KDESCRIPTOR Gdtr; } SHV_SPECIAL_REGISTERS, *PSHV_SPECIAL_REGISTERS; @@ -46,21 +48,21 @@ typedef struct _SHV_VP_DATA { union { - DECLSPEC_ALIGN(PAGE_SIZE) UCHAR ShvStackLimit[KERNEL_STACK_SIZE]; + DECLSPEC_ALIGN(PAGE_SIZE) UINT8 ShvStackLimit[KERNEL_STACK_SIZE]; struct { SHV_SPECIAL_REGISTERS SpecialRegisters; CONTEXT ContextFrame; - ULONG64 SystemDirectoryTableBase; + UINT64 SystemDirectoryTableBase; LARGE_INTEGER MsrData[17]; - ULONGLONG VmxOnPhysicalAddress; - ULONGLONG VmcsPhysicalAddress; - ULONGLONG MsrBitmapPhysicalAddress; - ULONGLONG EptPml4PhysicalAddress; + UINT64 VmxOnPhysicalAddress; + UINT64 VmcsPhysicalAddress; + UINT64 MsrBitmapPhysicalAddress; + UINT64 EptPml4PhysicalAddress; }; }; - DECLSPEC_ALIGN(PAGE_SIZE) UCHAR MsrBitmap[PAGE_SIZE]; + DECLSPEC_ALIGN(PAGE_SIZE) UINT8 MsrBitmap[PAGE_SIZE]; DECLSPEC_ALIGN(PAGE_SIZE) VMX_EPML4E Epml4[PML4E_ENTRY_COUNT]; DECLSPEC_ALIGN(PAGE_SIZE) VMX_HUGE_PDPTE Epdpt[PDPTE_ENTRY_COUNT]; @@ -78,49 +80,35 @@ typedef struct _SHV_VP_STATE ULONG_PTR GuestRip; ULONG_PTR GuestRsp; ULONG_PTR GuestEFlags; - USHORT ExitReason; - BOOLEAN ExitVm; + UINT16 ExitReason; + UINT8 ExitVm; } SHV_VP_STATE, *PSHV_VP_STATE; -typedef struct _SHV_CALLBACK_CONTEXT -{ - ULONG64 Cr3; - volatile ULONG InitCount; - LONG FailedCpu; - NTSTATUS FailureStatus; -} SHV_CALLBACK_CONTEXT, *PSHV_CALLBACK_CONTEXT; - -typedef -VOID -SHV_CPU_CALLBACK ( - _In_ PSHV_CALLBACK_CONTEXT Context - ); -typedef SHV_CPU_CALLBACK *PSHV_CPU_CALLBACK; VOID ShvVmxEntry ( VOID ); -VOID +VOID ShvVmxCleanup ( - _In_ USHORT Data, - _In_ USHORT Teb + _In_ UINT16 Data, + _In_ UINT16 Teb ); VOID _sldt ( - _In_ PUSHORT Ldtr + _In_ PUINT16 Ldtr ); VOID _str ( - _In_ PUSHORT Tr + _In_ PUINT16 Tr ); VOID __lgdt ( - _In_ PVOID Gdtr + _In_ VOID* Gdtr ); VOID @@ -130,15 +118,15 @@ ShvVmxLaunchOnVp ( VOID ShvUtilConvertGdtEntry ( - _In_ PVOID GdtBase, - _In_ USHORT Offset, + _In_ VOID* GdtBase, + _In_ UINT16 Offset, _Out_ PVMX_GDTENTRY64 VmxGdtEntry ); -ULONG +UINT32 ShvUtilAdjustMsr ( _In_ LARGE_INTEGER ControlValue, - _In_ ULONG DesiredValue + _In_ UINT32 DesiredValue ); PSHV_VP_DATA @@ -146,7 +134,7 @@ ShvVpAllocateGlobalData ( VOID ); -BOOLEAN +UINT8 ShvVmxProbe ( VOID ); @@ -156,48 +144,11 @@ ShvVmxEptInitialize ( _In_ PSHV_VP_DATA VpData ); -NTSTATUS -ShvLoad ( - VOID - ); - -VOID -ShvUnload ( - VOID - ); - -DECLSPEC_NORETURN -VOID -__cdecl -ShvOsRestoreContext ( - _In_ PCONTEXT ContextRecord - ); - -VOID -ShvOsFreeContiguousAlignedMemory ( - _In_ PVOID BaseAddress - ); - -PVOID -ShvOsAllocateContigousAlignedMemory ( - _In_ SIZE_T Size - ); - DECLSPEC_NORETURN VOID ShvVpRestoreAfterLaunch ( VOID ); -VOID -ShvOsRunCallbackOnProcessors ( - _In_ PSHV_CPU_CALLBACK Routine, - _In_opt_ PVOID Context - ); - -SHV_CPU_CALLBACK ShvVpLoadCallback; -SHV_CPU_CALLBACK ShvVpUnloadCallback; - extern PSHV_VP_DATA* ShvGlobalData; -#define ShvOsDebugPrint(format, ...) DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, format, __VA_ARGS__) diff --git a/shv.vcxproj b/shv.vcxproj index 96471bd..b70bb57 100644 --- a/shv.vcxproj +++ b/shv.vcxproj @@ -65,6 +65,7 @@ <ItemGroup> <ClInclude Include="shv.h" /> <ClInclude Include="ntint.h" /> + <ClInclude Include="shv_x.h" /> <ClInclude Include="vmx.h" /> </ItemGroup> <ItemGroup> @@ -0,0 +1,106 @@ +/*++ + +Copyright (c) Alex Ionescu. All rights reserved. + +Header Name: + + shv_x.h + +Abstract: + + This header defines the externally visible structures and functions of the + Simple Hyper Visor which are visible between the OS layer and SimpleVisor. + +Author: + + Alex Ionescu (@aionescu) 29-Aug-2016 - Initial version + +Environment: + + Kernel mode only. + +--*/ + +#pragma once + +#define SHV_STATUS_SUCCESS 0 +#define SHV_STATUS_NOT_AVAILABLE -1 +#define SHV_STATUS_NO_RESOURCES -2 +#define SHV_STATUS_NOT_PRESENT -3 + +typedef struct _SHV_CALLBACK_CONTEXT +{ + ULONG64 Cr3; + volatile long InitCount; + INT32 FailedCpu; + INT32 FailureStatus; +} SHV_CALLBACK_CONTEXT, *PSHV_CALLBACK_CONTEXT; + +typedef +void +SHV_CPU_CALLBACK ( + _In_ PSHV_CALLBACK_CONTEXT Context + ); +typedef SHV_CPU_CALLBACK *PSHV_CPU_CALLBACK; + +DECLSPEC_NORETURN +VOID +__cdecl +ShvOsRestoreContext ( + _In_ PCONTEXT ContextRecord + ); + +VOID +ShvOsCaptureContext ( + _In_ PCONTEXT ContextRecord + ); + +INT32 +ShvOsGetActiveProcessorCount ( + VOID + ); + +INT32 +ShvOsGetCurrentProcessorNumber ( + VOID + ); + +VOID +ShvOsFreeContiguousAlignedMemory ( + _In_ VOID* BaseAddress + ); + +VOID* +ShvOsAllocateContigousAlignedMemory ( + _In_ SIZE_T Size + ); + +UINT64 +ShvOsGetPhysicalAddress ( + _In_ VOID* BaseAddress + ); + +VOID +ShvOsDebugPrint ( + _In_ const char* Format, + ... + ); + +VOID +ShvOsRunCallbackOnProcessors ( + _In_ PSHV_CPU_CALLBACK Routine, + _In_opt_ VOID* Context + ); + +INT32 +ShvLoad ( + VOID + ); + +VOID +ShvUnload ( + VOID + ); + +SHV_CPU_CALLBACK ShvVpLoadCallback; +SHV_CPU_CALLBACK ShvVpUnloadCallback; @@ -20,7 +20,9 @@ Environment: --*/ -#include "shv.h" +#include <ntifs.h> +#include <varargs.h> +#include "shv_x.h" NTKERNELAPI _IRQL_requires_max_(APC_LEVEL) @@ -63,6 +65,34 @@ typedef struct _SHV_DPC_CONTEXT PSHV_CALLBACK_CONTEXT Context; } SHV_DPC_CONTEXT, *PSHV_DPC_CONTEXT; +NTSTATUS +FORCEINLINE +ShvOsErrorToError ( + INT32 Error + ) +{ + // + // Convert the possible SimpleVisor errors into NT Hyper-V Errors + // + if (Error == SHV_STATUS_NOT_AVAILABLE) + { + return STATUS_HV_FEATURE_UNAVAILABLE; + } + if (Error == SHV_STATUS_NO_RESOURCES) + { + return STATUS_HV_NO_RESOURCES; + } + if (Error == SHV_STATUS_NOT_PRESENT) + { + return STATUS_HV_NOT_PRESENT; + } + + // + // Unknown/unexpected error + // + return STATUS_UNSUCCESSFUL; +} + VOID ShvOsDpcRoutine ( _In_ struct _KDPC *Dpc, @@ -126,6 +156,17 @@ ShvOsAllocateContigousAlignedMemory ( KeGetCurrentNodeNumber()); } +ULONGLONG +ShvOsGetPhysicalAddress ( + _In_ PVOID BaseAddress + ) +{ + // + // Let the memory manager convert it + // + return MmGetPhysicalAddress(BaseAddress).QuadPart; +} + VOID ShvOsRunCallbackOnProcessors ( _In_ PSHV_CPU_CALLBACK Routine, @@ -156,6 +197,55 @@ ShvOsRestoreContext ( } VOID +ShvOsCaptureContext ( + _In_ PCONTEXT ContextRecord + ) +{ + // + // Windows provides a nice OS function to do this + // + RtlCaptureContext(ContextRecord); +} + +INT32 +ShvOsGetCurrentProcessorNumber ( + VOID + ) +{ + // + // Get the group-wide CPU index + // + return (INT32)KeGetCurrentProcessorNumberEx(NULL); +} + +INT32 +ShvOsGetActiveProcessorCount ( + VOID + ) +{ + // + // Get the group-wide CPU count + // + return (INT32)KeQueryActiveProcessorCountEx(ALL_PROCESSOR_GROUPS); +} + +VOID +ShvOsDebugPrint ( + _In_ PCCH Format, + ... + ) +{ + va_list arglist; + + // + // Call the debugger API + // + va_start(arglist); + vDbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, Format, arglist); + va_end(arglist); +} + +VOID DriverUnload ( _In_ PDRIVER_OBJECT DriverObject ) @@ -184,6 +274,6 @@ DriverEntry ( // // Load the hypervisor // - return ShvLoad(); + return ShvOsErrorToError(ShvLoad()); } @@ -24,8 +24,8 @@ Environment: VOID ShvUtilConvertGdtEntry ( - _In_ PVOID GdtBase, - _In_ USHORT Selector, + _In_ VOID* GdtBase, + _In_ UINT16 Selector, _Out_ PVMX_GDTENTRY64 VmxGdtEntry ) { @@ -36,7 +36,7 @@ ShvUtilConvertGdtEntry ( // Windows does not use an LDT for these selectors in kernel, so the TI bit // should never be set. // - gdtEntry = (PKGDTENTRY64)((ULONG_PTR)GdtBase + (Selector & ~RPL_MASK)); + gdtEntry = (PKGDTENTRY64)((UINT_PTR)GdtBase + (Selector & ~RPL_MASK)); // // Write the selector directly @@ -59,7 +59,7 @@ ShvUtilConvertGdtEntry ( // VmxGdtEntry->Base = ((gdtEntry->Bytes.BaseHigh << 24) | (gdtEntry->Bytes.BaseMiddle << 16) | - (gdtEntry->BaseLow)) & MAXULONG; + (gdtEntry->BaseLow)) & MAXUINT32; VmxGdtEntry->Base |= ((gdtEntry->Bits.Type & 0x10) == 0) ? ((ULONG_PTR)gdtEntry->BaseUpper << 32) : 0; @@ -77,10 +77,10 @@ ShvUtilConvertGdtEntry ( VmxGdtEntry->Bits.Unusable = !gdtEntry->Bits.Present; } -ULONG +UINT32 ShvUtilAdjustMsr ( _In_ LARGE_INTEGER ControlValue, - _In_ ULONG DesiredValue + _In_ UINT32 DesiredValue ) { // @@ -27,7 +27,7 @@ ShvVmxEptInitialize ( _In_ PSHV_VP_DATA VpData ) { - ULONGLONG i; + UINT64 i; VMX_HUGE_PDPTE tempEpdpte; // @@ -36,7 +36,7 @@ ShvVmxEptInitialize ( VpData->Epml4[0].Read = 1; VpData->Epml4[0].Write = 1; VpData->Epml4[0].Execute = 1; - VpData->Epml4[0].PageFrameNumber = MmGetPhysicalAddress(&VpData->Epdpt).QuadPart / PAGE_SIZE; + VpData->Epml4[0].PageFrameNumber = ShvOsGetPhysicalAddress(&VpData->Epdpt) / PAGE_SIZE; // // Fill out a RWX Write-back 1GB EPDPTE @@ -53,7 +53,7 @@ ShvVmxEptInitialize ( for (i = 0; i < PDPTE_ENTRY_COUNT; i++) VpData->Epdpt[i].PageFrameNumber = i; } -BOOLEAN +UINT8 ShvVmxEnterRootModeOnVp ( _In_ PSHV_VP_DATA VpData ) @@ -103,10 +103,10 @@ ShvVmxEnterRootModeOnVp ( // // Store the physical addresses of all per-LP structures allocated // - VpData->VmxOnPhysicalAddress = MmGetPhysicalAddress(&VpData->VmxOn).QuadPart; - VpData->VmcsPhysicalAddress = MmGetPhysicalAddress(&VpData->Vmcs).QuadPart; - VpData->MsrBitmapPhysicalAddress = MmGetPhysicalAddress(VpData->MsrBitmap).QuadPart; - VpData->EptPml4PhysicalAddress = MmGetPhysicalAddress(&VpData->Epml4).QuadPart; + VpData->VmxOnPhysicalAddress = ShvOsGetPhysicalAddress(&VpData->VmxOn); + VpData->VmcsPhysicalAddress = ShvOsGetPhysicalAddress(&VpData->Vmcs); + VpData->MsrBitmapPhysicalAddress = ShvOsGetPhysicalAddress(VpData->MsrBitmap); + VpData->EptPml4PhysicalAddress = ShvOsGetPhysicalAddress(&VpData->Epml4); // // Update CR0 with the must-be-zero and must-be-one requirements @@ -392,13 +392,13 @@ ShvVmxSetupVmcsForVp ( __vmx_vmwrite(HOST_RIP, (ULONG_PTR)ShvVmxEntry); } -BOOLEAN +UINT8 ShvVmxProbe ( VOID ) { - INT cpu_info[4]; - ULONGLONG featureControl; + INT32 cpu_info[4]; + UINT64 featureControl; // // Check the Hypervisor Present-bit @@ -440,7 +440,7 @@ ShvVmxLaunchOnVp ( _In_ PSHV_VP_DATA VpData ) { - ULONG i; + UINT32 i; // // Initialize all the VMX-related MSRs by reading their value @@ -41,7 +41,7 @@ ShvVmxResume ( ULONG_PTR FORCEINLINE ShvVmxRead ( - _In_ ULONG VmcsFieldId + _In_ UINT32 VmcsFieldId ) { SIZE_T FieldData; @@ -74,7 +74,7 @@ ShvVmxHandleCpuid ( _In_ PSHV_VP_STATE VpState ) { - INT cpu_info[4]; + INT32 cpu_info[4]; // // Check for the magic CPUID sequence, and check that it is is coming from @@ -94,7 +94,7 @@ ShvVmxHandleCpuid ( // Otherwise, issue the CPUID to the logical processor based on the indexes // on the VP's GPRs. // - __cpuidex(cpu_info, (INT)VpState->VpRegs->Rax, (INT)VpState->VpRegs->Rcx); + __cpuidex(cpu_info, (INT32)VpState->VpRegs->Rax, (INT32)VpState->VpRegs->Rcx); // // Check if this was CPUID 1h, which is the features request. @@ -132,7 +132,7 @@ ShvVmxHandleXsetbv ( // // Simply issue the XSETBV instruction on the native logical processor. // - _xsetbv((ULONG)VpState->VpRegs->Rcx, + _xsetbv((UINT32)VpState->VpRegs->Rcx, VpState->VpRegs->Rdx << 32 | VpState->VpRegs->Rax); } @@ -220,7 +220,7 @@ ShvVmxEntryHandler ( // // Get the per-VP data for this processor. // - vpData = (PVOID)((ULONG_PTR)(Context + 1) - KERNEL_STACK_SIZE); + vpData = (VOID*)((ULONG_PTR)(Context + 1) - KERNEL_STACK_SIZE); // // Build a little stack context to make it easier to keep track of certain @@ -282,8 +282,8 @@ ShvVmxEntryHandler ( // a longjmp back to that location. // Context->Rsp = guestContext.GuestRsp; - Context->Rip = (ULONG64)guestContext.GuestRip; - Context->EFlags = (ULONG)guestContext.GuestEFlags; + Context->Rip = (UINT64)guestContext.GuestRip; + Context->EFlags = (UINT32)guestContext.GuestEFlags; // // Turn off VMX root mode on this logical processor. We're done here. @@ -22,12 +22,12 @@ Environment: #include "shv.h" -BOOLEAN +UINT8 ShvIsOurHypervisorPresent ( VOID ) { - INT cpuInfo[4]; + INT32 cpuInfo[4]; // // Check if ECX[31h] ("Hypervisor Present Bit") is set in CPUID 1h @@ -129,7 +129,7 @@ ShvVpInitialize ( // By using RtlRestoreContext, that function sets the AC flag in EFLAGS and // returns here with our registers restored. // - RtlCaptureContext(&Data->ContextFrame); + ShvOsCaptureContext(&Data->ContextFrame); if ((__readeflags() & EFLAGS_ALIGN_CHECK) == 0) { // @@ -145,7 +145,7 @@ ShvVpUnloadCallback ( _In_ PSHV_CALLBACK_CONTEXT Context ) { - INT cpuInfo[4]; + INT32 cpuInfo[4]; PSHV_VP_DATA vpData; UNREFERENCED_PARAMETER(Context); @@ -154,7 +154,7 @@ ShvVpUnloadCallback ( // the VP data for the current CPU, which we must free. // __cpuidex(cpuInfo, 0x41414141, 0x42424242); - vpData = (PSHV_VP_DATA)((ULONG64)cpuInfo[0] << 32 | cpuInfo[1]); + vpData = (PSHV_VP_DATA)((UINT64)cpuInfo[0] << 32 | cpuInfo[1]); ShvOsFreeContiguousAlignedMemory(vpData); // @@ -206,9 +206,8 @@ ShvVpLoadCallback ( _In_ PSHV_CALLBACK_CONTEXT Context ) { - ULONG cpuIndex; PSHV_VP_DATA vpData; - NTSTATUS status; + INT32 status; // // Detect if the hardware appears to support VMX root mode to start. @@ -216,7 +215,7 @@ ShvVpLoadCallback ( // if (!ShvVmxProbe()) { - status = STATUS_HV_FEATURE_UNAVAILABLE; + status = SHV_STATUS_NOT_AVAILABLE; goto Failure; } @@ -226,7 +225,7 @@ ShvVpLoadCallback ( vpData = ShvVpAllocateData(); if (vpData == NULL) { - status = STATUS_HV_NO_RESOURCES; + status = SHV_STATUS_NO_RESOURCES; goto Failure; } @@ -252,22 +251,21 @@ ShvVpLoadCallback ( // Free the per-processor data // ShvOsFreeContiguousAlignedMemory(vpData); - status = STATUS_HV_NOT_PRESENT; + status = SHV_STATUS_NOT_PRESENT; goto Failure; } // // This CPU is hyperjacked! // - _InterlockedIncrement((PLONG)&Context->InitCount); + _InterlockedIncrement((volatile long*)&Context->InitCount); return; Failure: // // Return failure // - cpuIndex = KeGetCurrentProcessorNumberEx(NULL); - Context->FailedCpu = cpuIndex; + Context->FailedCpu = ShvOsGetCurrentProcessorNumber(); Context->FailureStatus = status; return; } @@ -354,42 +354,42 @@ enum vmcs_field { typedef struct _VMX_GDTENTRY64 { ULONG_PTR Base; - ULONG Limit; + UINT32 Limit; union { struct { - UCHAR Flags1; - UCHAR Flags2; - UCHAR Flags3; - UCHAR Flags4; + UINT8 Flags1; + UINT8 Flags2; + UINT8 Flags3; + UINT8 Flags4; } Bytes; struct { - USHORT SegmentType : 4; - USHORT DescriptorType : 1; - USHORT Dpl : 2; - USHORT Present : 1; - - USHORT Reserved : 4; - USHORT System : 1; - USHORT LongMode : 1; - USHORT DefaultBig : 1; - USHORT Granularity : 1; - - USHORT Unusable : 1; - USHORT Reserved2 : 15; + UINT16 SegmentType : 4; + UINT16 DescriptorType : 1; + UINT16 Dpl : 2; + UINT16 Present : 1; + + UINT16 Reserved : 4; + UINT16 System : 1; + UINT16 LongMode : 1; + UINT16 DefaultBig : 1; + UINT16 Granularity : 1; + + UINT16 Unusable : 1; + UINT16 Reserved2 : 15; } Bits; - ULONG AccessRights; + UINT32 AccessRights; }; - USHORT Selector; + UINT16 Selector; } VMX_GDTENTRY64, *PVMX_GDTENTRY64; typedef struct DECLSPEC_ALIGN(PAGE_SIZE) _VMX_VMCS { - ULONG RevisionId; - ULONG AbortIndicator; - UCHAR Data[PAGE_SIZE - 8]; + UINT32 RevisionId; + UINT32 AbortIndicator; + UINT8 Data[PAGE_SIZE - 8]; } VMX_VMCS, *PVMX_VMCS; typedef struct _VMX_EPTP @@ -398,14 +398,14 @@ typedef struct _VMX_EPTP { struct { - ULONGLONG Type : 3; - ULONGLONG PageWalkLength : 3; - ULONGLONG EnableAccessAndDirtyFlags : 1; - ULONGLONG Reserved : 5; - ULONGLONG PageFrameNumber : 36; - ULONGLONG ReservedHigh : 16; + UINT64 Type : 3; + UINT64 PageWalkLength : 3; + UINT64 EnableAccessAndDirtyFlags : 1; + UINT64 Reserved : 5; + UINT64 PageFrameNumber : 36; + UINT64 ReservedHigh : 16; }; - ULONGLONG AsUlonglong; + UINT64 AsUlonglong; }; } VMX_EPTP, *PVMX_EPTP; @@ -415,17 +415,17 @@ typedef struct _VMX_EPML4E { struct { - ULONGLONG Read : 1; - ULONGLONG Write : 1; - ULONGLONG Execute : 1; - ULONGLONG Reserved : 5; - ULONGLONG Accessed : 1; - ULONGLONG SoftwareUse : 3; - ULONGLONG PageFrameNumber : 36; - ULONGLONG ReservedHigh : 4; - ULONGLONG SoftwareUseHigh : 12; + UINT64 Read : 1; + UINT64 Write : 1; + UINT64 Execute : 1; + UINT64 Reserved : 5; + UINT64 Accessed : 1; + UINT64 SoftwareUse : 3; + UINT64 PageFrameNumber : 36; + UINT64 ReservedHigh : 4; + UINT64 SoftwareUseHigh : 12; }; - ULONGLONG AsUlonglong; + UINT64 AsUlonglong; }; } VMX_EPML4E, *PVMX_EPML4E; @@ -435,27 +435,27 @@ typedef struct _VMX_HUGE_PDPTE { struct { - ULONGLONG Read : 1; - ULONGLONG Write : 1; - ULONGLONG Execute : 1; - ULONGLONG Type : 3; - ULONGLONG IgnorePat : 1; - ULONGLONG Large : 1; - ULONGLONG Accessed : 1; - ULONGLONG Dirty : 1; - ULONGLONG SoftwareUse : 2; - ULONGLONG Reserved : 18; - ULONGLONG PageFrameNumber : 18; - ULONGLONG ReservedHigh : 4; - ULONGLONG SoftwareUseHigh : 11; - ULONGLONG SupressVme : 1; + UINT64 Read : 1; + UINT64 Write : 1; + UINT64 Execute : 1; + UINT64 Type : 3; + UINT64 IgnorePat : 1; + UINT64 Large : 1; + UINT64 Accessed : 1; + UINT64 Dirty : 1; + UINT64 SoftwareUse : 2; + UINT64 Reserved : 18; + UINT64 PageFrameNumber : 18; + UINT64 ReservedHigh : 4; + UINT64 SoftwareUseHigh : 11; + UINT64 SupressVme : 1; }; - ULONGLONG AsUlonglong; + UINT64 AsUlonglong; }; } VMX_HUGE_PDPTE, *PVMX_HUGE_PDPTE; -C_ASSERT(sizeof(VMX_EPTP) == sizeof(ULONGLONG)); -C_ASSERT(sizeof(VMX_EPML4E) == sizeof(ULONGLONG)); +C_ASSERT(sizeof(VMX_EPTP) == sizeof(UINT64)); +C_ASSERT(sizeof(VMX_EPML4E) == sizeof(UINT64)); #define PML4E_ENTRY_COUNT 512 #define PDPTE_ENTRY_COUNT 512 |