HV_ENLIGHTENMENT_INFORMATION

The HV_ENLIGHTENMENT_INFORMATION structure collects the flags that a Microsoft-compatible hypervisor’s cpuid leaf 0x40000004 produces in the eax, ebx, ecx and edx registers.

Availability

The HV_ENLIGHTENMENT_INFORMATION is defined in version 6.3, having developed from the unnamed structure that versions 6.0 to 6.2 define for the MsHvEnlightenmentInformation member of the HV_CPUID_RESULT union. It is superseded in version 10.0 by the HV_X64_ENLIGHTENMENT_INFORMATION. Version 10.0 also defines an HV_ARM64_ENLIGHTENMENT_INFORMATION, but what this represents on the applicable processors lies (far) outside the scope of this article.

It is here thought that HV_ENLIGHTENMENT_INFORMATION is retained in version 10.0 and higher as a macro for the appropriate processor-specific structure: HV_X64_ENLIGHTENMENT_INFORMATION when building for the x86 and x64 processors; but HV_ARM64_ENLIGHTENMENT_INFORMATION for the 32-bit and 64-bit ARM processors.

Documentation Status

The HV_ENLIGHTENMENT_INFORMATION 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.

Layout

The HV_ENLIGHTENMENT_INFORMATION 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 URLMON.DLL in Windows 8.1. Well might you wonder what URLMON.DLL has to do with the hypervisor such that its symbol files have type information for this structure but the kernel’s don’t!

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
/*  bit fields for EAX, see below  */
6.0 to 6.3
0x04
UINT32 ReservedEbx;
early 6.0 only
UINT32 LongSpinWaitCount;
late 6.0 to 6.3
0x08
UINT32 ReservedEcx;
6.0 to 6.3
0x0C
UINT32 ReservedEdx;
6.0 to 6.3

Version numbers before 6.3 refer to prior appearance in the MsHvEnlightenmentInformation member of the HV_CPUID_RESULT.

Though no definition of LongSpinWaitCount is known before Windows 7, one surely did exist since the kernel’s interpretation of the output in ebx starts at Windows Vista SP1.

Offset 0x00 (EAX)

Mask Definition Versions
 0x00000001
UINT32 UseHypercallForAddressSpaceSwitch : 1;
6.0 to 6.3
0x00000002
UINT32 UseHypercallForLocalFlush : 1;
6.0 to 6.3
0x00000004
UINT32 UseHypercallForRemoteFlush : 1;
6.0 to 6.3
0x00000008
UINT32 UseMsrForApicAccess : 1;
early 6.0 only
UINT32 UseApicMsrs : 1;
late 6.0 to 6.3
0x00000010
UINT32 UseMsrForReset : 1;
late 6.0 to 6.3
0x00000020
UINT32 UseRelaxedTiming : 1;
late 6.0 to 6.3
0x00000040
UINT32 UseDmaRemapping : 1;
6.2 to 6.3
0x00000080
UINT32 UseInterruptRemapping : 1;
6.2 to 6.3
0x00000100
UINT32 UseX2ApicMsrs : 1;
6.2 to 6.3
0x00000200
UINT32 DeprecateAutoEoi : 1;
6.2 to 6.3
 
UINT32 Reserved : 28;
6.0 only
UINT32 Reserved : 26;
6.1 only
UINT32 Reserved : 22;
6.2 to 6.3

When the 0x00000008 bit changed name is not known with the certainty of formal definition or even of type information, but inspection of the kernel and HAL binaries shows that interpretation of cpuid leaf 0x40000004 was extended for Windows Vista SP1 (see next paragraph) and it is here thought more likely that the name changes will have been done then rather than separately for Windows 7.

Though no definition is known for any bit beyond 0x00000008 before Windows 7, the HAL and the kernel in Windows Vista SP1 use the 0x00000010 and 0x00000020 bits, respectively, for the same purposes as do later versions.

All flags that are defined for version 6.3 continue to version 10.0 in the HV_X64_ENLIGHTENMENT_INFORMATION, but UseMsrForReset changes name to UseHvRegisterForReset.