ProcessFlags in the KPROCESS

The 32-bit bit fields in union with the ProcessFlags member of the KPROCESS have a complicated history that seems better presented separately from the structure. Notably, new versions bring not just new fields but redefinitions and even changes of type. The original, for the version 5.2 from Windows Server 2003 SP1, was a straightforward tidying up that collected what had been three single-byte booleans, but then someone got exercised about volatility and perhaps someone else later decided it didn’t matter:

Mask Definition Versions Remarks
0x00000001
LONG AutoAlignment : 1;
late 5.2 only previously BOOLEAN at 0x64
LONG volatile AutoAlignment : 1;
6.0 to 6.1  
LONG AutoAlignment : 1;
6.2 and higher  
0x00000002
LONG DisableBoost : 1;
late 5.2 only previously BOOLEAN at 0x67
LONG volatile DisableBoost : 1;
6.0 to 6.1  
LONG DisableBoost : 1;
6.2 and higher  
0x00000004
LONG DisableQuantum : 1;
late 5.2 only previously BOOLEAN at 0x69
LONG volatile DisableQuantum : 1;
6.0 to 6.1  
LONG DisableQuantum : 1;
6.2 and higher  

Additions started in version 6.1—for the ActiveGroupsMask, see further below—but are complicated by insertion and deletion. How version 6.2 added one bit as signed and two as unsigned may forever be anyone’s guess:

Mask Definition Versions
0x00000008 (6.2 to 6.3)
LONG AffinitySet : 1;
6.2 to 6.3
0x00000010 (6.2 to 6.3);
0x00000008
ULONG DeepFreeze : 1;
6.2 and higher
0x00000020 (6.2 to 6.3);
0x00000010
ULONG TimeVirtualization : 1;
6.2 and higher
0x00000040 (6.3);
0x00000020
ULONG CheckStackExtents : 1;
6.3 and higher
0x00000040
ULONG CacheIsolationEnabled : 1;
1803 and higher
0x000000C0 (10.0 to 1709);
0x00000380
ULONG SpareFlags0 : 2;
10.0 to 1607
ULONG PpmPolicy : 2;
1703 to 1709
ULONG PpmPolicy : 3;
1803 and higher

Through many versions, an ActiveGroupsMask is kept as the last of the defined fields, perhaps so that its processor-dependent width does not affect other fields. It even looked as if Windows 10 inserts the SpareFlags0 to align ActiveGroupMasks while leaving space both before for more bits and after for more processor groups. These two bits of spares sufficed at first for the PpmPolicy, but its widening for Version 1803 and the addition of VaSpaceDeleted may have drawn attention to the imminent exhaustion of the ProcessFlags for 64-bit Windows: the 1903 release removes the ActiveGroupsMask to be its own member of the KPROCESS.

Mask (x86) Mask (x64) Definition Versions
0x00000008 (6.1);
0x00000040 (6.2);
0x00000080 (6.3);
0x00000100 (10.0 to 1709);
0x00000400 (1803 to 1809)
0x00000078 (6.1);
0x03FFFFC0 (6.2);
0x07FFFF80 (6.3);
0x0FFFFF00 (10.0 to 1709);
0x3FFFFC00 1803 to 1809)
ULONG volatile ActiveGroupsMask : MAX_PROC_GROUPS;
6.1 only
ULONG ActiveGroupsMask : MAX_PROC_GROUPS;
6.2 to 1809;
next in KPROCESS
0x00000800 (1803 to 1809);
0x00000400
0x40000000 (1803 to 1809);
0x00000400
ULONG VaSpaceDeleted : 1;
1803 and higher
   
LONG ReservedFlags : 29;
late 5.2 only
LONG volatile ReservedFlags : 29;
6.0 only
LONG volatile ReservedFlags : 29 - MAX_PROC_GROUPS;
6.1 only
LONG ReservedFlags : 26 - MAX_PROC_GROUPS;
6.2 only
LONG ReservedFlags : 25 - MAX_PROC_GROUPS;
6.3 only
LONG ReservedFlags : 24 - MAX_PROC_GROUPS;
10.0 to 1709
LONG ReservedFlags : 21 - MAX_PROC_GROUPS;
1803 to 1809
LONG ReservedFlags : 21;
1903 and higher

In the preceding, MAX_PROC_GROUPS is an invented name for the maximum number of processor groups: