From: James Cleverdon Jun Nakajima is concerned about pulling out the non-power-of-2 code and that someone somewhere besides us might have cpuid APIC numbers that don't agree with the values in the APIC ID register. (And is absolutely not hinting about new CPUs coming down the pipe.) This patch should put the code back and use the sub-arch mechanism to only use APIC ID for Summit. arch/i386/kernel/cpu/intel.c | 24 +++++++++++++++++------- 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, 58 insertions(+), 7 deletions(-) diff -puN arch/i386/kernel/cpu/intel.c~cpu_sibling_map-fixes arch/i386/kernel/cpu/intel.c --- 25/arch/i386/kernel/cpu/intel.c~cpu_sibling_map-fixes 2003-12-16 20:28:55.000000000 -0800 +++ 25-akpm/arch/i386/kernel/cpu/intel.c 2003-12-16 20:28:55.000000000 -0800 @@ -10,6 +10,7 @@ #include #include "cpu.h" +#include "mach_apic.h" extern int trap_init_f00f_bug(void); @@ -277,6 +278,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 +287,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 +299,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-fixes include/asm-i386/genapic.h --- 25/include/asm-i386/genapic.h~cpu_sibling_map-fixes 2003-12-16 20:28:55.000000000 -0800 +++ 25-akpm/include/asm-i386/genapic.h 2003-12-16 20:28:55.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-fixes include/asm-i386/mach-bigsmp/mach_apic.h --- 25/include/asm-i386/mach-bigsmp/mach_apic.h~cpu_sibling_map-fixes 2003-12-16 20:28:55.000000000 -0800 +++ 25-akpm/include/asm-i386/mach-bigsmp/mach_apic.h 2003-12-16 20:28:55.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-fixes include/asm-i386/mach-default/mach_apic.h --- 25/include/asm-i386/mach-default/mach_apic.h~cpu_sibling_map-fixes 2003-12-16 20:28:55.000000000 -0800 +++ 25-akpm/include/asm-i386/mach-default/mach_apic.h 2003-12-16 20:28:55.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-fixes include/asm-i386/mach-es7000/mach_apic.h --- 25/include/asm-i386/mach-es7000/mach_apic.h~cpu_sibling_map-fixes 2003-12-16 20:28:55.000000000 -0800 +++ 25-akpm/include/asm-i386/mach-es7000/mach_apic.h 2003-12-16 20:28:55.000000000 -0800 @@ -191,4 +191,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-fixes include/asm-i386/mach-generic/mach_apic.h --- 25/include/asm-i386/mach-generic/mach_apic.h~cpu_sibling_map-fixes 2003-12-16 20:28:55.000000000 -0800 +++ 25-akpm/include/asm-i386/mach-generic/mach_apic.h 2003-12-16 20:28:55.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-fixes include/asm-i386/mach-numaq/mach_apic.h --- 25/include/asm-i386/mach-numaq/mach_apic.h~cpu_sibling_map-fixes 2003-12-16 20:28:55.000000000 -0800 +++ 25-akpm/include/asm-i386/mach-numaq/mach_apic.h 2003-12-16 20:28:55.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-fixes include/asm-i386/mach-summit/mach_apic.h --- 25/include/asm-i386/mach-summit/mach_apic.h~cpu_sibling_map-fixes 2003-12-16 20:28:55.000000000 -0800 +++ 25-akpm/include/asm-i386/mach-summit/mach_apic.h 2003-12-16 20:28:55.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-fixes include/asm-i386/mach-visws/mach_apic.h --- 25/include/asm-i386/mach-visws/mach_apic.h~cpu_sibling_map-fixes 2003-12-16 20:28:55.000000000 -0800 +++ 25-akpm/include/asm-i386/mach-visws/mach_apic.h 2003-12-16 20:28:55.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 */ _