HV_X64_PLATFORM_CAPABILITIES

The HV_X64_PLATFORM_CAPABILITIES structure (formally _HV_X64_PLATFORM_CAPABILITIES and actually a union) collects the flags that a Microsoft-compatible hypervisor produces in the eax, ebx, ecx and edx registers as output for some unknown leaf of the cpuid instruction.

Or so it seems reasonable to infer. The HV_CPUID_RESULT union that Microsoft defined in the Windows Driver Kit (WDK) for Windows 7 was at least intended at the time to cover all the cpuid leaves that matter to the hypervisor. For Windows 10, according to symbol files (see below), this union got three new members. The older members are in increasing order of cpuid leaf, and had got as far as 0x40000006. The first of the new members has the mystery type HV_X64_PLATFORM_CAPABILITIES. It is followed by members whose types, HV_X64_HYPERVISOR_CPU_MANAGEMENT_FEATURES and HV_HYPERVISOR_SVM_FEATURES, are clearly for cpuid leaves 0x40000007 and 0x40000008. Among cpuid leaves in the hypervisor series that starts 0x40000000, none that the Windows kernel is presently known to execute produces flags that match the HV_X64_PLATFORM_CAPABILITIES definition.

The best guess I have—and beware that I say guess because what I base it on is too thin to call evidence—is that the HV_X64_PLATFORM_CAPABILITIES structure models the output of cpuid leaf 0x40000082. This cpuid leaf can be executed by the kernel in versions 6.1 to 6.3 inclusive and by various boot applications, notably the EFI boot manager and boot loader, starting with 64-bit Windows 8 and 32-bit Windows 8.1, and continuing at least to the 2004 release of Windows 10. Indeed, the latter use has been broadening, such that it is also seen in KDNET.DLL. The kernel and the others each test one of the lowest two bits that cpuid leaf 0x40000082 produces in eax, the kernel for licensing, the others for whether to allow debugging (of themselves and of the kernel). Squint a little and the use of these two bits look a little like matching the AllowRedSignedCode and AllowKernelDebugging that the structure has for its two first bits (see below). In the absence of any other explanation for what HV_X64_PLATFORM_CAPABILITIES can be meant for in the HV_CPUID_RESULT, I latch onto cpuid leaf 0x40000082.

Documentation Status

The HV_X64_PLATFORM_CAPABILITIES is not documented. The hypervisor’s cpuid implementation is documented in the Hypervisor Top-Level Functional Specification (TLFS), which Microsoft provides under the Microsoft Open Specification Promise. No known version of this specification, from 2.0 dated May 2012 to 6.0b dated February 2020, mentions cpuid leaf 0x40000082 or any other whose output looks even a little like the HV_X64_PLATFORM_CAPABILITIES.

TLFS versions up to and including 5.0c, dated July 2018, do however have an appendix titled Architectural CPUID which documents the range 0x40000080 to 0x400000FF as “Reserved for use of intercept handlers in the parent partition”. I cannot discount that an earlier TLFS or precursor documented cpuid leaf 0x40000082 and perhaps even that hypervisors with Microsoft as vendor implement 0x40000080 as beginning a second series of hypervisor leaves that closely follow the pattern of the first. A quick search of the Internet turns up headers whose authors define at least something for cpuid leaf 0x400000082 and cite the TLFS (but not which version) at least for reference if not as their actual source. My thinking is that they mean their citation of the TLFS only as an inspiration for their own programmatic definitions, not that their definitions are reproduced from whatever Microsoft presented. After all, among these headers are two different names that suggest very different purposes. That I even bother to point out such apparently unreliable non-Microsoft secondary or tertiary sources is to make the point that cpuid leaf 0x40000082 is about as obscure as things get.

Independently of which cpuid leaf might be modelled by the HV_X64_PLATFORM_CAPABILITIES structure, there is anyway that the structure is about as obscure as things get for undocumented structures. In the downloadable packages of public symbols for 32-bit and 64-bit Windows 10, only the symbol files for URLMON.DLL have type information for HV_X64_PLATFORM_CAPABILITIES. URLMON 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_X64_PLATFORM_CAPABILITIES 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_X64_PLATFORM_CAPABILITIES 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_X64_PLATFORM_CAPABILITIES 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_X64_PLATFORM_CAPABILITIES for all versions of Windows 10 at least to the 2004 release.

Layout

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

Formally, the HV_X64_PLATFORM_CAPABILITIES is a 16-byte union of a structure of bit fields for the various flags and of two 64-bit integers for accessing of all flags together:

union {
    UINT64 AsUINT64 [2];
    struct {
        /*  mostly bit fields, see below  */
    };
};

The structure is essentially four dwords, each for one register as loaded by executing the unknown cpuid leaf:

Offset Definition
0x00
/*  bit fields for EAX, see below  */
0x04
/*  bit fields for EBX, see below  */
0x08
UINT ReservedEcx;
0x0C
/*  bit fields for EDX, see below  */

What counts, of course, are the flags as bit fields.

Offset 0x00 (EAX)

Except for one bit that is named as if reserved but perhaps had earlier use, the dword for output in eax is fully assigned even for the original Windows 10:

