Geoff Chappell - Software Analyst
The HV_HYPERVISOR_FEATURES structure (formally _HV_HYPERVISOR_FEATURES) collects the flags that a Microsoft-compatible hypervisor’s cpuid leaf 0x40000003 produces in the eax, ebx, ecx and edx registers.
The HV_HYPERVISOR_FEATURES is defined in version 6.3, having developed from the unnamed structure that versions 6.0 to 6.2 define for the MsHvFeatures member of the HV_CPUID_RESULT union. It is superseded in version 10.0 by the HV_X64_HYPERVISOR_FEATURES. Version 10.0 also defines an HV_ARM64_HYPERVISOR_FEATURES, but what this represents on the applicable processors lies (far) outside the scope of this article.
It is here thought that HV_HYPERVISOR_FEATURES is retained in version 10.0 and higher as a macro for the appropriate processor-specific structure: HV_X64_HYPERVISOR_FEATURES iwhen building for the x86 and x64 processors; but HV_ARM64_HYPERVISOR_FEATURES for the 32-bit and 64-bit ARM processors.
The HV_HYPERVISOR_FEATURES is not documented. Some of its members, having previously been defined in the HV_CPUID_RESULT, are documented in the Windows Driver Kit (WDK) for Windows 7, which also provided a C-language definition (of the structure’s unnamed ancestor) in the HVGDK.H header file. Except that documentation continued to a separately downloadable package for merging into Visual Studio 2012, later kits have neither the documentation nor the header.
The structure anyway repackages material that Microsoft documents in the Hypervisor Top-Level Functional Specification. If it or its members’ previous definitions have become undocumented, it may be just that Microsoft regards the structure as no more than a convenience for Microsoft’s own programming in the loader and kernel, if not in the hypervisor itself.
The HV_HYPERVISOR_FEATURES is 0x10 bytes in both 32-bit and 64-bit Windows, as was the unnamed structure that it was developed from. Offsets and definitions below are from type information in symbol files for the Windows 8.1 kernel.
These tables also survey the structure’s development in earlier versions when it was not yet a named structure. Offsets, names and types are from (in roughly decreasing order of forensic quality): the C-language definition of the HV_CPUID_RESULT in the WDK for Windows 7; type information in symbol files for URLMON.DLL for Windows 8; and type information in the statically linked library CLFSMGMT.LIB from the Software Development Kit (SDK) for Windows Vista. Some development within version 6.0 is inferred from inspection of binaries: late 6.0 starts with Windows Vista SP1.
Offset | Definition | Versions |
---|---|---|
0x00 |
HV_PARTITION_PRIVILEGE_MASK PartitionPrivileges; |
6.0 to 6.3 |
0x08 |
UINT32 ReservedEcx; |
early 6.0 only |
/* bit fields for ECX, see below */ |
late 6.0 to 6.3 | |
0x0C |
UINT32 ReservedEdx; |
early 6.0 only |
/* bit fields for EDX, see below */ |
late 6.0 to 6.3 |
Version numbers before 6.3 refer to prior appearance in the MsHvFeatures member of the HV_CPUID_RESULT.
Mask | Definition | Versions |
---|---|---|
0x0000000F |
UINT32 MaxSupportedCState : 4; |
late 6.0 to 6.3 |
0x00000010 |
UINT32 HpetNeededForC3PowerState : 1; |
6.2 to 6.3 |
UINT32 Reserved : 28; |
late 6.0 to 6.1 | |
UINT32 Reserved : 27; |
6.2 to 6.3 |
All flags that are defined for version 6.3 continue to version 10.0 in the HV_X64_HYPERVISOR_FEATURES, but with a change of name for HpetNeededForC3PowerState to make clear that it is deprecated. The MaxSupportedCState is also thought to have fallen out of use by then: its value is read by the kernel in Windows Vista SP1 and in Windows 7, but apparently not in Windows 8 or higher.
Mask | Definition | Versions |
---|---|---|
0x00000001 |
UINT32 MwaitAvailable : 1; |
6.1 to 6.3 |
0x00000002 |
UINT32 GuestDebuggingAvailable : 1; |
6.1 to 6.3 |
0x00000004 |
UINT32 PerformanceMonitorsAvailable : 1; |
6.1 to 6.3 |
0x00000008 |
UINT32 CpuDynamicPartitioningAvailable : 1; |
late 6.0 to 6.3 |
0x00000010 |
UINT32 XmmRegistersForFastHypercallAvailable : 1; |
6.1 to 6.3 |
0x00000020 |
UINT32 GuestIdleAvailable : 1; |
6.1 to 6.3 |
0x00000040 |
UINT32 HypervisorSleepStateSupportAvailable : 1; |
6.2 to 6.3 |
0x00000080 |
UINT32 NumaDistanceQueryAvailable : 1; |
6.2 to 6.3 |
0x00000100 |
UINT32 FrequencyMsrsAvailable : 1; |
6.2 to 6.3 |
0x00000200 |
UINT32 SyntheticMachineCheckAvailable : 1; |
6.2 to 6.3 |
0x00000400 |
UINT32 GuestCrashMsrsAvailable : 1; |
6.2 to 6.3 |
0x00000800 |
UINT32 DebugMsrsAvailable : 1; |
6.2 to 6.3 |
0x00001000 |
UINT32 Npiep1Available : 1; |
6.3 only |
0x00002000 |
UINT32 DisableHypervisorAvailable : 1; |
6.3 only |
UINT32 Reserved1 : 26; |
6.1 only | |
UINT32 Reserved1 : 20; |
6.2 only | |
UINT32 Reserved1 : 18; |
6.3 only |
Which of these flags were defined before version 6.1 is a work in progress. Only CpuDynamicPartitioningAvailable is yet known to be read by the kernel in Windows Vista SP1.
All flags that are defined for version 6.3 continue to version 10.0 in the HV_X64_HYPERVISOR_FEATURES, but with a change of name for MwaitAvailable to make clear that it is deprecated.
The acronym in Npiep1Available is Non-Privileged Instruction Execution Prevention. An NPIEP2 may have been anticipated but none is yet known.