From: William Lee Irwin III The following patch repairs kicking of non-present cpus by making cpu_present_to_apicid() bounds-check its argument. It also corrects the same issue on NUMA-Q by correctly passing the generated artificial APIC ID instead of the raw value discovered in the MP table. A miscellaneous compilefix for CONFIG_ACPI_BOOT is also included for completeness. Signed-off-by: Andrew Morton --- 25-akpm/arch/i386/kernel/io_apic.c | 2 +- 25-akpm/arch/i386/kernel/mpparse.c | 8 ++++---- 25-akpm/include/asm-i386/apic.h | 2 ++ 25-akpm/include/asm-i386/mach-default/mach_apic.h | 5 ++++- 25-akpm/include/asm-i386/mach-visws/mach_apic.h | 5 ++++- 5 files changed, 15 insertions(+), 7 deletions(-) diff -puN arch/i386/kernel/io_apic.c~apic-fix-kicking-of-non-present-cpus arch/i386/kernel/io_apic.c --- 25/arch/i386/kernel/io_apic.c~apic-fix-kicking-of-non-present-cpus Wed Jun 9 14:45:58 2004 +++ 25-akpm/arch/i386/kernel/io_apic.c Wed Jun 9 14:45:58 2004 @@ -722,7 +722,7 @@ static int __init ioapic_pirq_setup(char __setup("pirq=", ioapic_pirq_setup); -static int get_physical_broadcast(void) +int get_physical_broadcast(void) { unsigned int lvr, version; lvr = apic_read(APIC_LVR); diff -puN arch/i386/kernel/mpparse.c~apic-fix-kicking-of-non-present-cpus arch/i386/kernel/mpparse.c --- 25/arch/i386/kernel/mpparse.c~apic-fix-kicking-of-non-present-cpus Wed Jun 9 14:45:58 2004 +++ 25-akpm/arch/i386/kernel/mpparse.c Wed Jun 9 14:45:58 2004 @@ -107,7 +107,7 @@ static struct mpc_config_translation *tr #ifdef CONFIG_X86_NUMAQ static int MP_valid_apicid(int apicid, int version) { - return hweight_long(i & 0xf) == 1 && (i >> 4) != 0xf; + return hweight_long(apicid & 0xf) == 1 && (apicid >> 4) != 0xf; } #else static int MP_valid_apicid(int apicid, int version) @@ -207,7 +207,7 @@ void __init MP_processor_info (struct mp num_processors++; ver = m->mpc_apicver; - if (MP_valid_apicid(m->mpc_apicid, ver)) + if (MP_valid_apicid(apicid, ver)) MP_mark_version_physids(ver); else { printk(KERN_WARNING "Processor #%d INVALID. (Max ID: %d).\n", @@ -871,7 +871,7 @@ void __init mp_register_lapic ( MP_processor_info(&processor); } -#if defined(CONFIG_X86_IO_APIC) && defined(CONFIG_ACPI_INTERPRETER) +#if defined(CONFIG_X86_IO_APIC) && (defined(CONFIG_ACPI_INTERPRETER) || defined(CONFIG_ACPI_BOOT)) #define MP_ISA_BUS 0 #define MP_MAX_IOAPIC_PIN 127 @@ -1103,5 +1103,5 @@ void mp_register_gsi (u32 gsi, int edge_ active_high_low == ACPI_ACTIVE_HIGH ? 0 : 1); } -#endif /*CONFIG_X86_IO_APIC && CONFIG_ACPI_INTERPRETER*/ +#endif /*CONFIG_X86_IO_APIC && (CONFIG_ACPI_INTERPRETER || CONFIG_ACPI_BOOT)*/ #endif /*CONFIG_ACPI_BOOT*/ diff -puN include/asm-i386/apic.h~apic-fix-kicking-of-non-present-cpus include/asm-i386/apic.h --- 25/include/asm-i386/apic.h~apic-fix-kicking-of-non-present-cpus Wed Jun 9 14:45:58 2004 +++ 25-akpm/include/asm-i386/apic.h Wed Jun 9 14:45:58 2004 @@ -41,6 +41,8 @@ static __inline__ void apic_wait_icr_idl do { } while ( apic_read( APIC_ICR ) & APIC_ICR_BUSY ); } +int get_physical_broadcast(void); + #ifdef CONFIG_X86_GOOD_APIC # define FORCE_READ_AROUND_WRITE 0 # define apic_read_around(x) diff -puN include/asm-i386/mach-default/mach_apic.h~apic-fix-kicking-of-non-present-cpus include/asm-i386/mach-default/mach_apic.h --- 25/include/asm-i386/mach-default/mach_apic.h~apic-fix-kicking-of-non-present-cpus Wed Jun 9 14:45:58 2004 +++ 25-akpm/include/asm-i386/mach-default/mach_apic.h Wed Jun 9 14:45:58 2004 @@ -79,7 +79,10 @@ static inline int cpu_to_logical_apicid( static inline int cpu_present_to_apicid(int mps_cpu) { - return mps_cpu; + if (mps_cpu < get_physical_broadcast()) + return mps_cpu; + else + return BAD_APICID; } static inline physid_mask_t apicid_to_cpu_present(int phys_apicid) diff -puN include/asm-i386/mach-visws/mach_apic.h~apic-fix-kicking-of-non-present-cpus include/asm-i386/mach-visws/mach_apic.h --- 25/include/asm-i386/mach-visws/mach_apic.h~apic-fix-kicking-of-non-present-cpus Wed Jun 9 14:45:58 2004 +++ 25-akpm/include/asm-i386/mach-visws/mach_apic.h Wed Jun 9 14:45:58 2004 @@ -60,7 +60,10 @@ static inline int cpu_to_logical_apicid( static inline int cpu_present_to_apicid(int mps_cpu) { - return mps_cpu; + if (mps_cpu < get_physical_broadcast()) + return mps_cpu; + else + return BAD_APICID; } static inline physid_mask_t apicid_to_cpu_present(int apicid) _