Geoff Chappell - Software Analyst
The Model Specific Register (MSR) to Enable Miscellaneous Processor Features has the register address 0x000001A0 on Intel processors. No use of this register is known by the x86 or x64 kernels before version 6.0 or if the vendor string from cpuid leaf 0 is not GenuineIntel.
Windows cares about very few of the bits in this MSR. Yet in anticipation of coming across code that accesses an unfamiliar bit, it may be as well to collect at least Intel’s titles even for the non-architectural bits that exist only in some models: much of the point to this page is to have it as a ready reference just in case. Anyway, one bit that the Windows kernel does access in IA32_MISC_ENABLE is not yet known to have been documented by either Intel or Microsoft.
The Windows kernel is not known to use this bit.
This bit is not architectural. Intel has sometimes named this bit ENABLEFOPCODE. The Windows kernel is not known to use this bit.
The Windows kernel is not known to use this bit.
This bit is not architectural. The Windows kernel is not known to use this bit.
This bit is not architectural. The Windows kernel is not known to use this bit.
Intel has sometimes used the symbolic names PERFMON_AVAILABLE and EMON_AVAILABLE for this bit.
A set bit 7 in IA32_MISC_ENABLE (and a clear bit 12) is required for the NtSetSystemInformation function’s support of its information class SystemProcessorProfileControlArea (0x81) in version 6.2 and higher. The 32-bit kernel requires additionally that the DTES64 bit (2) be set in ecx from cpuid leaf 1.
This information class prepares a PROCESSOR_PROFILE_CONTROL_AREA for the processor so that one kernel-mode caller can manage the processor’s tracing of Processor Event Based Sampling (PEBS) records to caller-supplied buffers and the kernel can have access to the PEBS index for stamping some of its own events. The control area is what Intel’s literature presents as the DS Save Area—specifically in its 64-bit format (hence the 32-bit kernel’s additional requirement, above). The kernel merely prepares the zero-initialised control area in suitable memory. The caller must fill it in, notably to set the buffer into which the processor is to store PEBS records, and the caller must write to the IA32_DS_AREA register (0x0600) to tell the processor where to find the DS Save Area. Identifying an intended caller is for further study.
The same requirement of a set bit 7 and clear bit 12 is known in version 6.1 to the 64-bit kernel only. Control areas for each processor are in an array whose address is in an internal variable named BBTBuffer. In versions 6.1 to 6.3 for both the 32-bit and 64-bit kernels, this variable looks to have no way of ever being loaded with any address. In versions 5.0 to 6.0, however, and again for version 10.0, it gets loaded at startup with the address of an amount of memory that comes ultimately from the perfmem boot option (or /PERFMEM switch in BOOT.INI). In all versions 5.0 and higher, the variable is copied to ReservedForPerf in every TEB. It’s some small mystery, and will remain so without further study.
This bit is not architectural. The Windows kernel is not known to use this bit.
This bit is not architectural. The Windows kernel is not known to use this bit.
This bit is not architectural. The Windows kernel is not known to use this bit.
This bit is not architectural. The Windows kernel is not known to use this bit.
This bit is not architectural. The Windows kernel is not known to use this bit.
Intel has sometimes used the symbolic name BTS_UNAVAILABLE for this bit.
Branch Trace Storage (BTS) gets some specialised use by the kernel in version 6.0 and higher for the Driver Verifier. BTS is available if all processors satisfy the following conditions:
and none have bit 11 set in IA32_MISC_ENABLE.
This use of BTS has the following several quirks, which are presently left for further study.
First, both BTS and Processor Event Based Sampling (PEBS, see bit 12) require that the IA32_DS_AREA register (0x0600) be programmed with the address of a Debug Store (DS) save area, which in turn provides the addresses of buffers in which the processor is to store branch records and PEBS records. Yet no coordination is known between the kernel’s own use of BTS in version 6.0 and higher and its support for PEBS in version 6.2 and higher.
Second, the 32-bit kernel’s code for using BTS knows only of the 32-bit DS save area and its 12-byte branch records. Intel’s documentation seems to read that if cpuid leaf 1 returns ecx with a set DTES64 bit (2), then the processor uses the 64-bit DS save area and 24-byte branch records even when not in IA-32e mode. Perhaps processors can’t show both the DS and DTES64 bits, else this use of BTS is surely broken. Contrast with the 32-bit kernel’s code that supports PEBS: it requires the DTES64 bit and knows only of the 64-bit DS save area.
Third, when the kernel starts its BTS recording by setting appropriate bits in the IA32_DEBUGCTL register (0x01D9) it sets the TR and BTS bits (6 and 7), as documented, if the family is 6. If the family is 15, however, it sets the reserved bits 2 and 3 instead.
Intel has sometimes used the symbolic name PEBS_UNAVAILABLE for this bit.
A clear bit 12 in IA32_MISC_ENABLE (and a set bit 7) is required for the NtSetSystemInformation function’s support of its information class SystemProcessorProfileControlArea (0x81) in version 6.2 and higher. The 32-bit kernel requires additionally that the DTES64 bit (2) be set in ecx from cpuid leaf 1. Refer above to bit 7 for additional notes.
This bit is not architectural. The Windows kernel is not known to use this bit.
The Windows kernel is not known to use this bit.
The Windows kernel is not known to use this bit.
This bit is not architectural. The Windows kernel is not known to use this bit.
This bit is not architectural. The Windows kernel is not known to use this bit.
Bit 22 may have made IA32_MISC_ENABLE the best known of all MSRs that are in any sense quirky. When this bit is set, the processor varies the behaviour of the cpuid instruction so that leaf 0 reports that the instruction allows only 2 or 3 as its maximum valid input for eax. Intel’s manuals say 2 now but have said 3. A known reason for wanting to limit the maximum is that early versions of Windows, before Windows NT 4.0 SP6, from a time when the cpuid instruction was relatively new, were skeptical of any supposed cpuid support that claimed implausibly much. If cpuid leaf 0 returns with eax greater than 3, these versions recognise the processor as a Pentium whose cpuid is completely unusable. With bit 22 set in IA32_MISC_ENABLE, early Windows versions can run on new processors.
The intention, apparently, was that a BIOS knew or determined that the processor is too new for these early Windows versions, it could at least offer to set this bit, or not, according to some setup option. In the usual nature of such workarounds, this presents a sort of reverse problem: what is a new Windows to do with a new processor if this BIOS option is set? For a while, an acceptable answer was that if the user chooses to constrain Windows to do without processor functionality whose existence is reported by cpuid leaves higher than 3, then so be it: computers are meant to obey their masters. Anyway, it was years yet before the Windows kernel would be troubled. Eventually, though, ever more new functionality would become less an option than a necessity or at least so desirable an option that nobody should sensibly want to hobble a new Windows on a computer whose BIOS retains this option from ancient history.
Both the 32-bit and 64-bit kernels in version 6.0 and higher clear this bit at startup if either:
This cut-off for family 6 is presumably not arbitrary. The earlier models extend to the Pentium III, Pentium M and Celeron M. Model 14 marks the change from manufacturing with the 90nm process to 65nm for the Intel Core™. Family 15 began with the Pentium 4. The cut-off for the Windows version isn’t arbitrary, either. For 32-bit Windows, version 6.0 is the first that seeks to use a cpuid leaf higher than 3. This is not quite true of 64-bit Windows, though. Its first version, 5.2 from Windows Server 2003 SP1, uses cpuid leaf 4: it is not known whether anyone had real-world experience of their top-shelf server under-performing because the kernel could not read Intel-specific cache information.
What the kernel does with this MSR bit is nowadays immaterial for the boot processor: in version 6.3 and higher, the bit will have been cleared already by the loader. This happens because the loader knows that kernel stacks have an area at the top for saving floating-point state, originally, but now extended to a possibly much larger XSAVE Area. For the loader’s preparation of a stack for the kernel’s first execution, it naturally seeks more space according to how much bigger the XSAVE Area could be. Its calculation of how big depends on which state components the processor can save and restore. Finding these is done by querying through cpuid leaf 13, which is not possible if bit 22 is set in IA32_MISC_ENABLE. The loader for Windows 8 doesn’t notice, but the loader for Windows 8.1 does: if the XSAVE bit (26) is set in ecx from cpuid leaf 1 for a GenuineIntel processor, then the loader clears this MSR bit so that it can enumerate state components and compute the maximum size that can be needed for an XSAVE Area. The family and model are irrelevant. To the loader for Windows 10, so too is the XSAVE bit.
The Windows kernel is not known to use this bit.
This bit is not architectural. The Windows kernel is not known to use this bit.
The 32-bit and 64-bit kernels in version 6.1 and higher both set this bit for all processors if all have bit 1 set in ecx from cpuid leaf 6. Both bits are described by Intel as reserved.
The purpose of this bit is to control whether cpuid reveals the availability of functionality that Intel names Execute Disable, but which has become much better known as No Execute. When bit 34 is set in IA32_MISC_ENABLE, cpuid leaf 0x80000001 returns with a clear XD or NX bit (20) in edx.
What the NX bit represents is that the most significant bit in a 64-bit Page Table Entry (PTE) can tell whether the memory that is described by the PTE is non-executable. Note that the NX bit represents only capability. The PTE bit can have this meaning but only if it is enabled, which is done by setting the NXE bit (11) in MSR 0xC0000080, which Intel names IA32_EFER. When this is done, the kernel can enforce a clean separation of code and data: code gets loaded onto pages that can be read and executed and are then ideally not written to; data can be read and written, but ideally is never executed.
That such separation is natural and desirable does not mean that it has always been practical. The kernel did not use the NX functionality until the version 5.1 from Windows XP SP2 and the version 5.2 from Windows Server 2003 SP1. By then and for a few years after, much software, including from Microsoft, was written without respect for these ideals and so the kernel’s enforcement of them was always configurable. A BIOS option to set bit 34 in IA32_MISC_ENABLE was arguably the most severe configuration: with cpuid reporting a clear NX bit, the kernel would not perceive that it even the means to enforce that data is not executable, even if configured to.
In versions 6.2 and 6.3, if the SSE2 bit (26) is set in edx from cpuid leaf 1 and the processor’s vendor string from cpuid leaf 0 is GenuineIntel and this bit in this MSR is set, then the kernel clears the bit. The involvement of the SSE2 bit may be a mystery forever: it is here thought to be a coding error, but with the reservation that it’s difficult to see how such an error could get made.
In version 10, clearing this bit for the boot processor is instead done by the loader (WINLOAD). In contrast to the kernel’s test of the SSE2 bit, the loader tests what is much more easily understood as the right bit. If the XD bit (20) is clear in edx from cpuid leaf 0x80000001 and the processor’s vendor string is GenuineIntel, then the loader clears bit 34 in IA32_MISC_ENABLE. The plain intention is that the XD bit can only have been clear from having been disabled through this MSR and now it should be set. the availability of a No Execute bit in 64-bit page table entries can thence be taken as granted. The loader proceeds immediately to enabling this functionality by setting the NXE bit (11) in MSR 0xC0000080 (IA32_EFER).
This bit is not architectural. The Windows kernel is not known to use this bit.
This bit is not architectural. The Windows kernel is not known to use this bit.
This bit is not architectural. The Windows kernel is not known to use this bit.
This bit is not architectural. The Windows kernel is not known to use this bit.