diff --git a/ntoskrnl/ex/sysinfo.c b/ntoskrnl/ex/sysinfo.c index 75e3dd452fd..6c6547bf3b8 100644 --- a/ntoskrnl/ex/sysinfo.c +++ b/ntoskrnl/ex/sysinfo.c @@ -664,7 +664,13 @@ QSI_DEF(SystemProcessorInformation) #else Spi->MaximumProcessors = 0; #endif - Spi->ProcessorFeatureBits = KeFeatureBits; + + /* According to Geoff Chappell, on Win 8.1 x64 / Win 10 x86, where this + field is extended to 64 bits, it continues to produce only the low 32 + bits. For the full value, use SYSTEM_PROCESSOR_FEATURES_INFORMATION. + See https://www.geoffchappell.com/studies/windows/km/ntoskrnl/api/ex/sysinfo/processor.htm + */ + Spi->ProcessorFeatureBits = (ULONG)KeFeatureBits; DPRINT("Arch %u Level %u Rev 0x%x\n", Spi->ProcessorArchitecture, Spi->ProcessorLevel, Spi->ProcessorRevision); diff --git a/ntoskrnl/include/internal/i386/ke.h b/ntoskrnl/include/internal/i386/ke.h index 81194e91e0e..596c58b418f 100644 --- a/ntoskrnl/include/internal/i386/ke.h +++ b/ntoskrnl/include/internal/i386/ke.h @@ -462,7 +462,7 @@ NTAPI KiSetProcessorType(VOID); CODE_SEG("INIT") -ULONG +ULONG64 NTAPI KiGetFeatureBits(VOID); diff --git a/ntoskrnl/include/internal/ke.h b/ntoskrnl/include/internal/ke.h index c5fcd5b8af3..5af00103476 100644 --- a/ntoskrnl/include/internal/ke.h +++ b/ntoskrnl/include/internal/ke.h @@ -103,7 +103,7 @@ extern BOOLEAN ExCmosClockIsSane; extern USHORT KeProcessorArchitecture; extern USHORT KeProcessorLevel; extern USHORT KeProcessorRevision; -extern ULONG KeFeatureBits; +extern ULONG64 KeFeatureBits; extern KNODE KiNode0; extern PKNODE KeNodeBlock[1]; extern UCHAR KeNumberNodes; diff --git a/ntoskrnl/ke/amd64/krnlinit.c b/ntoskrnl/ke/amd64/krnlinit.c index d7aea4db738..f580cacbba9 100644 --- a/ntoskrnl/ke/amd64/krnlinit.c +++ b/ntoskrnl/ke/amd64/krnlinit.c @@ -233,7 +233,7 @@ KiInitializeKernel(IN PKPROCESS InitProcess, ULONG i; /* Set boot-level flags */ - KeFeatureBits = Prcb->FeatureBits; + KeFeatureBits = Prcb->FeatureBits | (ULONG64)Prcb->FeatureBitsHigh << 32; /* Initialize 8/16 bit SList support */ RtlpUse16ByteSLists = (KeFeatureBits & KF_CMPXCHG16B) ? TRUE : FALSE; diff --git a/ntoskrnl/ke/i386/cpu.c b/ntoskrnl/ke/i386/cpu.c index 598a21d9de1..ab639340443 100644 --- a/ntoskrnl/ke/i386/cpu.c +++ b/ntoskrnl/ke/i386/cpu.c @@ -209,13 +209,13 @@ KiSetProcessorType(VOID) } CODE_SEG("INIT") -ULONG +ULONG64 NTAPI KiGetFeatureBits(VOID) { PKPRCB Prcb = KeGetCurrentPrcb(); ULONG Vendor; - ULONG FeatureBits = KF_WORKING_PTE; + ULONG64 FeatureBits = KF_WORKING_PTE; CPU_INFO CpuInfo, DummyCpuInfo; UCHAR Ccr1; BOOLEAN ExtendedCPUID = TRUE; diff --git a/ntoskrnl/ke/i386/kiinit.c b/ntoskrnl/ke/i386/kiinit.c index e3ec9ed94bf..4d576e86f8a 100644 --- a/ntoskrnl/ke/i386/kiinit.c +++ b/ntoskrnl/ke/i386/kiinit.c @@ -384,7 +384,7 @@ KiVerifyCpuFeatures(PKPRCB Prcb) KeBugCheckEx(UNSUPPORTED_PROCESSOR, 0x386, 0, 0, 0); // 3. Finally, obtain CPU features. - ULONG FeatureBits = KiGetFeatureBits(); + ULONG64 FeatureBits = KiGetFeatureBits(); // 4. Verify it supports everything we need. if (!(FeatureBits & KF_RDTSC)) @@ -423,7 +423,8 @@ KiVerifyCpuFeatures(PKPRCB Prcb) } // 5. Save feature bits. - Prcb->FeatureBits = FeatureBits; + Prcb->FeatureBits = (ULONG)FeatureBits; + Prcb->FeatureBitsHigh = FeatureBits >> 32; } CODE_SEG("INIT") @@ -445,7 +446,7 @@ KiInitializeKernel(IN PKPROCESS InitProcess, /* Set boot-level flags */ if (Number == 0) - KeFeatureBits = Prcb->FeatureBits; + KeFeatureBits = Prcb->FeatureBits | (ULONG64)Prcb->FeatureBitsHigh << 32; /* Set the default NX policy (opt-in) */ SharedUserData->NXSupportPolicy = NX_SUPPORT_POLICY_OPTIN; diff --git a/ntoskrnl/ke/krnlinit.c b/ntoskrnl/ke/krnlinit.c index 4ffdb0bd104..edb455abfc5 100644 --- a/ntoskrnl/ke/krnlinit.c +++ b/ntoskrnl/ke/krnlinit.c @@ -19,7 +19,7 @@ USHORT KeProcessorArchitecture; USHORT KeProcessorLevel; USHORT KeProcessorRevision; -ULONG KeFeatureBits; +ULONG64 KeFeatureBits; /* System call count */ ULONG KiServiceLimit = NUMBER_OF_SYSCALLS; diff --git a/sdk/include/ndk/amd64/ketypes.h b/sdk/include/ndk/amd64/ketypes.h index 08c94196db3..5d65d4a3508 100644 --- a/sdk/include/ndk/amd64/ketypes.h +++ b/sdk/include/ndk/amd64/ketypes.h @@ -939,8 +939,11 @@ typedef struct _KPRCB ULONG CacheCount; #endif #ifdef __REACTOS__ +#if (NTDDI_VERSION < NTDDI_WINBLUE) + // On Win 8.1+ the FeatureBits field is extended to 64 bits ULONG FeatureBitsHigh; #endif +#endif } KPRCB, *PKPRCB; // diff --git a/sdk/include/ndk/extypes.h b/sdk/include/ndk/extypes.h index 2b190f1ca30..251a7a0e6f2 100644 --- a/sdk/include/ndk/extypes.h +++ b/sdk/include/ndk/extypes.h @@ -761,7 +761,11 @@ typedef struct _SYSTEM_PROCESSOR_INFORMATION #else USHORT MaximumProcessors; #endif +#if (NTDDI_VERSION >= NTDDI_WIN10) || ((NTDDI_VERSION >= NTDDI_WINBLUE) && defined(_WIN64)) + ULONG64 ProcessorFeatureBits; +#else ULONG ProcessorFeatureBits; +#endif } SYSTEM_PROCESSOR_INFORMATION, *PSYSTEM_PROCESSOR_INFORMATION; // Class 2 diff --git a/sdk/include/ndk/i386/ketypes.h b/sdk/include/ndk/i386/ketypes.h index 757fd4e82d4..e97f243b6c0 100644 --- a/sdk/include/ndk/i386/ketypes.h +++ b/sdk/include/ndk/i386/ketypes.h @@ -781,6 +781,12 @@ typedef struct _KPRCB ULONG PackageProcessorSet; ULONG CoreProcessorSet; #endif +#ifdef __REACTOS__ +#if (NTDDI_VERSION < NTDDI_WIN10) + // On Win 10+ the FeatureBits field is extended to 64 bits + ULONG FeatureBitsHigh; +#endif +#endif } KPRCB, *PKPRCB; //