FeatureBits in the KPRCB

Microsoft’s names for a smattering of the feature bits are known from assembly-language headers KS386.INC and KSAMD64.INC in various development kits, starting with the Device Driver Kit (DDK) for Windows Server 2003 SP1. Names for many feature bits might easily be hypothesised, since most correspond directly to a single bit in output from one or another cpuid leaf. As manageable as that may be, it is unsound since the known names do not fit so straightforward a pattern. Since the known names are so few, they are given not in the table below but in notes at the end.

Mask (x86) Mask (x64) Summary Description Versions
0x00000000`00000001   VME bit (0x00000002) in edx from cpuid leaf 1 3.50 and higher
  0x00000000`00000001 SMEP bit (0x00000080) in ebx from cpuid leaf 7 6.2
0x00000000`00000002 0x00000000`00000002 TSC bit (0x00000010) in edx from cpuid leaf 1 (x86);
always set (x64)
3.50 and higher
0x00000000`00000004 0x00000000`00000004 MCE bit (0x00000080) in edx from cpuid leaf 1 3.50 to 3.51
VME, PSE or PGE bit in edx from cpuid leaf 1 (x86);
always set (x64)
4.0 and higher
0x00000000`00000008 0x00000000`00000008 CMOV bit (0x00008000) in edx from cpuid leaf 1 (x86);
always set (x64)
4.0 and higher
0x00000000`00000010 0x00000000`00000010 PGE bit (0x00002000) in edx from cpuid leaf 1 (x86);
always set (x64)
4.0 and higher
0x00000000`00000020 0x00000000`00000020 PSE bit (0x00000008) in edx from cpuid leaf 1 (x86);
always set (x64)
4.0 and higher
0x00000000`00000040 0x00000000`00000040 MTRR bit (0x00001000) in edx from cpuid leaf 1 (x86);
always set (x64)
4.0 and higher
0x00000000`00000080 0x00000000`00000080 CX8 bit (0x00000100) in edx from cpuid leaf 1 (x86);
always set (x64)
4.0 and higher
0x00000000`00000100 0x00000000`00000100 MMX bit (0x00800000) in edx from cpuid leaf 1 (x86);
always set (x64)
4.0 and higher
0x00000000`00000200   set by default;
clear for some early Intel steppings, see note 
5.0 and higher
  0x00000000`00000200 DS bit (0x00200000) in edx from cpuid leaf 1 late 5.2 to 6.2
0x00000000`00000400 0x00000000`00000400 PAT bit (0x00010000) in edx from cpuid leaf 1 (x86);
always set (x64)
5.0 and higher
0x00000000`00000800 0x00000000`00000800 FXSR bit (0x01000000) in edx from cpuid leaf 1 (x86);
always set (x64)
5.0 and higher
0x00000000`00001000 0x00000000`00001000 SEP bit (0x00000800) in edx from cpuid leaf 1 (x86);
always set (x64)
5.1 and higher
0x00000000`00002000 0x00000000`00002000 SSE bit (0x02000000) in edx from cpuid leaf 1 (x86);
always set (x64)
5.0 and higher
0x00000000`00004000 0x00000000`00004000 3DNow bit (0x80000000) in edx from cpuid leaf 0x80000001 5.0 and higher (x86);
late 5.2 to 6.2 (x64)
0x00000000`00008000   AMD-specific MTRR support 5.0 to 6.1
  0x00000000`00008000    
0x00000000`00010000 0x00000000`00010000 SSE2 bit (0x04000000) in edx from cpuid leaf 1 (x86);
always set (x64)
5.1 and higher
0x00000000`00020000   DS bit (0x00200000) in edx from cpuid leaf 1 5.1 and higher
  0x00000000`00020000 see note 6.1 to 6.2
0x00000000`00040000   HTT bit (0x10000000) in edx from cpuid leaf 1 5.1 only
apparently unused 5.2 only
CLFSH bit (0x00080000) in edx from cpuid leaf 1 6.0 and higher
  0x00000000`00040000    
0x00000000`00080000 0x00000000`00080000 SSE3 bit (0x00000001) in ecx from cpuid leaf 1 6.0 and higher
  0x00000000`00100000 CMPXCHG16B (0x00002000) in ecx from cpuid leaf 1 6.0 to 6.2
0x00000000`00100000 0x00000000`00200000 0x00010000 bit in ecx from cpuid leaf 1 6.0 only
vendor is AuthenticAMD and family is 5 or higher (x86);
vendor is AuthenticAMD (x64)
6.1 and higher
0x00000000`00200000 0x00000000`00400000 0x00000002 bit in ecx from cpuid leaf 6 6.1 and higher
0x00000000`00400000 0x00000000`00800000 see note 6.1 and higher
0x00000000`00800000 0x00000000`01000000 vendor is GenuineIntel 6.1 and higher
0x00000000`01000000   SMEP bit (0x00000080) in ebx from cpuid leaf 7 6.2 and higher
0x00000000`02000000   RDRAND bit (0x40000000) in ecx from cpuid leaf 1 6.3 and higher
  0x00000000`02000000    
