https://git.reactos.org/?p=reactos.git;a=commitdiff;h=fa52f2fae0b73ca10e18fe187b0dff16cfaabfc8

commit fa52f2fae0b73ca10e18fe187b0dff16cfaabfc8
Author:     Marcus Boillat <[email protected]>
AuthorDate: Sun May 8 19:27:27 2022 +0200
Commit:     Stanislav Motylkov <[email protected]>
CommitDate: Mon May 9 21:50:24 2022 +0300

    [NTOS:KE] Fix CPU extended family and model detection
    
    Based on documentation from Geoff Chappell:
    https://www.geoffchappell.com/studies/windows/km/cpu/cpuid/00000001h/eax.htm
    
    CORE-17974
---
 ntoskrnl/ke/amd64/cpu.c | 29 +++++++++++++++++++++++++++--
 ntoskrnl/ke/i386/cpu.c  | 23 +++++++++++++++++++++++
 2 files changed, 50 insertions(+), 2 deletions(-)

diff --git a/ntoskrnl/ke/amd64/cpu.c b/ntoskrnl/ke/amd64/cpu.c
index 4ed7e5470fe..d4a8888c664 100644
--- a/ntoskrnl/ke/amd64/cpu.c
+++ b/ntoskrnl/ke/amd64/cpu.c
@@ -98,7 +98,11 @@ KiSetProcessorType(VOID)
 {
     CPU_INFO CpuInfo;
     CPU_SIGNATURE CpuSignature;
-    ULONG Stepping, Type;
+    BOOLEAN ExtendModel;
+    ULONG Stepping, Type, Vendor;
+
+    /* This initializes Prcb->CpuVendor */
+    Vendor = KiGetCpuVendor();
 
     /* Do CPUID 1 now */
     KiCpuId(&CpuInfo, 1);
@@ -111,8 +115,29 @@ KiSetProcessorType(VOID)
      */
     CpuSignature.AsULONG = CpuInfo.Eax;
     Stepping = CpuSignature.Model;
+    ExtendModel = (CpuSignature.Family == 15);
+#if ( (NTDDI_VERSION >= NTDDI_WINXPSP2) && (NTDDI_VERSION < NTDDI_WS03) ) || 
(NTDDI_VERSION >= NTDDI_WS03SP1)
+    if (CpuSignature.Family == 6)
+    {
+        ExtendModel |= (Vendor == CPU_INTEL);
+#if (NTDDI_VERSION >= NTDDI_WIN8)
+        ExtendModel |= (Vendor == CPU_CENTAUR);
+#endif
+    }
+#endif
+    if (ExtendModel)
+    {
+        /* Add ExtendedModel to distinguish from non-extended values. */
+        Stepping |= (CpuSignature.ExtendedModel << 4);
+    }
     Stepping = (Stepping << 8) | CpuSignature.Step;
     Type = CpuSignature.Family;
+    if (CpuSignature.Family == 15)
+    {
+        /* Add ExtendedFamily to distinguish from non-extended values.
+         * It must not be larger than 0xF0 to avoid overflow. */
+        Type += min(CpuSignature.ExtendedFamily, 0xF0);
+    }
 
     /* Save them in the PRCB */
     KeGetCurrentPrcb()->CpuID = TRUE;
@@ -130,7 +155,7 @@ KiGetFeatureBits(VOID)
     CPU_INFO CpuInfo;
 
     /* Get the Vendor ID */
-    Vendor = KiGetCpuVendor();
+    Vendor = Prcb->CpuVendor;
 
     /* Make sure we got a valid vendor ID at least. */
     if (!Vendor) return FeatureBits;
diff --git a/ntoskrnl/ke/i386/cpu.c b/ntoskrnl/ke/i386/cpu.c
index 711070eeb07..0e4b8fa8468 100644
--- a/ntoskrnl/ke/i386/cpu.c
+++ b/ntoskrnl/ke/i386/cpu.c
@@ -159,6 +159,7 @@ KiSetProcessorType(VOID)
 {
     CPU_INFO CpuInfo;
     CPU_SIGNATURE CpuSignature;
+    BOOLEAN ExtendModel;
     ULONG Stepping, Type;
 
     /* Do CPUID 1 now */
@@ -172,8 +173,30 @@ KiSetProcessorType(VOID)
      */
     CpuSignature.AsULONG = CpuInfo.Eax;
     Stepping = CpuSignature.Model;
+    ExtendModel = (CpuSignature.Family == 15);
+#if ( (NTDDI_VERSION >= NTDDI_WINXPSP2) && (NTDDI_VERSION < NTDDI_WS03) ) || 
(NTDDI_VERSION >= NTDDI_WS03SP1)
+    if (CpuSignature.Family == 6)
+    {
+        ULONG Vendor = KiGetCpuVendor();
+        ExtendModel |= (Vendor == CPU_INTEL);
+#if (NTDDI_VERSION >= NTDDI_WIN8)
+        ExtendModel |= (Vendor == CPU_CENTAUR);
+#endif
+    }
+#endif
+    if (ExtendModel)
+    {
+        /* Add ExtendedModel to distinguish from non-extended values. */
+        Stepping |= (CpuSignature.ExtendedModel << 4);
+    }
     Stepping = (Stepping << 8) | CpuSignature.Step;
     Type = CpuSignature.Family;
+    if (CpuSignature.Family == 15)
+    {
+        /* Add ExtendedFamily to distinguish from non-extended values.
+         * It must not be larger than 0xF0 to avoid overflow. */
+        Type += min(CpuSignature.ExtendedFamily, 0xF0);
+    }
 
     /* Save them in the PRCB */
     KeGetCurrentPrcb()->CpuID = TRUE;

Reply via email to