From: "Nakajima, Jun" <jun.nakajima@intel.com>

Restore the HT detection algorithm.  Make the processor package mapping
subarch-specific so that it can reflect the APIC ID info provided by BIOS
if required.



 arch/i386/kernel/cpu/intel.c              |   31 +++++++++++++++++++++++-------
 include/asm-i386/genapic.h                |    2 +
 include/asm-i386/mach-bigsmp/mach_apic.h  |    5 ++++
 include/asm-i386/mach-default/mach_apic.h |    5 ++++
 include/asm-i386/mach-es7000/mach_apic.h  |    5 ++++
 include/asm-i386/mach-generic/mach_apic.h |    1 
 include/asm-i386/mach-numaq/mach_apic.h   |    6 +++++
 include/asm-i386/mach-summit/mach_apic.h  |   11 ++++++++++
 include/asm-i386/mach-visws/mach_apic.h   |    6 +++++
 9 files changed, 65 insertions(+), 7 deletions(-)

diff -puN arch/i386/kernel/cpu/intel.c~cpu_sibling_map-fix arch/i386/kernel/cpu/intel.c
--- 25/arch/i386/kernel/cpu/intel.c~cpu_sibling_map-fix	2003-12-30 16:44:35.000000000 -0800
+++ 25-akpm/arch/i386/kernel/cpu/intel.c	2003-12-30 16:44:35.000000000 -0800
@@ -1,5 +1,7 @@
+#include <linux/config.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
+
 #include <linux/string.h>
 #include <linux/bitops.h>
 #include <linux/smp.h>
@@ -11,6 +13,12 @@
 
 #include "cpu.h"
 
+#ifdef CONFIG_X86_LOCAL_APIC
+#include <asm/mpspec.h>
+#include <asm/apic.h>
+#include <mach_apic.h>
+#endif
+
 extern int trap_init_f00f_bug(void);
 
 #ifdef CONFIG_X86_INTEL_USERCOPY