0x00000000`04000000 0x00000000`04000000 see note 6.2 and higher
0x00000000`08000000 0x00000000`08000000 see note 6.2 and higher
  0x00000000`10000000 FSGSBASE bit (0x00000001) in ecx from cpuid leaf 7 6.2 and higher
0x00000000`20000000 0x00000000`20000000 NX bit (0x00100000) in edx from cpuid leaf 0x80000001;
always set (x64 in 6.2 and higher)
late 5.2 and higher
0x00000000`40000000 0x00000000`40000000    
0x00000000`80000000 0x00000000`80000000    
  0x00000001`00000000 RDRAND bit (0x40000000) in ecx from cpuid leaf 1 10.0 and higher
  0x00000002`00000000    
0x00000001`00000000 0x00000004`00000000 RDTSCP bit (0x08000000) bit in edx from cpuid leaf 0x80000001 10.0 and higher
0x00000002`00000000   CLFLUSHOPT bit (0x00800000) in ebx from cpuid leaf 7 10.0 and higher
0x00000004`00000000   HDC bit (0x00002000) in eax from cpuid leaf 6 10.0 and higher
0x00000008`00000000      
  0x00000008`00000000    
  0x00000010`00000000    
  0x00000020`00000000 0x04000000 bit in edx from cpuid leaf 0x80000001 1607 and higher
  0x00000040`00000000    
  0x00000080`00000000    
  0x00000100`00000000    
0x00000010`00000000
0x00000200`00000000    

Microsoft’s assembly-language name for the 0x00000001 feature bit is KF_V86_VIS. Versions before 4.0 recognise this feature bit if the vendor is GenuineIntel or AuthenticAMD but then discard it. Version 4.0 extends the recognition to CyrixInstead. Its effect in all known x86 versions is to set the VME bit in cr4 for all processors (though only at startup and not at all if the DisableVme registry value is present).

The name KF_RDTSC is known for the 0x00000002 feature bit in both 32-bit and 64-bit Windows. Again, detection for early versions is restricted to particular vendors: GenuineIntel and AuthenticAMD before version 4.0, adding CyrixInstead in version 4.0.

From Microsoft’s known name KF_CR4 for it in both 32-bit and 64-bit Windows, the 0x00000004 feature bit seems intended to record whether the processor has the cr4 register. There is no direct test for this register’s presence. Intel’s manuals have it that “Control register CR4 was introduced in the Pentium processor” and the kernel’s earliest code for saving and restoring the processor’s control state takes as granted that cr4 can be read and written as long as the CpuType, i.e., processor family, is at least 5. Starting with version 4.0, however, it tests for whether KF_CR4 was discovered for the feature bits. Discovery is by inference. Some features are enabled only by setting a bit in cr4. If cpuid tells that such a feature is present, then presumably cr4 is too. In versions 3.50 and 3.51, this inference is made solely from the MCE feature and only then if the vendor is GenuineIntel. (That said, it is not yet ruled out that the intention truly was to test for the MCE feature.) Version 4.0 looks instead for any of several others:

The 0x00000008, KF_GLOBAL_PAGE and KF_LARGE_PAGE feature bits are detected in version 4.0 only if the vendor is GenuineIntel or CyrixInstead. Though this constraint is abandoned in version 5.0, all later versions until at least the 1803 release of Windows 10 ignore one or more of these features in some early AMD processors. It is not known whether AMD and Intel had different meanings for the PSE, PGE and CMOV bits or whether AMD’s implementation was thought unsafe to use, but all three bits are ignored in the cpuid report of all AuthenticAMD processors whose family is less than 5. In versions 5.1 through 6.1, the PGE bit is ignored for family 5 up to and including model 1 stepping 3.

The 0x00000040 feature bit is detected in version 4.0 only if the vendor is GenuineIntel.

The KF_CMPXCHG8B feature bit is detected in version 4.0 if the vendor is GenuineIntel, AuthenticAMD or CyrixInstead. Version 5.0 removes this restriction. Version 5.1 provides specially for other manufacturers whose processors may have their cpuid instruction report that CX8 is not supported even though they do have a working cmpxchg8b instruction. They’ll have designed their processors this way for the understandable reason that they wanted their wares to work with the original Windows NT 4.0 and its first few service packs.

