# This is a BitKeeper generated diff -Nru style patch.
#
# ChangeSet
#   2004/03/17 00:41:44-05:00 len.brown@intel.com 
#   [ACPI] check "maxcpus=N" early -- same as NR_CPUS check.
#   http://bugzilla.kernel.org/show_bug.cgi?id=2317
#   
#   When the BIOS enumerates physical processors before logical,
#   maxcpus=N/2 will now effectively disable HT.
#   
#   This can be verified by boot messages warning that HT is off:
#   eg. "maxcpus=2" on a 2xHT system:
#   
#   Total of 2 processors activated (11141.12 BogoMIPS).
#   WARNING: No sibling found for CPU 0.
#   WARNING: No sibling found for CPU 1.
# 
# arch/x86_64/kernel/smpboot.c
#   2004/03/17 00:25:09-05:00 len.brown@intel.com +1 -16
#   check "maxcpus=N" at processor enumeration-time rather than smpboot-time
# 
# arch/x86_64/kernel/mpparse.c
#   2004/03/17 00:25:09-05:00 len.brown@intel.com +17 -0
#   check "maxcpus=N" at processor enumeration-time rather than smpboot-time
# 
# arch/x86_64/kernel/e820.c
#   2004/03/17 00:25:09-05:00 len.brown@intel.com +12 -0
#   check "maxcpus=N" at processor enumeration-time rather than smpboot-time
# 
# arch/i386/kernel/smpboot.c
#   2004/03/17 00:25:09-05:00 len.brown@intel.com +1 -15
#   check "maxcpus=N" at processor enumeration-time rather than smpboot-time
# 
# arch/i386/kernel/setup.c
#   2004/03/17 00:25:09-05:00 len.brown@intel.com +11 -0
#   check "maxcpus=N" at processor enumeration-time rather than smpboot-time
# 
# arch/i386/kernel/mpparse.c
#   2004/03/17 00:25:09-05:00 len.brown@intel.com +16 -0
#   check "maxcpus=N" at processor enumeration-time rather than smpboot-time
# 
diff -Nru a/arch/i386/kernel/mpparse.c b/arch/i386/kernel/mpparse.c
--- a/arch/i386/kernel/mpparse.c	Wed Mar 17 00:41:47 2004
+++ b/arch/i386/kernel/mpparse.c	Wed Mar 17 00:41:47 2004
@@ -34,6 +34,9 @@
 
 /* Have we found an MP table */
 int smp_found_config;
+#ifdef	CONFIG_SMP
+extern unsigned int max_cpus;
+#endif
 
 /*
  * Various Linux-internal data structures created from the
@@ -228,6 +231,19 @@
 		boot_cpu_physical_apicid = m->mpc_apicid;
 		boot_cpu_logical_apicid = logical_apicid;
 	}
+
+#ifdef	CONFIG_SMP
+	if (num_processors >= NR_CPUS) {
+		printk(KERN_WARNING "WARNING: NR_CPUS limit of %i reached."
+			" Processor ignored.\n", NR_CPUS);
+		return;
+	}
+	if (num_processors >= max_cpus) {
+		printk(KERN_WARNING "WARNING: maxcpus limit of %i reached."
+			" Processor ignored.\n", max_cpus);
+		return;
+	}
+#endif
 
 	num_processors++;
 
diff -Nru a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c
--- a/arch/i386/kernel/setup.c	Wed Mar 17 00:41:47 2004
+++ b/arch/i386/kernel/setup.c	Wed Mar 17 00:41:47 2004
@@ -808,6 +808,17 @@
 				}
 			}
 		}
+#ifdef	CONFIG_SMP
+		/*
+		 * If the BIOS enumerates physical processors before logical,
+		 * maxcpus=N at enumeration-time can be used to disable HT.
+		 */
+		else if (!memcmp(from, "maxcpus=", 8)) {
+			extern unsigned int max_cpus;
+
+			max_cpus = simple_strtoul(from + 8, NULL, 0);
+		}
+#endif
 
 #ifdef CONFIG_ACPI_BOOT
 		/* "acpi=off" disables both ACPI table parsing and interpreter */
diff -Nru a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c
--- a/arch/i386/kernel/smpboot.c	Wed Mar 17 00:41:47 2004
+++ b/arch/i386/kernel/smpboot.c	Wed Mar 17 00:41:47 2004
@@ -51,7 +51,7 @@
 static int smp_b_stepping;
 
 /* Setup configured maximum number of CPUs to activate */
-static int max_cpus = -1;
+unsigned int max_cpus = NR_CPUS;
 
 /* Total count of live CPUs */
 int smp_num_cpus = 1;
@@ -77,10 +77,6 @@
  *
  * Command-line option of "nosmp" or "maxcpus=0" will disable SMP
  * activation entirely (the MPS table probe still happens, though).
