SYSTEM_HYPERVISOR_QUERY_INFORMATION

The SYSTEM_HYPERVISOR_QUERY_INFORMATION structure (formally _SYSTEM_HYPERVISOR_QUERY_INFORMATION) is what a successful call to ZwQuerySystemInformation or NtQuerySystemInformation produces in its output buffer when given the information class SystemHypervisorInformation (0x5B).

Availability

The SYSTEM_HYPERVISOR_QUERY_INFORMATION and the corresponding information class were introduced for Windows Vista and remain defined at least to the 2004 release of Windows 10.

Documentation Status

The SYSTEM_HYPERVISOR_QUERY_INFORMATION structure is not documented.

Microsoft does publish the practical equivalent of a C-language definition as type information in symbol files—not for the kernel, where the structure is prepared, nor even for low-level user-mode DLLs that interpret the structure, but for a handful of higher-level DLLs that might ordinarily be thought very distant from any involvement with the structure. Perhaps only by oversight, but starting as long ago as Windows 8, Microsoft’s downloadable packages of public symbols have included a smattering of private symbol files and these continue to be available through the public symbol server. Precisely which DLLs have the type information varies between versions. COMBASE.DLL is among the more reliable nowadays. Disclosure in symbol files for URLMON.DLL stopped for the 1803 release of Windows 10 but is specially notable because of this DLL’s origins in Internet Explorer and thence for the strong suggestion that Microsoft’s programmers of Internet Explorer had access to more details of low-level Windows programming than Microsoft publishes for wider use (including by the programmers of competing web browsers).

Layout

The SYSTEM_HYPERVISOR_QUERY_INFORMATION is 0x10 bytes in 32-bit and 64-bit Windows. Offsets, names and types are from symbol files, as noted above, starting with Windows 8. What’s known for earlier versions is something of a guess from inspection of the kernel.

Offset Definition Versions
0x00
BOOLEAN HypervisorConnected;
6.0 and higher
0x01
BOOLEAN HypervisorDebuggingEnabled;
6.3 and higher
0x02
BOOLEAN HypervisorPresent;
10.0 and higher
0x03
UCHAR HypervisorSchedulerType;
1903 and higher
0x01 (6.0 to 6.2);
0x02 (6.3);
0x03 (10.0 to 1809);
0x04
UCHAR Spare0 [7];
6.0 to 6.2
UCHAR Spare0 [6];
6.3 only
UCHAR Spare0 [5];
10.0 to 1809
UCHAR Spare0 [4];
1903 and higher
0x08
ULONGLONG EnabledAddressSpaceEnlightenments;
6.0 to 6.3
ULONGLONG EnabledEnlightenments;
10.0 and higher

Microsoft’s assembly-language names for a few of the EnabledEnlightenments are known from headers named KS386.INC and KSAMD64.INC in either or both of Windows Driver Kit (WDK) and the Software Development Kit (SDK) for various Windows versions:

Mask Name Versions
0x00000001 HV_MMU_USE_HYPERCALL_FOR_ADDRESS_SWITCH 6.0 and higher
0x00000002 HV_MMU_USE_HYPERCALL_FOR_LOCAL_FLUSH 6.0 and higher
0x00000004 HV_MMU_USE_HYPERCALL_FOR_REMOTE_FLUSH 6.0 and higher
0x00000010 HV_APIC_ENLIGHTENED 6.2 and higher
0x00000040 HV_KE_USE_HYPERCALL_FOR_LONG_SPIN_WAIT 6.1 and higher
0x00002000 (6.2 to 10.0);
0x00001000
HV_DEPRECATE_AUTO_EOI 6.2 and higher

