Geoff Chappell - Software Analyst
The HV_CPUID_FUNCTION enumeration (formally _HV_CPUID_FUNCTION) is Microsoft’s collection of names for cpuid leaves that are meaningful to the Windows kernel’s support of a Microsoft-compatible hypervisor.
The HV_CPUID_FUNCTION enumeration is documented in the Windows Driver Kit (WDK) for Windows 7, which was the last to have documentation included. This kit also provides a C-language definition 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.
If the HV_CPUID_FUNCTION has become undocumented, it may be that Microsoft regards the enumeration as no more than a convenience for Microsoft’s own programming in the loader and kernel, if not in the hypervisor itself. The HV_CPUID_FUNCTION just repackages material that Microsoft documents elsewhere.
The obvious, if not the only, candidate for elsewhere is the Hypervisor Top-Level Functional Specification (TLFS) which today, 12th November 2016, offers as its most recent version a PDF that is three years old. It, version 4.0b, extends no further than cpuid leaf 0x40000006 and thus misses the leaves that are newly recognised by the Windows 10 kernels from 2015. These leaves, up to and including 0x4000000A, are documented in version 5.0a, dated February 2017, nearing two years after Windows 10 was released as the world’s must-have new Windows. 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 years ahead of the documentation that Microsoft opens for general use.
As for the HV_CPUID_FUNCTION as Microsoft’s particular naming of cpuid leaves, disclosure after the WDK for Windows 7 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_CPUID_FUNCTION 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_CPUID_FUNCTION 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_CPUID_FUNCTION also turns out to have been hiding in the relatively plain sight of a statically linked library named CLFSMGMT.LIB which is among the many that are supplied with the Software Development Kit (SDK) for user-mode programming. Type information in this library has the special value of confirming that the HV_CPUID_FUNCTION was defined as long ago as Windows Vista, i.e., before Microsoft published HVGDK.H for Windows 7. Against this is that type information for this enumeration is not in all versions of the library. It doesn’t start in the 64-bit library until WIndows 8 and it drops out for both 32-bit and 64-bit in Version 2004. Beware anyway that type information in statically linked libraries has less forensic value (than in the operating system’s symbol files) because it does not always match the operating system that the library is supposedly intended for.
Microsoft’s names for the HV_CPUID_FUNCTION enumeration and its members are known from (in roughly decreasing order of forensic quality): the C-language definition in the WDK for Windows 7; type information in symbol files for the kernel in Windows 8.1 (only) and for URLMON.DLL in Windows 8 through to the 1709 release of Windows 10; and type information in most versions of CLFSMGMT.LIB for Windows Vista through to the 1903 release of Windows 10. I know of no public source beyond Version 1903.
Value | Name | Versions |
---|---|---|
0x00000001 | HvCpuIdFunctionVersionAndFeatures | 6.0 and higher |
0x40000000 | HvCpuIdFunctionHvVendorAndMaxFunction | 6.0 and higher |
0x40000001 | HvCpuIdFunctionHvInterface | 6.0 and higher |
0x40000002 | HvCpuIdFunctionMsHvVersion | 6.0 and higher |
0x40000003 | HvCpuIdFunctionMsHvFeatures | 6.0 and higher |
0x40000004 | HvCpuIdFunctionMsHvEnlightenmentInformation | 6.0 and higher |
0x40000005 | HvCpuIdFunctionMsHvImplementationLimits | 6.0 and higher |
0x40000006 | HvCpuIdFunctionMsHvHardwareFeatures | 6.2 and higher |
0x40000007 | HvCpuIdFunctionMsHvCpuManagementFeatures | 10.0 and higher |
0x40000008 | HvCpuIdFunctionMsHvSvmFeatures | 10.0 and higher |
0x40000009 | HvCpuIdFunctionMsHvSkipLevelFeatures | 1511 and higher |
0x4000000A | HvCpuidFunctionMsHvNestedVirtFeatures | 1511 and higher |
0x4000000B | HvCpuidFunctionMsHvIptFeatures | 1903 and higher |
0x40000005 (6.1); 0x40000006 (6.2 to 6.3); 0x40000008 (10.0); 0x4000000A (1511 to 1809); 0x4000000B |
HvCpuIdFunctionMaxReserved | 6.1 and higher |
Note that the members’ names differentiate cpuid leaves 0x40000000 and 0x40000001 as generic to any hypervisor (“Hv”), and subsequent leaves as particular to Microsoft hypervisors (“MsHv”).
Type information in CLFSMGMT.LIB does not show HvCpuIdFunctionMaxReserved until the version from the Windows 8 SDK, no matter that the published HVGDK.H shows it for Windows 7. It may have been defined only shortly before the final build for Windows 7: the library in the Windows 7 SDK was built a month before the Windows 7 kernel (11th June 2009 versus 14th July).
Symbol files for Windows 8 have the enumeration extend to HvCpuIdFunctionMsHvHardwareFeatures. The TLFS from the time, version 2.0a dated May 2012, also ends with cpuid leaf 0x40000006. The roughly contemporaneous WDK documentation to merge into Visual Studio 2012 had not caught up: its page for HV_CPUID_FUNCTION is dated “7/19/2012” but reaches only to HvCpuIdFunctionMsHvImplementationLimits (0x40000005), just as did the corresponding page in the WDK for Windows 7 from “June 18, 2009”.
The kernel is known to use cpuid leaf 0x4000000B in the first of the half-yearly updates for 2019 and Microsoft’s name for this leaf is in CLFSMGMT.LIB from the Windows SDK as distributed with the Enterprise WDK for Version 1903. Nearly a year later this use is not covered by the TLFS version 6.0b, dated February 2020.