HV_CPUID_RESULT

The HV_CPUID_RESULT union collects the various sorts of flags and other data that a Microsoft-compatible hypervisor’s implementation of the cpuid instruction produces in the eax, ebx, ecx and edx registers.

Documentation Status

The HV_CPUID_RESULT is documented in the Windows Driver Kit (WDK) for Windows 7, which was the last to have documentation included. That kit also provides a C-language definition in the HVGDK.H header file. Later kits do not. A search through Google today (13th November 2016) produces just five results for the name, none from Microsoft.

If the HV_CPUID_RESULT has become undocumented, it may be 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_CPUID_RESULT just repackages material that Microsoft does document—or represents as documented. The hypervisor’s cpuid implementation is documented in the Hypervisor Top-Level Functional Specification, which today (12th November 2016) offers as its most recent version a PDF that is only three years old. Despite the Microsoft Open Specification Promise, nobody will be surprised that the defined flags run ahead of the documentation.

Layout

The HV_CPUID_RESULT is 0x10 bytes. Names and definitions below are from the C-language definition in the WDK for Windows 7 and from type information in the symbol files for URLMON.DLL in Windows 8 and higher. 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!

The first member of the union allows for access to each dword as retrieved in successive registers:

Offset Definition
0x00
UINT Eax;
0x04
UINT Ebx;
0x08
UINT Ecx;
0x0C
UINT Edx;

A second member provides for similar access but as an array:

UINT AsUINT32 [4];

Intel Leaf

A third member, named VersionAndFeatures, is defined inline as an unnamed structure. It picks out two items that are produced by the Intel-defined cpuid leaf 1 but which have particular interest to a hypervisor.

Offset Definition
0x00
UINT ReservedEax;
0x04
union {
    UINT ReservedEbx : 24;
    UINT InitialApicId : 8;             // 0xFF000000
};
0x08
union {
    UINT ReservedEcx : 31;
    UINT HypervisorPresent : 1;         // 0x80000000
};
0x0C
UINT ReservedEdx;

The HypervisorPresent flag is described in Intel’s cpuid documentation as “Not Used” and “Always returns 0”. If the bit is set, the kernel infers that some sort of hypervisor is present such that cpuid supports leaves 0x40000000 and 0x40000001.

Hypervisor Leaves

The remaining members are specialised for input values of eax beginning at 0x40000000. Except for MsHvVersion, each was defined inline as an unnamed structure up to and including version 6.2, but all now have separate definitions. The inline definitions are not reproduced below. To find what these early versions defined for a leaf, refer to the separate documentation of the corresponding structure.

Offset Leaf Definition Versions
0x00 0x40000000
HV_VENDOR_AND_MAX_FUNCTION HvVendorAndMaxFunction;
6.1 and higher
0x40000001
HV_HYPERVISOR_INTERFACE_INFO HvInterface;
6.1 and higher
0x40000002
HV_HYPERVISOR_VERSION_INFO MsHvVersion;
6.1 and higher
0x40000003
HV_HYPERVISOR_FEATURES  MsHvFeatures;
6.1 to 6.3
HV_X64_HYPERVISOR_FEATURES  MsHvFeatures;
10.0 and higher
0x40000004
HV_ENLIGHTENMENT_INFORMATION MsHvEnlightenmentInformation;
6.1 to 6.3
HV_X64_ENLIGHTENMENT_INFORMATION MsHvEnlightenmentInformation;
10.0 and higher
0x40000005
HV_IMPLEMENTATION_LIMITS MsHvImplementationLimits;
6.1 and higher
0x40000006
HV_HYPERVISOR_HARDWARE_FEATURES MsHvHardwareFeatures;
6.2 to 6.3
HV_X64_HYPERVISOR_HARDWARE_FEATURES MsHvHardwareFeatures;
10.0 and higher
 
HV_X64_PLATFORM_CAPABILITIES MsHvPlatformCapabilities;
10.0 and higher
0x40000007
HV_X64_HYPERVISOR_CPU_MANAGEMENT_FEATURES MsHvCpuManagementFeatures;
10.0 and higher
0x40000008
HV_HYPERVISOR_SVM_FEATURES   MsHvSvmFeatures;
10.0 and higher

Though Windows 10 inserts MsHvPlatformCapabilities among members that plainly correspond to CPU leaves, the kernel is not known to query any cpuid leaf for anything like the flags that are defined for that member.

CPUID Leaves

Microsoft’s names for the cpuid leaves are known too, as an HV_CPUID_FUNCTION enumeration:

Value Name Versions
0x00000001 HvCpuIdFunctionVersionAndFeatures 6.1 and higher
0x40000000 HvCpuIdFunctionHvVendorAndMaxFunction 6.1 and higher
0x40000001 HvCpuIdFunctionHvInterface 6.1 and higher
0x40000002 HvCpuIdFunctionMsHvVersion 6.1 and higher
0x40000003 HvCpuIdFunctionMsHvFeatures 6.1 and higher
0x40000004 HvCpuIdFunctionMsHvEnlightenmentInformation 6.1 and higher
0x40000005 HvCpuIdFunctionMsHvImplementationLimits 6.1 and higher
0x40000006 HvCpuIdFunctionMsHvHardwareFeatures 6.2 and higher
0x40000007 HvCpuIdFunctionMsHvCpuManagementFeatures 10.0 and higher
0x40000008 HvCpuIdFunctionMsHvSvmFeatures 10.0 and higher
0x40000005 (6.1);
0x40000006 (6.2 to 6.3);
0x40000008
HvCpuIdFunctionMaxReserved