From 705e07ce3150473de09c12457023b0a773370b59 Mon Sep 17 00:00:00 2001 From: Victor Perevertkin Date: Sat, 15 Jan 2022 03:24:55 +0300 Subject: [PATCH] [NTOS:KE] Move CPU features detection to a separate function on i586 --- ntoskrnl/ke/i386/kiinit.c | 86 ++++++++++++++++++++++----------------- 1 file changed, 49 insertions(+), 37 deletions(-) diff --git a/ntoskrnl/ke/i386/kiinit.c b/ntoskrnl/ke/i386/kiinit.c index c8a9872b519..5c24902d2e5 100644 --- a/ntoskrnl/ke/i386/kiinit.c +++ b/ntoskrnl/ke/i386/kiinit.c @@ -392,6 +392,46 @@ KiInitializePcr(IN ULONG ProcessorNumber, Pcr->PrcbData.MultiThreadProcessorSet = Pcr->PrcbData.SetMember; } +static +CODE_SEG("INIT") +VOID +KiVerifyCpuFeatures(PKPRCB Prcb) +{ + ULONG FeatureBits; + + /* Detect and set the CPU Type */ + KiSetProcessorType(); + + /* Check if an FPU is present */ + KeI386NpxPresent = KiIsNpxPresent(); + + /* Bugcheck if this is a 386 CPU */ + if (Prcb->CpuType == 3) + KeBugCheckEx(UNSUPPORTED_PROCESSOR, 0x386, 0, 0, 0); + + /* Get the processor features for the CPU */ + FeatureBits = KiGetFeatureBits(); + + /* Detect 8-byte compare exchange support */ + if (!(FeatureBits & KF_CMPXCHG8B)) + { + ULONG Vendor[3]; + + /* Copy the vendor string */ + RtlCopyMemory(Vendor, Prcb->VendorString, sizeof(Vendor)); + + /* Bugcheck the system. Windows *requires* this */ + KeBugCheckEx(UNSUPPORTED_PROCESSOR, + (1 << 24 ) | (Prcb->CpuType << 16) | Prcb->CpuStep, + Vendor[0], + Vendor[1], + Vendor[2]); + } + + /* Save feature bits */ + Prcb->FeatureBits = FeatureBits; +} + CODE_SEG("INIT") VOID NTAPI @@ -402,27 +442,16 @@ KiInitializeKernel(IN PKPROCESS InitProcess, IN CCHAR Number, IN PLOADER_PARAMETER_BLOCK LoaderBlock) { - BOOLEAN NpxPresent; - ULONG FeatureBits; ULONG PageDirectory[2]; PVOID DpcStack; - ULONG Vendor[3]; KIRQL DummyIrql; - /* Detect and set the CPU Type */ - KiSetProcessorType(); - - /* Check if an FPU is present */ - NpxPresent = KiIsNpxPresent(); - /* Initialize the Power Management Support for this PRCB */ PoInitializePrcb(Prcb); - /* Bugcheck if this is a 386 CPU */ - if (Prcb->CpuType == 3) KeBugCheckEx(UNSUPPORTED_PROCESSOR, 0x386, 0, 0, 0); - - /* Get the processor features for the CPU */ - FeatureBits = KiGetFeatureBits(); + /* Set boot-level flags */ + if (Number == 0) + KeFeatureBits = Prcb->FeatureBits; /* Set the default NX policy (opt-in) */ SharedUserData->NXSupportPolicy = NX_SUPPORT_POLICY_OPTIN; @@ -432,31 +461,28 @@ KiInitializeKernel(IN PKPROCESS InitProcess, { /* Set it always on */ SharedUserData->NXSupportPolicy = NX_SUPPORT_POLICY_ALWAYSON; - FeatureBits |= KF_NX_ENABLED; + KeFeatureBits |= KF_NX_ENABLED; } else if (strstr(KeLoaderBlock->LoadOptions, "NOEXECUTE=OPTOUT")) { /* Set it in opt-out mode */ SharedUserData->NXSupportPolicy = NX_SUPPORT_POLICY_OPTOUT; - FeatureBits |= KF_NX_ENABLED; + KeFeatureBits |= KF_NX_ENABLED; } else if ((strstr(KeLoaderBlock->LoadOptions, "NOEXECUTE=OPTIN")) || (strstr(KeLoaderBlock->LoadOptions, "NOEXECUTE"))) { /* Set the feature bits */ - FeatureBits |= KF_NX_ENABLED; + KeFeatureBits |= KF_NX_ENABLED; } else if ((strstr(KeLoaderBlock->LoadOptions, "NOEXECUTE=ALWAYSOFF")) || (strstr(KeLoaderBlock->LoadOptions, "EXECUTE"))) { /* Set disabled mode */ SharedUserData->NXSupportPolicy = NX_SUPPORT_POLICY_ALWAYSOFF; - FeatureBits |= KF_NX_DISABLED; + KeFeatureBits |= KF_NX_DISABLED; } - /* Save feature bits */ - Prcb->FeatureBits = FeatureBits; - /* Save CPU state */ KiSaveProcessorControlState(&Prcb->ProcessorState); @@ -475,30 +501,14 @@ KiInitializeKernel(IN PKPROCESS InitProcess, KeNodeBlock[0]->ProcessorMask = Prcb->SetMember; /* Set boot-level flags */ - KeI386NpxPresent = NpxPresent; KeI386CpuType = Prcb->CpuType; KeI386CpuStep = Prcb->CpuStep; KeProcessorArchitecture = PROCESSOR_ARCHITECTURE_INTEL; KeProcessorLevel = (USHORT)Prcb->CpuType; if (Prcb->CpuID) KeProcessorRevision = Prcb->CpuStep; - KeFeatureBits = FeatureBits; KeI386FxsrPresent = (KeFeatureBits & KF_FXSR) ? TRUE : FALSE; KeI386XMMIPresent = (KeFeatureBits & KF_XMMI) ? TRUE : FALSE; - /* Detect 8-byte compare exchange support */ - if (!(KeFeatureBits & KF_CMPXCHG8B)) - { - /* Copy the vendor string */ - RtlCopyMemory(Vendor, Prcb->VendorString, sizeof(Vendor)); - - /* Bugcheck the system. Windows *requires* this */ - KeBugCheckEx(UNSUPPORTED_PROCESSOR, - (1 << 24 ) | (Prcb->CpuType << 16) | Prcb->CpuStep, - Vendor[0], - Vendor[1], - Vendor[2]); - } - /* Set the current MP Master KPRCB to the Boot PRCB */ Prcb->MultiThreadSetMaster = Prcb; @@ -813,6 +823,8 @@ AppCpuInit: __writefsdword(KPCR_SET_MEMBER_COPY, 1 << Cpu); __writefsdword(KPCR_PRCB_SET_MEMBER, 1 << Cpu); + KiVerifyCpuFeatures(Pcr->Prcb); + /* Initialize the Processor with HAL */ HalInitializeProcessor(Cpu, KeLoaderBlock);