From: William Lee Irwin III <wli@holomorphy.com>

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 <akpm@osdl.org>
---

 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)
_