Geoff Chappell - Software Analyst
The HV_X64_HYPERVISOR_HARDWARE_FEATURES structure (formally _HV_X64_HYPERVISOR_HARDWARE_FEATURES) collects the flags that a Microsoft-compatible hypervisor’s cpuid leaf 0x40000006 produces in the eax, ebx, ecx and edx registers.
The HV_X64_HYPERVISOR_HARDWARE_FEATURES is defined for Windows 10. It supersedes the HV_HYPERVISOR_HARDWARE_FEATURES from Windows 8.1, which in turn developed from an unnamed structure for the MsHvHardwareFeatures member of the HV_CPUID_RESULT union. Though the new name suggests a specialisation to the x64 processor, the structure is defined identically for both 32-bit and 64-bit Windows. Version 10.0 also defines an HV_ARM64_HYPERVISOR_HARDWARE_FEATURES, but what this represents on the applicable processors lies (far) outside the scope of this article.
It is here thought that HV_HYPERVISOR_HARDWARE_FEATURES is retained in version 10.0 and higher as a macro for the appropriate processor-specific structure: HV_X64_HYPERVISOR_HARDWARE_FEATURES when building for the x86 and x64 processors; but HV_ARM64_HYPERVISOR_HARDWARE_FEATURES for the 32-bit and 64-bit ARM processors.
The kernel provides two ways to get the whole output from cpuid leaf 0x40000006 into a caller-supplied HV_X64_HYPERVISOR_HARDWARE_FEATURES:
Both are available only in version 10.0 or higher.
The HV_X64_HYPERVISOR_HARDWARE_FEATURES structure is not documented. The structure anyway repackages material that Microsoft does document in the Hypervisor Top-Level Functional Specification (TLFS). If the structure 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.
That said, the Specification that is offered today, 12th November 2016, as the most recent version is a PDF that is three years old (version 4.0b, dated August 2013). The three flags that were added for Windows 10 were left undocumented in the Specification until version 5.0a, dated February 2017. Better late than never, perhaps, but the reality behind the superficially fine words of the Microsoft Open Specification Promise is that the Hyper-V implementation, and presumably Microsoft’s use of it to Microsoft’s advantage for Microsoft’s purposes, runs ahead of the documentation that Microsoft opens for general use.
As for the HV_X64_HYPERVISOR_HARDWARE_FEATURES as Microsoft’s particular expression of the output from cpuid leaf 0x40000006, disclosure by Microsoft is conspicuously thin. The practical equivalent of a C-language definition is published as type information in symbol files, but in the downloadable packages of public symbols for 32-bit and 64-bit Windows 10, type information for HV_X64_HYPERVISOR_HARDWARE_FEATURES appears only in the symbol files for URLMON.DLL. This is a user-mode DLL that originated as a component of Internet Explorer (and still follows Internet Explorer’s version numbering). Well might you wonder what this DLL has to do with the hypervisor such that its symbol files have type information for this structure but the kernel’s don’t! Symbol files for URLMON.DLL starting with Windows 8, both in packages of Windows symbols and when downloaded from Microsoft’s public symbol server, happen to be private symbols. This surely was an oversight, but however this disclosure came about, Microsoft stopped it for Version 1803. That URLMON.DLL knows of the HV_X64_HYPERVISOR_HARDWARE_FEATURES is because some URLMON.DLL source code has a #include for a header named hvgdk_mini.h. Microsoft is known to use his header for its own programming of the Windows kernel but is not known to have ever made it available for use by programmers in general (let alone by the programmers of competing web browsers).
Type information for the HV_X64_HYPERVISOR_HARDWARE_FEATURES turns out to have been also disclosed in the relatively plain sight of two statically linked libraries. I say relatively plain because even experts tend to overlook that libraries can hold type information. Beware anyway that type information in statically linked libraries does not always match the operating system that the library is supposedly intended for. One of the libraries, named CLFSMGMT.LIB, is among the many that are supplied with the Software Development Kit (SDK) for user-mode programming. Type information for the HV_X64_HYPERVISOR_HARDWARE_FEATURES drops out of this library in Version 2004. The other is more obviously related to hypervisors. It is named KDHV.LIB. Microsoft distributes it among the programming samples in the Debugging Tools for Windows. It has type information for the HV_X64_HYPERVISOR_HARDWARE_FEATURES for all versions of Windows 10 at least to the 2004 release.
The HV_X64_HYPERVISOR_HARDWARE_FEATURES is 0x10 bytes. Offsets and definitions below are from type information in symbol files for URLMON.DLL before Version 1803 and then in KDHV.LIB.
Offset | Definition |
---|---|
0x00 |
/* changing bit fields, see below */ |
0x04 |
UINT32 ReservedEbx; |
0x08 |
UINT32 ReservedEcx; |
0x0C |
UINT32 ReservedEdx; |
What cpuid leaf 0x40000006 produces in eax is still evolving as of the 2004 edition of Windows 10:
Mask | Definition | Versions |
---|---|---|
0x00000001 |
UINT32 ApicOverlayAssistInUse: 1; |
10.0 and higher |
0x00000002 |
UINT32 MsrBitmapsInUse : 1; |
10.0 and higher |
0x00000004 |
UINT32 ArchitecturalPerformanceCountersInUse : 1; |
10.0 and higher |
0x00000008 |
UINT32 SecondLevelAddressTranslationInUse : 1; |
10.0 and higher |
0x00000010 |
UINT32 DmaRemappingInUse : 1; |
10.0 and higher |
0x00000020 |
UINT32 InterruptRemappingInUse : 1; |
10.0 and higher |
0x00000040 |
UINT32 MemoryPatrolScrubberPresent : 1; |
10.0 and higher |
0x00000080 |
UINT32 DmaProtectionInUse : 1; |
10.0 and higher |
0x00000100 |
UINT32 HpetRequested : 1; |
10.0 and higher |
0x00000200 |
UINT32 SyntheticTimersVolatile : 1; |
10.0 and higher |
0x00003C00 |
UINT32 HypervisorLevel : 4; |
1511 and higher |
0x00004000 |
UINT32 PhysicalDestinationModeRequired : 1; |
1703 and higher |
0x00008000 |
UINT32 UseVmfuncForAliasMapSwitch : 1; |
1803 and higher |
0x00010000 |
UINT32 HvRegisterForMemoryZeroingSupported : 1; |
1803 and higher |
0x00020000 |
UINT32 UnrestrictedGuestSupported : 1; |
1803 and higher |
0x00040000 |
UINT32 L3CachePartitioningSupported : 1; |
1809 only |
UINT32 RdtAFeaturesSupported : 1; |
1903 and higher | |
0x00800000 |
UINT32 L3CacheMonitoringSupported : 1; |
1809 only |
UINT32 RdtMFeaturesSupported : 1; |
1903 and higher | |
0x01000000 |
UINT32 ChildPerfmonPmuSupported : 1; |
2004 and higher |
0x02000000 |
UINT32 ChildPerfmonLbrSupported : 1; |
2004 and higher |
0x04000000 |
UINT32 ChildPerfmonIptSupported : 1; |
2004 and higher |
0x08000000 |
UINT32 ApicEmulationSupported : 1; |
2004 and higher |
UINT32 Reserved : 22; |
10.0 only | |
UINT32 Reserved : 18; |
1511 to 1607 | |
UINT32 Reserved : 17; |
1703 to 1709 | |
UINT32 Reserved : 14; |
1803 only | |
UINT32 Reserved : 12; |
1809 to 1903 | |
UINT32 Reserved : 8; |
2004 and higher |
Bits from 0x00000001 to 0x00000040 have earlier definitions in the HV_HYPERVISOR_HARDWARE_FEATURES for version 6.3 and even before then in an unnamed structure nested in the HV_CPUID_RESULT. In this sense, all date from Windows 8.
The HypervisorLevel and PhysicalDestinationModeRequired flags, from 2015 and 2017 respectively, are documented only as Reserved even as recently as the TLFS version 6.0b dated February 2020. This is true also of the several that were newly defined in 2018, but perhaps the repurposing of two indicates that none were yet considered stable enough to document. The four additions for the first half-yearly release in 2020 were perhaps too early for this TLFS version, not that there is yet known to be another.