The 0x00000200 feature bit is cleared for GenuineIntel processors whose family is 6 and either the model is 1 up to and including stepping 9 or the model is 3 up to and including stepping 4. For these early processors, a routine for flushing translation buffers gets patched to an alternative that works synchronously, presumably to correct for a known defect in these processors.

The KF_FAST_SYSCALL feature bit is known to the kernel in version 5.0 as indicating that some returns to user mode can go through the sysexit instruction instead of iret, but no code for detecting the feature is known in any x86 build of Windows 2000. In version 5.1 and higher, support for the SEP feature is ignored in Intel processors that aren’t at least family 6, model 3, stepping 3.

That the KF_FAST_SYSCALL feature bit is necessarily set for 64-bit Windows is presumably because the SYSCALL bit (0x00000800) is set in edx from cpuid leaf 0x80000001.

The 0x00004000 feature bit indicates the AMD-specific 3DNow instruction set. Except on an AuthenticAMD process whose family is less than 5, the kernel executes cpuid leaf 0x80000000 to discover what extended information is available. A return in eax between 0x80000000 and 0x800000FF is taken to be the highest leaf for extended information. If this is at least 0x80000001, then the kernel executes cpuid leaf 0x80000001. If the vendor is AuthenticAMD, then a set 0x80000000 bit in edx indicates support for 3DNow.

The 0x00008000 feature bit is set for AuthenticAMD processors whose family is 5, starting with model 8 stepping 8 and continuing to all steppings of model 9. It indicates that the kernel uses AMD-specific coding when loading Memory Type Range Registers (MTRR). This code, and the feature bit too, was removed for Windows 8.

The 0x00020000 feature bit for 64-bit Windows has the known assembly-language name KF_BRANCH. It is set for processors that the kernel recognises as having Model Specific Registers for keeping a Last Branch Record (LBR). This functionality is assumed for all AMD processors. For Intel processors, it is not so much detected as inferred from the family and model. Version 6.1 recognises it for family 6, models 15, 22, 23 and 26.

That cpuid sets the HTT bit in edx means that information is also returned in ebx to tell of “the Maximum number of addressable IDs for logical processors in this package.” Windows XP extracts this into the KPRCB as the LogicalProcessorsPerPhysicalProcessor member. That it also makes a feature bit of it, 0x00040000, was soon recognised as unnecessary, which gives the first example of a feature bit eventually getting repurposed.

In version 6.0 only, the 0x00100000 feature bit on 64-bit Windows is simply assumed if the vendor is GenuineIntel. For other vendors, and for Intel in later versions, it is set only if availability of the cmpxchg16b instruction is established by the appropriate cpuid query.

The 0x00100000 feature bit is recognised only for GenuineIntel processors in version 6.0.

The 0x00200000 feature bit for 64-bit Windows Vista is recognised only for GenuineIntel processors. The 0x00010000 bit in ecx from cpuid leaf 1 is described by Intel as reserved. The kernel takes it as a cue to enable User-Mode Instruction Prevention (UMIP) by setting the UMIP bit in cr4.

The 0x00200000 and 0x00400000 feature bit for 32-bit and 64-bit Windows, respectively, are recognised only for GenuineIntel processors. It causes the kernel to set the 0x08000000 bit in Model Specific Register 0x01A0 (IA32_MISC_ENABLE) for every processor. Both the cpuid bit for the detection and this MSR bit for the action are described by Intel as reserved.

The 0x01000000 feature bit is recognised only for GenuineIntel processors in versions 6.2 and 6.3. Version 10.0 detects it also for AuthenticAMD processors.

The 0x04000000 feature bit is detected differently for GenuineIntel and AuthenticAMD processors. There is a series of requirements for Intel:

For AMD processors, the test is simply whether the NP bit (0x00000001) is set in edx from cpuid leaf 0x8000000A.

The 0x08000000 feature bit also has different methods of detection for GenuineIntel and AuthenticAMD processors. For Intel:

Again, the test for AMD is seemingly simpler, just whether the 0x00000010 bit is clear in Model Specific Register 0xC0010114.

The 0x20000000 feature bit is the first that depends on extended information from cpuid but is not AMD-specific. The name NX for the 0x00100000 bit in edx from cpuid leaf 0x80000001 is AMD’s. Intel does not name it but describes it as meaning “Execute Disable Bit available.”

The 0x00000002`00000000 and 0x00000004`00000000 feature bits are detected only if the vendor is GenuineIntel. HDC is Hardware Duty Cycling.