Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/ionescu007/SimpleVisor.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorionescu007 <aionescu+git@gmail.com>2016-08-29 23:51:13 +0300
committerionescu007 <aionescu+git@gmail.com>2016-08-29 23:51:13 +0300
commit2bc0a27d447902930ed725269a35a96a3d32f562 (patch)
treed770592451aafabe2f130a0855c087cf58890bf0
parentf35f5b35bf3dfda2b65b92ccf47a2e7953351563 (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.h176
-rw-r--r--shv.c10
-rw-r--r--shv.h113
-rw-r--r--shv.vcxproj1
-rw-r--r--shv_x.h106
-rw-r--r--shvos.c94
-rw-r--r--shvutil.c12
-rw-r--r--shvvmx.c22
-rw-r--r--shvvmxhv.c14
-rw-r--r--shvvp.c24
-rw-r--r--vmx.h114
11 files changed, 473 insertions, 213 deletions
diff --git a/ntint.h b/ntint.h
index 22fff93..a21f6e4 100644
--- a/ntint.h
+++ b/ntint.h
@@ -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;
diff --git a/shv.c b/shv.c
index 8672c8c..e604d1b 100644
--- a/shv.c
+++ b/shv.c
@@ -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;
}
diff --git a/shv.h b/shv.h
index e78e557..677c556 100644
--- a/shv.h
+++ b/shv.h
@@ -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>
diff --git a/shv_x.h b/shv_x.h
new file mode 100644
index 0000000..f0bfa0d
--- /dev/null
+++ b/shv_x.h
@@ -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;
diff --git a/shvos.c b/shvos.c
index ec914da..a1a68cb 100644
--- a/shvos.c
+++ b/shvos.c
@@ -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());
}
diff --git a/shvutil.c b/shvutil.c
index 5009f35..24477f0 100644
--- a/shvutil.c
+++ b/shvutil.c
@@ -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
)
{
//
diff --git a/shvvmx.c b/shvvmx.c
index eb080ff..f5c7eb5 100644
--- a/shvvmx.c
+++ b/shvvmx.c
@@ -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
diff --git a/shvvmxhv.c b/shvvmxhv.c
index 879928b..0c78453 100644
--- a/shvvmxhv.c
+++ b/shvvmxhv.c
@@ -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.
diff --git a/shvvp.c b/shvvp.c
index 27b0d88..8de228e 100644
--- a/shvvp.c
+++ b/shvvp.c
@@ -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;
}
diff --git a/vmx.h b/vmx.h
index cf07bad..d25be3c 100644
--- a/vmx.h
+++ b/vmx.h
@@ -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