From: "Nakajima, Jun" 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 #include #include + #include #include #include @@ -11,6 +13,12 @@ #include "cpu.h" +#ifdef CONFIG_X86_LOCAL_APIC +#include +#include +#include +#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 */ _