- *
- * Command-line option of "maxcpus=<NUM>", where <NUM> is an integer
- * greater than 0, limits the maximum number of CPUs activated in
- * SMP mode to <NUM>.
  */
 
 static int __init nosmp(char *str)
@@ -91,14 +87,6 @@
 
 __setup("nosmp", nosmp);
 
-static int __init maxcpus(char *str)
-{
-	get_option(&str, &max_cpus);
-	return 1;
-}
-
-__setup("maxcpus=", maxcpus);
-
 /*
  * Trampoline 80x86 program as an array.
  */
@@ -1115,8 +1103,6 @@
 			continue;
 
 		if (!(phys_cpu_present_map & (1ul << bit)))
-			continue;
-		if ((max_cpus >= 0) && (max_cpus <= cpucount+1))
 			continue;
 
 		do_boot_cpu(apicid);
diff -Nru a/arch/x86_64/kernel/e820.c b/arch/x86_64/kernel/e820.c
--- a/arch/x86_64/kernel/e820.c	Wed Mar 17 00:41:47 2004
+++ b/arch/x86_64/kernel/e820.c	Wed Mar 17 00:41:47 2004
@@ -540,6 +540,18 @@
 			iommu_setup(from+6); 
 		} 	
 #endif
+#ifdef	CONFIG_SMP
+		/*
+		 * If the BIOS enumerates physical processors before logical,
+		 * maxcpus=N at enumeration-time can be used to disable HT.
+		 */
+		else if (!memcmp(from, "maxcpus=", 8)) {
+			extern unsigned int max_cpus;
+
+			max_cpus = simple_strtoul(from + 8, NULL, 0);
+		}
+#endif
+
 #ifdef        CONFIG_ACPI_BOOT
  		else if (!memcmp(from, "acpi=off", 8))
   			acpi_disabled = 1;
diff -Nru a/arch/x86_64/kernel/mpparse.c b/arch/x86_64/kernel/mpparse.c
--- a/arch/x86_64/kernel/mpparse.c	Wed Mar 17 00:41:47 2004
+++ b/arch/x86_64/kernel/mpparse.c	Wed Mar 17 00:41:47 2004
@@ -35,6 +35,9 @@
 
 /* Have we found an MP table */
 int smp_found_config = 0;
+#ifdef	CONFIG_SMP
+extern unsigned int max_cpus;
+#endif
 
 /*
  * Various Linux-internal data structures created from the
@@ -111,6 +114,20 @@
 		Dprintk("    Bootup CPU\n");
 		boot_cpu_id = m->mpc_apicid;
 	}
+
+#ifdef	CONFIG_SMP
+	if (num_processors >= NR_CPUS) {
+		printk(KERN_WARNING "WARNING: NR_CPUS limit of %i reached."
+			" Processor ignored.\n", NR_CPUS);
+		return;
+	}
+	if (num_processors >= max_cpus) {
+		printk(KERN_WARNING "WARNING: maxcpus limit of %i reached."
+			" Processor ignored.\n", max_cpus);
+		return;
+	}
+#endif
+
 	num_processors++;
 
 	if (m->mpc_apicid > MAX_APICS) {
diff -Nru a/arch/x86_64/kernel/smpboot.c b/arch/x86_64/kernel/smpboot.c
--- a/arch/x86_64/kernel/smpboot.c	Wed Mar 17 00:41:47 2004
+++ b/arch/x86_64/kernel/smpboot.c	Wed Mar 17 00:41:47 2004
@@ -52,7 +52,7 @@
 #include <asm/proto.h>
 
 /* Setup configured maximum number of CPUs to activate */
-static int max_cpus = -1;
+unsigned int max_cpus = NR_CPUS;
 
 static int cpu_mask = -1; 
 
@@ -83,10 +83,6 @@
  *
  * Command-line option of "nosmp" or "maxcpus=0" will disable SMP
  * activation entirely (the MPS table probe still happens, though).
- *
- * Command-line option of "maxcpus=<NUM>", where <NUM> is an integer
- * greater than 0, limits the maximum number of CPUs activated in
- * SMP mode to <NUM>.
  */
 
 static int __init nosmp(char *str)
@@ -97,15 +93,6 @@
 
 __setup("nosmp", nosmp);
 
-static int __init maxcpus(char *str)
-{
-	get_option(&str, &max_cpus);
-	return 1;
-}
-
-__setup("maxcpus=", maxcpus);
-
-
 static int __init cpumask(char *str)
 {
 	get_option(&str, &cpu_mask);
@@ -936,8 +923,6 @@
 		if (!(phys_cpu_present_map & (1 << apicid)))
 			continue;
 		if (((1<<apicid) & cpu_mask) == 0) 
-			continue;
-		if ((max_cpus >= 0) && (max_cpus <= cpucount+1))
 			continue;
 
 		cpu = do_boot_cpu(apicid);