Independently of what names might be learnt from Microsoft, the following quick survey of individual bits is obtained by looking at how the kernel initialises the variable that EnabledEnlightenments is copied from. The kernel determines most from one or another bit in the output from one or another cpuid leaf. These bits are described below by their names in the HV_X64_HYPERVISOR_FEATURES, HV_X64_ENLIGHTENMENT_INFORMATION or HV_X64_HYPERVISOR_CPU_MANAGEMENT_FEATURES structures that are Microsoft’s programmatic representation of the output from cpuid leaves 0x40000003, 0x40000004 and 0x40000007, respectively. For some, there are additional conditions or other subtleties. The aim below is only to sketch what looks most likely as the essential character for Microsoft’s choice of its unknown names for the EnabledEnlightenments. It is all anyway a work in (occasional) progress. In particular, I’m yet to study the additions for Version 1703 and higher, let alone to devise their presentation.

Mask Leaf Bit Versions
0x00000001 0x40000004 UseHypercallForAddressSpaceSwitch 6.0 and higher
0x00000002 0x40000004 UseHypercallForLocalFlush
6.0 and higher
0x00000004 0x40000004 UseHypercallForRemoteFlush 6.0 and higher
0x00000008   always set 6.0 only
0x40000003 CpuManagement 6.1 to 6.3
0x40000007 ReservedIdentityBit 10.0 and higher
0x00000010 0x40000004 UseApicMsrs
6.0 and higher
0x00000020 0x40000004 UseRelaxedTiming 6.1 and higher
0x00000040 0x40000004 positive LongSpinWaitCount 6.1 and higher
0x00000080 0x40000003 XmmRegistersForFastHypercallAvailable 6.1 and higher (x64)
0x00000100 0x40000003 both AccessPartitionReferenceCounter
and AccessPartitionReferenceTsc
6.1 and higher
0x00000200 0x40000003 GuestIdleAvailable 6.1 and higher
0x00000400 0x40000003 CpuManagement 6.2 to 6.3
0x40000007 ProcessorPowerManagement 10.0 and higher
0x00000800 0x40000003 either CpuManagement
or NumaDistanceQueryAvailable
6.2 to 6.3
0x40000003 NumaDistanceQueryAvailable 10.0 and higher
0x00001000 0x40000004 UseInterruptRemapping 6.2 to 10.0
0x00002000 (6.2 to 10.0);
0x00001000
0x40000004 DeprecateAutoEoi 6.2 and higher
0x00004000 (6.2 to 10.0);
0x00002000
0x40000003 GuestCrashRegsAvailable 6.2 and higher
0x00008000 (6.2 to 10.0);
0x00004000
0x40000004 UseSyntheticClusterIpi 10.0 and higher
0x00010000 (6.2 to 10.0);
0x00008000
0x40000003 StartVirtualProcessor 10.0 and higher
0x00020000 (6.2 to 10.0);
0x00010000
0x40000007 ReservedIdentityBit 10.0 and higher
0x00040000 (6.2 to 10.0);
0x00020000
0x40000007 MwaitIdleStates 10.0 and higher
0x00080000 (6.2 to 10.0);
0x00040000
0x40000007 LogicalProcessorIdling 10.0 and higher
0x00080000 0x40000004 UseIntForMbecSystemCalls 1511 and higher (x64)
0x00100000 0x40000003 HypercallMsrLockAvailable 1511 and higher
0x00200000 extended
capability
0x00000002 bit 1703 and higher
0x00400000 extended
capability
0x00000004 bit 1709 and higher
0x00800000     1803 and higher
0x01000000      
0x02000000      
0x04000000 0x40000003 CrossVtlFlushAvailable 1903 and higher
0x08000000 extended
capability
0x00000080 bit 2004 and higher

The LongSpinWaitCount is known to be declared as an unsigned integer, but for the purpose of determining enlightenments it is reinterpreted as signed. A wait count of 0x80000000 or higher, not that anyone would want it, would be ignored for being negative.

The 0x04000000 enlightenment is shown above as corresponding to the CrossVtlFlushAvailable feature, but this is for brevity. The enlightenment is reported for 32-bit Windows, but the feature relates to the secure kernel and is meaningful only for 64-bit Windows. The cross-VTL flush is done only as a fast hypercall, and so although the 0x04000000 englightenment requires this feature, it also requires XmmRegistersForFastHypercallAvailable.