@@ -277,6 +285,7 @@ static void __init init_intel(struct cpu
 		extern	int phys_proc_id[NR_CPUS];
 		
 		u32 	eax, ebx, ecx, edx;
+		int 	index_lsb, index_msb, tmp;
 		int 	cpu = smp_processor_id();
 
 		cpuid(1, &eax, &ebx, &ecx, &edx);
@@ -285,6 +294,8 @@ static void __init init_intel(struct cpu
 		if (smp_num_siblings == 1) {
 			printk(KERN_INFO  "CPU: Hyper-Threading is disabled\n");
 		} else if (smp_num_siblings > 1 ) {
+			index_lsb = 0;
+			index_msb = 31;
 			/*
 			 * At this point we only support two siblings per
 			 * processor package.
@@ -295,13 +306,19 @@ static void __init init_intel(struct cpu
 				smp_num_siblings = 1;
 				goto too_many_siblings;
 			}
-			/* cpuid returns the value latched in the HW at reset,
-			 * not the APIC ID register's value.  For any box
-			 * whose BIOS changes APIC IDs, like clustered APIC
-			 * systems, we must use hard_smp_processor_id.
-			 * See Intel's IA-32 SW Dev's Manual Vol2 under CPUID.
-			 */
-			phys_proc_id[cpu] = hard_smp_processor_id() & ~(smp_num_siblings - 1);
+			tmp = smp_num_siblings;
+			while ((tmp & 1) == 0) {
+				tmp >>=1 ;
+				index_lsb++;
+			}
+			tmp = smp_num_siblings;
+			while ((tmp & 0x80000000 ) == 0) {
+				tmp <<=1 ;
+				index_msb--;
+			}
+			if (index_lsb != index_msb )
+				index_msb++;
+			phys_proc_id[cpu] = phys_pkg_id((ebx >> 24) & 0xFF, index_msb);
 
 			printk(KERN_INFO  "CPU: Physical Processor ID: %d\n",
                                phys_proc_id[cpu]);
diff -puN include/asm-i386/genapic.h~cpu_sibling_map-fix include/asm-i386/genapic.h
--- 25/include/asm-i386/genapic.h~cpu_sibling_map-fix	2003-12-30 16:44:35.000000000 -0800
+++ 25-akpm/include/asm-i386/genapic.h	2003-12-30 16:44:35.000000000 -0800
@@ -45,6 +45,7 @@ struct genapic { 
 	void (*setup_portio_remap)(void); 
 	int (*check_phys_apicid_present)(int boot_cpu_physical_apicid);
 	void (*enable_apic_mode)(void);
+	u32 (*phys_pkg_id)(u32 cpuid_apic, int index_msb);
 
 	/* mpparse */
 	void (*mpc_oem_bus_info)(struct mpc_config_bus *, char *, 
@@ -105,6 +106,7 @@ struct genapic { 
 	APICFUNC(send_IPI_allbutself), \
 	APICFUNC(send_IPI_all), \
 	APICFUNC(enable_apic_mode), \
+	APICFUNC(phys_pkg_id), \
 	}
 
 extern struct genapic *genapic;
diff -puN include/asm-i386/mach-bigsmp/mach_apic.h~cpu_sibling_map-fix include/asm-i386/mach-bigsmp/mach_apic.h
--- 25/include/asm-i386/mach-bigsmp/mach_apic.h~cpu_sibling_map-fix	2003-12-30 16:44:35.000000000 -0800
+++ 25-akpm/include/asm-i386/mach-bigsmp/mach_apic.h	2003-12-30 16:44:35.000000000 -0800
@@ -173,4 +173,9 @@ static inline unsigned int cpu_mask_to_a
 	return apicid;
 }
 
+static inline u32 phys_pkg_id(u32 cpuid_apic, int index_msb)
+{
+	return cpuid_apic >> index_msb;
+}
+
 #endif /* __ASM_MACH_APIC_H */
diff -puN include/asm-i386/mach-default/mach_apic.h~cpu_sibling_map-fix include/asm-i386/mach-default/mach_apic.h
--- 25/include/asm-i386/mach-default/mach_apic.h~cpu_sibling_map-fix	2003-12-30 16:44:35.000000000 -0800
+++ 25-akpm/include/asm-i386/mach-default/mach_apic.h	2003-12-30 16:44:35.000000000 -0800
@@ -127,4 +127,9 @@ static inline void enable_apic_mode(void
 {
 }
 
+static inline u32 phys_pkg_id(u32 cpuid_apic, int index_msb)
+{
+	return cpuid_apic >> index_msb;
+}
+
 #endif /* __ASM_MACH_APIC_H */
diff -puN include/asm-i386/mach-es7000/mach_apic.h~cpu_sibling_map-fix include/asm-i386/mach-es7000/mach_apic.h
--- 25/include/asm-i386/mach-es7000/mach_apic.h~cpu_sibling_map-fix	2003-12-30 16:44:35.000000000 -0800
+++ 25-akpm/include/asm-i386/mach-es7000/mach_apic.h	2003-12-30 16:44:35.000000000 -0800
@@ -192,4 +192,9 @@ static inline unsigned int cpu_mask_to_a
 	return apicid;
 }
 
+static inline u32 phys_pkg_id(u32 cpuid_apic, int index_msb)
+{
+	return cpuid_apic >> index_msb;
+}
+
 #endif /* __ASM_MACH_APIC_H */
diff -puN include/asm-i386/mach-generic/mach_apic.h~cpu_sibling_map-fix include/asm-i386/mach-generic/mach_apic.h
--- 25/include/asm-i386/mach-generic/mach_apic.h~cpu_sibling_map-fix	2003-12-30 16:44:35.000000000 -0800
+++ 25-akpm/include/asm-i386/mach-generic/mach_apic.h	2003-12-30 16:44:35.000000000 -0800
@@ -27,5 +27,6 @@
 #define check_apicid_used (genapic->check_apicid_used)
 #define cpu_mask_to_apicid (genapic->cpu_mask_to_apicid)
 #define enable_apic_mode (genapic->enable_apic_mode)
+#define phys_pkg_id (genapic->phys_pkg_id)
 
 #endif /* __ASM_MACH_APIC_H */
diff -puN include/asm-i386/mach-numaq/mach_apic.h~cpu_sibling_map-fix include/asm-i386/mach-numaq/mach_apic.h
--- 25/include/asm-i386/mach-numaq/mach_apic.h~cpu_sibling_map-fix	2003-12-30 16:44:35.000000000 -0800
+++ 25-akpm/include/asm-i386/mach-numaq/mach_apic.h	2003-12-30 16:44:35.000000000 -0800
@@ -141,4 +141,10 @@ static inline unsigned int cpu_mask_to_a
 	return (int) 0xF;
 }
 
+/* No NUMA-Q box has a HT CPU, but it can't hurt to use the default code. */
+static inline u32 phys_pkg_id(u32 cpuid_apic, int index_msb)
+{
+	return cpuid_apic >> index_msb;
+}
+
 #endif /* __ASM_MACH_APIC_H */
diff -puN include/asm-i386/mach-summit/mach_apic.h~cpu_sibling_map-fix include/asm-i386/mach-summit/mach_apic.h
--- 25/include/asm-i386/mach-summit/mach_apic.h~cpu_sibling_map-fix	2003-12-30 16:44:35.000000000 -0800
+++ 25-akpm/include/asm-i386/mach-summit/mach_apic.h	2003-12-30 16:44:35.000000000 -0800
@@ -173,4 +173,15 @@ static inline unsigned int cpu_mask_to_a
 	return apicid;
 }
 
+/* cpuid returns the value latched in the HW at reset, not the APIC ID
+ * register's value.  For any box whose BIOS changes APIC IDs, like
+ * clustered APIC systems, we must use hard_smp_processor_id.
+ *
+ * See Intel's IA-32 SW Dev's Manual Vol2 under CPUID.
+ */
+static inline u32 phys_pkg_id(u32 cpuid_apic, int index_msb)
+{
+	return hard_smp_processor_id() >> index_msb;
+}
+
 #endif /* __ASM_MACH_APIC_H */
diff -puN include/asm-i386/mach-visws/mach_apic.h~cpu_sibling_map-fix include/asm-i386/mach-visws/mach_apic.h
--- 25/include/asm-i386/mach-visws/mach_apic.h~cpu_sibling_map-fix	2003-12-30 16:44:35.000000000 -0800
+++ 25-akpm/include/asm-i386/mach-visws/mach_apic.h	2003-12-30 16:44:35.000000000 -0800
@@ -88,4 +88,10 @@ static inline unsigned int cpu_mask_to_a
 {
 	return cpus_coerce_const(cpumask);
 }
+
+static inline u32 phys_pkg_id(u32 cpuid_apic, int index_msb)
+{
+	return cpuid_apic >> index_msb;
+}
+
 #endif /* __ASM_MACH_APIC_H */

_