HV_X64_HYPERVISOR_FEATURES

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

Availability

The HV_X64_HYPERVISOR_FEATURES is defined for Windows 10. It supersedes the HV_HYPERVISOR_FEATURES from Windows 8.1, which in turn developed from an unnamed structure for the MsHvFeatures 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_FEATURES, but what this represents on the applicable processors lies (far) outside the scope of this article.

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

Access

The kernel provides two ways to get the whole output from cpuid leaf 0x40000003 into a caller-supplied HV_X64_HYPERVISOR_FEATURES:

Both are available only in version 10.0 or higher.

Documentation Status

The HV_X64_HYPERVISOR_FEATURES structure 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 does document—or represents as documented—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). 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.

Layout

The HV_X64_HYPERVISOR_FEATURES is 0x10 bytes in both 32-bit and 64-bit Windows. Offsets and definitions below are from type information in public symbol files for the kernel, starting with the original Windows 10.

Offset Definition
0x00
HV_PARTITION_PRIVILEGE_MASK PartitionPrivileges;
0x08
/*  changing bit fields for ECX, see below  */
0x0C
/*  changing bit fields for EDX, see below  */

Separation into an 8-byte member for what cpuid leaf 0x40000003 produces in eax and ebx and then unstructured bit fields for ecx and edx goes back to the structure’s origin for Windows Vista. Public symbol files for the kernel reveal the name of an inline routine that extracts just the low eight bytes:

VOID HviGetPartitionPrivileges (HV_PARTITION_PRIVILEGE_MASK *);

Offset 0x08 (ECX)

The cpuid output for ecx is very stable across the versions, as far as shown by the type information:

Mask Definition Versions
0x0000000F
UINT32 MaxSupportedCState : 4;
10.0 and higher
0x00000010
UINT32 HpetNeededForC3PowerState_Deprecated : 1;
10.0 and higher
 
UINT32 Reserved : 27;
10.0 and higher

Both MaxSupportedCState and HpetNeededForC3PowerState have earlier definitions in the HV_HYPERVISOR_FEATURES for version 6.3 and even before then in an unnamed structure nested in the HV_CPUID_RESULT. The first is meaningful to the kernel as far back as Windows Vista SP1, though no use of it is known after Windows 7. The second was newly defined for Windows 8. It was renamed for Windows 10 to mark it explicitly as deprecated, but no use is yet known of it even before this deprecation: more research is required.

Offset 0x0C (EDX)

Flags in edx from cpuid leaf 0x40000003 are still evolving as of the 2004 edition of Windows 10:

Mask Definition Versions
0x00000001
UINT32 MwaitAvailable_Deprecated : 1;
10.0 and higher
0x00000002
UINT32 GuestDebuggingAvailable : 1;
10.0 and higher
0x00000004
UINT32 PerformanceMonitorsAvailable : 1;
10.0 and higher
0x00000008
UINT32 CpuDynamicPartitioningAvailable : 1;
10.0 and higher
0x00000010
UINT32 XmmRegistersForFastHypercallAvailable : 1;
10.0 and higher
0x00000020
UINT32 GuestIdleAvailable : 1;
10.0 and higher
0x00000040
UINT32 HypervisorSleepStateSupportAvailable : 1;
10.0 and higher
0x00000080
UINT32 NumaDistanceQueryAvailable : 1;
10.0 and higher
0x00000100
UINT32 FrequencyRegsAvailable : 1;
10.0 and higher
0x00000200
UINT32 SyntheticMachineCheckAvailable : 1;
10.0 and higher
0x00000400
UINT32 GuestCrashRegsAvailable : 1;
10.0 and higher
0x00000800
UINT32 DebugRegsAvailable : 1;
10.0 and higher
0x00001000
UINT32 Npiep1Available : 1;
10.0 and higher
0x00002000
UINT32 DisableHypervisorAvailable : 1;
10.0 and higher
0x00004000
UINT32 ExtendedGvaRangesForFlushVirtualAddressListAvailable : 1;
10.0 and higher
0x00008000
UINT32 FastHypercallOutputAvailable : 1;
10.0 and higher
0x00010000
UINT32 SvmFeaturesAvailable : 1;
10.0 and higher
0x00020000
UINT32 SintPollingModeAvailable : 1;
10.0 and higher
0x00040000
UINT32 HypercallMsrLockAvailable : 1;
1511 and higher
0x00080000
UINT32 DirectSyntheticTimers : 1;
1607 and higher
0x00100000
UINT32 RegisterPatAvailable : 1;
1703 and higher
0x00200000
UINT32 RegisterBndcfgsAvailable : 1;
1703 and higher
0x00400000
UINT32 WatchdogTimerAvailable : 1;
1703 and higher
0x00800000
UINT32 SyntheticTimeUnhaltedTimerAvailable : 1;
1709 and higher
0x01000000
UINT32 DeviceDomainsAvailable : 1;
1709 and higher
0x02000000
UINT32 S1DeviceDomainsAvailable : 1;
1803 and higher
0x04000000
UINT32 LbrAvailable : 1;
1809 and higher
0x08000000
UINT32 IptAvailable : 1;
1903 and higher
0x10000000
UINT32 CrossVtlFlushAvailable : 1;
1903 and higher
0x20000000
UINT32 IdleSpecCtrlAvailable : 1;
2004 and higher
 
UINT32 Reserved1 : 14;
10.0 only
UINT32 Reserved1 : 13;
1511 only
UINT32 Reserved1 : 12;
1607 only
UINT32 Reserved1 : 9;
1703 only
UINT32 Reserved1 : 7;
1709 only
UINT32 Reserved1 : 6;
1803 only
UINT32 Reserved1 : 5;
1809 only
UINT32 Reserved1 : 3;
1903 only
UINT32 Reserved1 : 2;
2004 and higher

All the flags from MwaitAvailable (not yet deprecated) through to DisableHypervisorAvailable have earlier definitions in the HV_HYPERVISOR_FEATURES. Many are even older, appearing first in an unnamed structure nested in the HV_CPUID_RESULT.

No matter that SvmFeaturesAvailable is in type information for a kernel released in 2015, the TLFS even as late as version 6.0b dated February 2020 has it as Reserved. A little differently, the RegisterPatAvailable and RegisterBndcfgsAvailable flags are known to a kernel from early 2017 but were still Reserved a year later, according to the TLFS version 5.0c dated July 2018. They got documented for the TLFS version 6.0b but their contemporary WatchdogTimerAvailable remains Reserved. Also still Reserved in February 2020 are DeviceDomainsAvailable and S1DeviceDomainsAvailable from 2017 and 2018 and all three additions for Version 1903 and higher.