HV_HYPERVISOR_NESTED_VIRT_FEATURES

The HV_HYPERVISOR_NESTED_VIRT_FEATURES structure (formally _HV_HYPERVISOR_NESTED_VIRT_FEATURES ) collects the flags that a Microsoft-compatible hypervisor’s cpuid leaf 0x4000000A produces in the eax, ebx, ecx and edx registers.

Availability

The HV_HYPERVISOR_NESTED_VIRT_FEATURES is new for the 1511 release of Windows 10.

Access

The kernel is not known to expose this structure or any reading of cpuid leaf 0x4000000A through any interface, documented or not, even in kernel mode.

Documentation Status

The HV_HYPERVISOR_NESTED_VIRT_FEATURES structure is not documented. The hypervisor’s cpuid implementation is documented in the Hypervisor Top-Level Functional Specification (TLFS). What’s offered today, 12th November 2016, as the specification’s most recent version is a PDF that is three years old (version 4.0b, dated August 2013). it extends only to leaf 0x40000006. Revelation of cpuid leaf 0x4000000A apparently had to wait for 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_HYPERVISOR_NESTED_VIRT_FEATURES as Microsoft’s particular expression of the output from cpuid leaf 0x4000000A, 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_HYPERVISOR_NESTED_VIRT_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_HYPERVISOR_NESTED_VIRT_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_HYPERVISOR_NESTED_VIRT_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_HYPERVISOR_NESTED_VIRT_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_HYPERVISOR_NESTED_VIRT_FEATURES for all versions of Windows 10 at least to the 2004 release.

Layout

The HV_HYPERVISOR_NESTED_VIRT_FEATURES is 0x10 bytes in both 32-bit and 64-bit Windows. Offsets and definitions below are from type information in symbol files for URLMON.DLL before Version 1803 and then in KDHV.LIB.

Offset Definition Versions
0x00
/*  bit fields, see below  */
1511 and higher
0x04
UINT32 ReservedEbx;
1511 to 1903
/*  bit fields, see below  */
2004 and higher
0x08
UINT32 ReservedEcx;
1511 and higher
0x0C
UINT32 ReservedEdx;
1511 and higher

That ebx is newly meaningful for the first half-yearly release of 2020 is perhaps too early for TLFS version 6.0b, dated February 2020, which is the latest at Microsoft’s website nearly three years later in December 2022.

Offset 0x00 (EAX)

Mask Definition Versions
0x000000FF
UINT32 EnlightedVmcsVersionLow : 8;
1511 and higher
0x0000FF00
UINT32 EnlightedVmcsVesionHigh : 8;
1511 and higher
0x00010000
UINT32 FlushGuestPhysicalHypercall_Deprecated : 1;
1607 and higher
0x00020000
UINT32 NestedFlushVirtualHypercall : 1;
1607 and higher
0x00040000
UINT32 FlushGuestPhysicalHypercall : 1;
1607 and higher
0x00080000
UINT32 MsrBitmap : 1;
1607 and higher
0x00100000
UINT32 VirtualizationException : 1;
1709 and higher
0x00200000
UINT32 DebugCtl : 1;
2004 and higher
 
UINT32 Reserved0 : 16;
1511 and higher
UINT32 Reserved0 : 12;
1607 to 1703
UINT32 Reserved0 : 11;
1709 to 1903
UINT32 Reserved0 : 10;
2004 and higher

Presumably, there was a FlushGuestPhysicalHypercall flag before it was renamed to make clear its deprecation. Perhaps the functionality it governed has some complicated history during the development of the 1607 release such that it needed a new bit. The deprecated bit is marked as Reserved in all the known TLFS versions 5.0a to 6.0b.

Though the VirtualizationException flag was defined for the second half-yearly release of 2017, according to symbol files, it gets no mention nearly a year later in the TLFS version 5.0c dated July 2018. It is documented in the TLFS version 6.0b dated February 2020.

Offset 0x04 (EBX)

Mask Definition Versions
0x00000001
UINT32 PerfGlobalCtrl : 1;
2004 and higher
 
UINT32 Reserved1 : 31;
2004 and higher