diff --git a/hal/halx86/generic/halinit.c b/hal/halx86/generic/halinit.c index cc962bdb4c9..22561c19931 100644 --- a/hal/halx86/generic/halinit.c +++ b/hal/halx86/generic/halinit.c @@ -14,6 +14,9 @@ /* GLOBALS *******************************************************************/ +//#ifdef CONFIG_SMP // FIXME: Reenable conditional once HAL is consistently compiled for SMP mode +BOOLEAN HalpOnlyBootProcessor; +//#endif BOOLEAN HalpPciLockSettings; /* PRIVATE FUNCTIONS *********************************************************/ @@ -30,6 +33,12 @@ HalpGetParameters( /* Read the command line */ PCSTR CommandLine = LoaderBlock->LoadOptions; +//#ifdef CONFIG_SMP // FIXME: Reenable conditional once HAL is consistently compiled for SMP mode + /* Check whether we should only start one CPU */ + if (strstr(CommandLine, "ONECPU")) + HalpOnlyBootProcessor = TRUE; +//#endif + /* Check if PCI is locked */ if (strstr(CommandLine, "PCILOCK")) HalpPciLockSettings = TRUE; diff --git a/hal/halx86/smp/i386/spinup.c b/hal/halx86/smp/i386/spinup.c index 12fbea168cb..359cc30d657 100644 --- a/hal/halx86/smp/i386/spinup.c +++ b/hal/halx86/smp/i386/spinup.c @@ -16,6 +16,8 @@ /* GLOBALS *******************************************************************/ +extern BOOLEAN HalpOnlyBootProcessor; + extern PPROCESSOR_IDENTITY HalpProcessorIdentity; extern PHYSICAL_ADDRESS HalpLowStubPhysicalAddress; extern PVOID HalpLowStub; @@ -88,6 +90,11 @@ HalStartNextProcessor( _In_ PLOADER_PARAMETER_BLOCK LoaderBlock, _In_ PKPROCESSOR_STATE ProcessorState) { + /* Bail out if we only use the boot CPU */ + if (HalpOnlyBootProcessor) + return FALSE; + + /* Bail out if we have started all available CPUs */ if (HalpStartedProcessorCount == HalpApicInfoTable.ProcessorCount) return FALSE; diff --git a/ntoskrnl/ex/init.c b/ntoskrnl/ex/init.c index 6393a1083f9..179a357b32e 100644 --- a/ntoskrnl/ex/init.c +++ b/ntoskrnl/ex/init.c @@ -1559,6 +1559,34 @@ Phase1InitializationDiscard(IN PVOID Context) } #ifdef CONFIG_SMP + /* + * IMPORTANT NOTE: + * Because ReactOS is a "nice" OS, we do not care _at all_ + * about any number of registered/licensed processors: + * no usage of KeRegisteredProcessors nor KeLicensedProcessors. + */ + if (CommandLine) + { + PSTR Option; + + /* Check for NUMPROC: maximum number of logical processors + * that can be started (including dynamically) at run-time */ + Option = strstr(CommandLine, "NUMPROC"); + if (Option) Option = strstr(Option, "="); + if (Option) KeNumprocSpecified = atol(Option + 1); + + /* Check for BOOTPROC (NT6+ and ReactOS): maximum number + * of logical processors that can be started at boot-time */ + Option = strstr(CommandLine, "BOOTPROC"); + if (Option) Option = strstr(Option, "="); + if (Option) KeBootprocSpecified = atol(Option + 1); + + /* Check for MAXPROC (NT6+ and ReactOS): forces the kernel to report + * as existing the maximum number of processors that can be handled */ + if (strstr(CommandLine, "MAXPROC")) + KeMaximumProcessors = MAXIMUM_PROCESSORS; + } + /* Start Application Processors */ KeStartAllProcessors(); #endif diff --git a/ntoskrnl/include/internal/ke.h b/ntoskrnl/include/internal/ke.h index 40a45385c92..3efa907e309 100644 --- a/ntoskrnl/include/internal/ke.h +++ b/ntoskrnl/include/internal/ke.h @@ -90,7 +90,6 @@ typedef PCHAR IN ULONG Length ); -extern KAFFINITY KeActiveProcessors; extern PKNMI_HANDLER_CALLBACK KiNmiCallbackListHead; extern KSPIN_LOCK KiNmiCallbackListLock; extern PVOID KeUserApcDispatcher; @@ -104,6 +103,13 @@ extern USHORT KeProcessorArchitecture; extern USHORT KeProcessorLevel; extern USHORT KeProcessorRevision; extern ULONG64 KeFeatureBits; +extern KAFFINITY KeActiveProcessors; +extern PKPRCB KiProcessorBlock[]; +#ifdef CONFIG_SMP +extern ULONG KeMaximumProcessors; +extern ULONG KeNumprocSpecified; +extern ULONG KeBootprocSpecified; +#endif extern KNODE KiNode0; extern PKNODE KeNodeBlock[1]; extern UCHAR KeNumberNodes; @@ -136,7 +142,6 @@ extern LIST_ENTRY KiProcessListHead; extern LIST_ENTRY KiProcessInSwapListHead, KiProcessOutSwapListHead; extern LIST_ENTRY KiStackInSwapListHead; extern KEVENT KiSwapEvent; -extern PKPRCB KiProcessorBlock[]; extern KAFFINITY KiIdleSummary; extern PVOID KeUserApcDispatcher; extern PVOID KeUserCallbackDispatcher; diff --git a/ntoskrnl/ke/i386/mproc.c b/ntoskrnl/ke/i386/mproc.c index 63e7a748bd1..e3e05191dfc 100644 --- a/ntoskrnl/ke/i386/mproc.c +++ b/ntoskrnl/ke/i386/mproc.c @@ -9,6 +9,7 @@ /* INCLUDES *****************************************************************/ #include + #define NDEBUG #include @@ -38,12 +39,28 @@ NTAPI KeStartAllProcessors(VOID) { PVOID KernelStack, DPCStack; - ULONG ProcessorCount = 0; PAPINFO APInfo; + ULONG ProcessorCount; + ULONG MaximumProcessors; - while (TRUE) + /* NOTE: NT6+ HAL exports HalEnumerateProcessors() and + * HalQueryMaximumProcessorCount() that help determining + * the number of detected processors on the system. */ + MaximumProcessors = KeMaximumProcessors; + + /* Limit the number of processors we can start at run-time */ + if (KeNumprocSpecified) + MaximumProcessors = min(MaximumProcessors, KeNumprocSpecified); + + /* Limit also the number of processors we can start during boot-time */ + if (KeBootprocSpecified) + MaximumProcessors = min(MaximumProcessors, KeBootprocSpecified); + + // TODO: Support processor nodes + + /* Start ProcessorCount at 1 because we already have the boot CPU */ + for (ProcessorCount = 1; ProcessorCount < MaximumProcessors; ++ProcessorCount) { - ProcessorCount++; KernelStack = NULL; DPCStack = NULL; diff --git a/ntoskrnl/ke/processor.c b/ntoskrnl/ke/processor.c index 157bd34ab77..48e6b11fe6d 100644 --- a/ntoskrnl/ke/processor.c +++ b/ntoskrnl/ke/processor.c @@ -13,9 +13,27 @@ /* GLOBALS *******************************************************************/ -CCHAR KeNumberProcessors = 0; KAFFINITY KeActiveProcessors = 0; +/* Number of processors */ +CCHAR KeNumberProcessors = 0; + +#ifdef CONFIG_SMP + +/* Theoretical maximum number of processors that can be handled. + * Set once at run-time. Returned by KeQueryMaximumProcessorCount(). */ +ULONG KeMaximumProcessors = MAXIMUM_PROCESSORS; + +/* Maximum number of logical processors that can be started + * (including dynamically) at run-time. If 0: do not perform checks. */ +ULONG KeNumprocSpecified = 0; + +/* Maximum number of logical processors that can be started + * at boot-time. If 0: do not perform checks. */ +ULONG KeBootprocSpecified = 0; + +#endif // CONFIG_SMP + /* FUNCTIONS *****************************************************************/ KAFFINITY