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
path: root/shv.c
diff options
context:
space:
mode:
authorionescu007 <aionescu+git@gmail.com>2016-08-28 23:07:25 +0300
committerionescu007 <aionescu+git@gmail.com>2016-08-28 23:07:25 +0300
commitbbc18f49a677f7e452c14cf614bace6131411c5b (patch)
treeea0d47f0324ea42893ee052a3bfe9e34eac69271 /shv.c
parent16b6c8ffe1beb92e250f3f094b89ce97a0f3a94a (diff)
Fix SimpleVisor to work on VMWare, stop using KeSaveStateForHibernate and misc. cleanups
SimpleVisor was previously using the presence of *ANY* hypervisor as a sign that it is already loaded. This breaks if the loaded hypervisor actually supports nesting and/or isn't SimpleVisor. As such, always try to enable SimpleVisor -- ShvVmxProbe will fail if we can't, and detect SimpleVisor explicitly using the Hyper-V Detection Interface (used by all hypervisors these days). Second, stop using KeSaveStateForHibernate. While it saved us the need for two more assembly instructions (str/sldt), it appears to have bugs around handling of DebugControl, on top of the other bugs we already had to work around. Instead, just use compiler instrincs to grab the required state, which is faster anyway. Move Intel VT-x specific structures into vmx.h instead of shv.h
Diffstat (limited to 'shv.c')
-rw-r--r--shv.c48
1 files changed, 35 insertions, 13 deletions
diff --git a/shv.c b/shv.c
index 900c466..91802b4 100644
--- a/shv.c
+++ b/shv.c
@@ -24,6 +24,39 @@ Environment:
PSHV_GLOBAL_DATA ShvGlobalData;
+BOOLEAN
+ShvIsOurHypervisorPresent (
+ VOID
+ )
+{
+ INT cpuInfo[4];
+
+ //
+ // Check if ECX[31h] ("Hypervisor Present Bit") is set in CPUID 1h
+ //
+ __cpuid(cpuInfo, 1);
+ if (cpuInfo[2] & HYPERV_HYPERVISOR_PRESENT_BIT)
+ {
+ //
+ // Next, check if this is a compatible Hypervisor, and if it has the
+ // SimpleVisor signature
+ //
+ __cpuid(cpuInfo, HYPERV_CPUID_INTERFACE);
+ if (cpuInfo[0] == ' vhS')
+ {
+ //
+ // It's us!
+ //
+ return TRUE;
+ }
+ }
+
+ //
+ // No Hypervisor, or someone else's
+ //
+ return FALSE;
+}
+
VOID
ShvUnload (
_In_ PDRIVER_OBJECT DriverObject
@@ -71,17 +104,6 @@ ShvInitialize (
UNREFERENCED_PARAMETER(RegistryPath);
//
- // Detect if a hypervisor is already loaded, using the standard high bit in
- // the ECX features register. Hypervisors may choose to hide from this, at
- // which point entering VMX root mode will fail (unless a shadows VMCS is
- // used).
- //
- if (HviIsAnyHypervisorPresent())
- {
- return STATUS_HV_OBJECT_IN_USE;
- }
-
- //
// Next, detect if the hardware appears to support VMX root mode to start.
// No attempts are made to enable this if it is lacking or disabled.
//
@@ -115,10 +137,10 @@ ShvInitialize (
KeGenericCallDpc(ShvVpCallbackDpc, (PVOID)__readcr3());
//
- // A hypervisor should now be seen as present on this (and all other) LP,
+ // Our hypervisor should now be seen as present on this (and all other) LP,
// as the SHV correctly handles CPUID ECX features register.
//
- if (HviIsAnyHypervisorPresent() == FALSE)
+ if (ShvIsOurHypervisorPresent() == FALSE)
{
MmFreeContiguousMemory(ShvGlobalData);
return STATUS_HV_NOT_PRESENT;