Mask Definition Versions
0x00000001
UINT AllowRedSignedCode : 1;
6.1 and higher
0x00000002
UINT AllowKernelModeDebugging : 1;
6.2 and higher
0x00000004
UINT AllowUserModeDebugging : 1;
10.0 and higher
0x00000008
UINT AllowTelnetServer : 1;
10.0 and higher
0x00000010
UINT AllowIOPorts : 1;
10.0 and higher
0x00000020
UINT AllowFullMsrSpace : 1;
10.0 and higher
0x00000040
UINT AllowPerfCounters : 1;
10.0 and higher
0x00000080
UINT AllowHost512MB : 1;
10.0 and higher
 
UINT ReservedEax1 : 1;
10.0 and higher
0x00000200
UINT AllowRemoteRecovery : 1;
10.0 and higher
0x00000400
UINT AllowStreaming : 1;
10.0 and higher
0x00000800
UINT AllowPushDeployment : 1;
10.0 and higher
0x00001000
UINT AllowPullDeployment : 1;
10.0 and higher
0x00002000
UINT AllowProfiling : 1;
10.0 and higher
0x00004000
UINT AllowJsProfiling : 1;
10.0 and higher
0x00008000
UINT AllowCrashDump : 1;
10.0 and higher
0x00010000
UINT AllowVsCrashDump : 1;
10.0 and higher
0x00020000
UINT AllowToolFileIO : 1;
10.0 and higher
0x00040000
UINT AllowConsoleMgmt : 1;
10.0 and higher
0x00080000
UINT AllowTracing : 1;
10.0 and higher
0x00100000
UINT AllowXStudio : 1;
10.0 and higher
0x00200000
UINT AllowGestureBuilder : 1;
10.0 and higher
0x00400000
UINT AllowSpeechLab : 1;
10.0 and higher
0x00800000
UINT AllowSmartglassStudio : 1;
10.0 and higher
0x01000000
UINT AllowNetworkTools : 1;
10.0 and higher
0x02000000
UINT AllowTcrTool : 1;
10.0 and higher
0x04000000
UINT AllowHostNetworkStack : 1;
10.0 and higher
0x08000000
UINT AllowSystemUpdateTest : 1;
10.0 and higher
0x10000000
UINT AllowOffChipPerfCtrStreaming : 1;
10.0 and higher
0x20000000
UINT AllowToolingMemory : 1;
10.0 and higher
0x40000000
UINT AllowSystemDowngrade : 1;
10.0 and higher
0x80000000
UINT AllowGreenDiskLicenses : 1;
10.0 and higher

That the first two flags are given above for versions before 10.0 is to be understood in the context of guessing that the HV_X64_PLATFORM_CAPABILITIES is the output of cpuid leaf 0x40000082.

The kernel in versions 6.1 to 6.3, both for 32-bit and 64-bit Windows, executes cpuid leaf 0x40000082 solely to check for the 0x00000001 bit. Its sole purpose is to configure the later behaviour of NtQueryLicenceValue, which is of course the implementation of the exported ZwQueryLicenseValue. The specific query that is affected is for Kernel-VMDetection-Private. How this might match the structure’s AllowRedSignedCode is a topic for research. Meanwhile, I observe only that the bit’s name (for signing) isn’t obviously incompatible with the kernel’s use (for licensing).

Interestingly, the kernel’s expectation for availability of cpuid leaf 0x40000082 is only that ecx from cpuid leaf 1 reports that a hypervisor is present and cpuid leaf 0x40000000 identifies the vendor as “Microsoft Hv”. Public symbols name relevant internal routines as ExpIsViridian and ExpIsViridianGuest, apparently called to answer ExpIsVirtualMachinePrivate.

Other software, none yet known to predate version 6.2, executes cpuid leaf 0x40000082 solely to check for the 0x00000002 bit. All this known use is for setting up kernel-mode debugging but not in its whole generality, only for whether to use something named synthetic debugging. Again, more research is required.

Offset 0x04 (EBX)

What cpuid produces in ebx was still in active development if only briefly after the original Windows 10 but no changes are known beyond Version 1511:

Mask Definition Versions
0x00000001
UINT IsLiveConnected : 1;
10.0 and higher
0x00000002
UINT IsMteBoosted : 1;
10.0 and higher
0x00000004
UINT IsQaSlt : 1;
10.0 and higher
0x00000008
UINT IsStockImage : 1;
10.0 and higher
0x00000010
UINT IsMsTestLab : 1;
10.0 and higher
0x00000020
UINT IsRetailDebugger : 1;
10.0 and higher
0x00000040
UINT IsXvdSort : 1;
10.0 and higher
0x00000080
UINT IsGreenDebug : 1;
10.0 and higher
0x00000100
UINT IsHwDevTest : 1;
10.0 and higher
0x00000200
UINT AllowDiskLicenses : 1;
1511 and higher
0x00000400
UINT AllowInstrumentation : 1;
1511 and higher
0x00000800
UINT AllowWifiTester : 1;
1511 and higher
0x00001000
UINT AllowWifiTesterDFS : 1;
1511 and higher
0x00002000
UINT IsHwTest : 1;
1511 and higher
0x00004000
UINT AllowHostOddTest : 1;
1511 and higher
0x00008000
UINT IsLiveUnrestricted : 1;
1511 and higher
0x00010000
UINT AllowDiscLicensesWithoutMediaAuth : 1;
1511 and higher
 
UINT ReservedEbx : 23;
10.0 only
UINT ReservedEbx : 15;
1511 and higher

Offset 0x0C (EDX)

Registers ecx and edx look to have been kept as reserved except for the most significant bit:

Mask Definition Versions
 
UINT ReservedEdx : 31;
10.0 and higher
0x80000000
UINT UseAlternateXvd : 1;
10.0 and higher