From: "Andi Kleen" <ak@suse.de>

Separate AMD CMP detection from Hyper Threading detection.  This cleans up the
code a bit and fixes some problems with high CPU IDs.

Signed-off-by: Andi Kleen <ak@suse.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 25-akpm/arch/x86_64/kernel/setup.c |   39 ++++++++++++++++++++++---------------
 1 files changed, 24 insertions(+), 15 deletions(-)

diff -puN arch/x86_64/kernel/setup.c~x86_64-separate-amd-cmp-detection-from-hyper-threading arch/x86_64/kernel/setup.c
--- 25/arch/x86_64/kernel/setup.c~x86_64-separate-amd-cmp-detection-from-hyper-threading	Wed Mar 23 15:38:15 2005
+++ 25-akpm/arch/x86_64/kernel/setup.c	Wed Mar 23 15:38:15 2005
@@ -725,6 +725,25 @@ static void __init display_cacheinfo(str
 	}
 }
 
+/*
+ * Detect CMP (multi core) CPUs.
+ * Don't set up smp_num_siblings here because we don't want
+ * the scheduler to use SMT heuristics.
+ * This uses the AMD specification. Intel CPUs currently don't set
+ * c->x86_num_cores, this will need to be changed later.
+ * TBD: tune the scheduler for multi core.
+ * TBD: This should handle SMT+CMP CPUs.
+ */
+static void __init detect_cmp(struct cpuinfo_x86 *c)
+{
+#ifdef CONFIG_SMP
+	int cpu = smp_processor_id();
+	phys_proc_id[cpu] = c->x86_apicid;
+	if (c->x86_num_cores > 1) {
+		phys_proc_id[cpu] >>= hweight32(c->x86_num_cores - 1);
+	}
+#endif
+}
 
 static int __init init_amd(struct cpuinfo_x86 *c)
 {
@@ -768,6 +787,9 @@ static int __init init_amd(struct cpuinf
 		   When using SRAT use mapping from SRAT. */
 		cpu = c->x86_apicid;
 		if (acpi_numa <= 0 && c->x86_num_cores > 1) {
+			/* There is a node id field in 80000001 EBX
+			   but we assume the BIOS follows the AMD
+			   recommendations. */
 			cpu_to_node[cpu] = cpu >> hweight32(c->x86_num_cores - 1);
 			if (!node_online(cpu_to_node[cpu]))
 				cpu_to_node[cpu] = first_node(node_online_map);
@@ -787,7 +809,7 @@ static void __init detect_ht(struct cpui
 	int 	index_lsb, index_msb, tmp;
 	int 	cpu = smp_processor_id();
 	
-	if (!cpu_has(c, X86_FEATURE_HT))
+	if (!cpu_has(c, X86_FEATURE_HT) || cpu_has(c, X86_FEATURE_CMP_LEGACY))
 		return;
 
 	cpuid(1, &eax, &ebx, &ecx, &edx);
@@ -826,19 +848,6 @@ static void __init detect_ht(struct cpui
 	}
 #endif
 }
-
-static void __init sched_cmp_hack(struct cpuinfo_x86 *c)
-{
-#ifdef CONFIG_SMP
-	/* AMD dual core looks like HT but isn't really. Hide it from the
-	   scheduler. This works around problems with the domain scheduler.
-	   Also probably gives slightly better scheduling and disables
-	   SMT nice which is harmful on dual core.
-	   TBD tune the domain scheduler for dual core. */
-	if (c->x86_vendor == X86_VENDOR_AMD && cpu_has(c, X86_FEATURE_CMP_LEGACY))
-		smp_num_siblings = 1;
-#endif
-}
 	
 static void __init init_intel(struct cpuinfo_x86 *c)
 {
@@ -984,7 +993,7 @@ void __init identify_cpu(struct cpuinfo_
 
 	select_idle_routine(c);
 	detect_ht(c); 
-	sched_cmp_hack(c);
+	detect_cmp(c);
 
 	/*
 	 * On SMP, boot_cpu_data holds the common feature set between
_