From: James Cleverdon 32-way IBM x445s will have I/O xAPICs with IDs greater than 0xF (0x8 to 0xE isn't enough). This breaks the code in setup_ioapic_ids_from_mpc. However, the entire unique ID check is unnecessary. Only I/O APICs using the serial APIC bus need the unique numbers. Those sending messages through the system bus simply don't use them. arch/i386/kernel/io_apic.c | 4 ++++ include/asm-i386/genapic.h | 2 ++ include/asm-i386/mach-bigsmp/mach_apic.h | 2 ++ include/asm-i386/mach-default/mach_apic.h | 2 ++ include/asm-i386/mach-generic/mach_apic.h | 1 + include/asm-i386/mach-numaq/mach_apic.h | 2 ++ include/asm-i386/mach-summit/mach_apic.h | 2 ++ include/asm-i386/mach-visws/mach_apic.h | 2 ++ 8 files changed, 17 insertions(+) diff -puN arch/i386/kernel/io_apic.c~x445-no-ioapic-check arch/i386/kernel/io_apic.c --- 25/arch/i386/kernel/io_apic.c~x445-no-ioapic-check 2003-09-17 21:08:52.000000000 -0700 +++ 25-akpm/arch/i386/kernel/io_apic.c 2003-09-17 21:08:52.000000000 -0700 @@ -1653,6 +1653,10 @@ static void __init setup_ioapic_ids_from mp_ioapics[apic].mpc_apicid = reg_00.bits.ID; } + /* Don't check I/O APIC IDs for some xAPIC systems. They have + * no meaning without the serial APIC bus. */ + if (NO_IOAPIC_CHECK) + continue; /* * Sanity check, is the ID really free? Every APIC in a * system must have a unique ID or we get lots of nice diff -puN include/asm-i386/genapic.h~x445-no-ioapic-check include/asm-i386/genapic.h --- 25/include/asm-i386/genapic.h~x445-no-ioapic-check 2003-09-17 21:08:52.000000000 -0700 +++ 25-akpm/include/asm-i386/genapic.h 2003-09-17 21:08:52.000000000 -0700 @@ -30,6 +30,7 @@ struct genapic { unsigned long (*check_apicid_used)(physid_mask_t bitmap, int apicid); unsigned long (*check_apicid_present)(int apicid); int no_balance_irq; + int no_ioapic_check; void (*init_apic_ldr)(void); physid_mask_t (*ioapic_phys_id_map)(physid_mask_t map); @@ -77,6 +78,7 @@ struct genapic { .int_dest_mode = INT_DEST_MODE, \ .apic_broadcast_id = APIC_BROADCAST_ID, \ .no_balance_irq = NO_BALANCE_IRQ, \ + .no_ioapic_check = NO_IOAPIC_CHECK, \ APICFUNC(apic_id_registered), \ APICFUNC(target_cpus), \ APICFUNC(check_apicid_used), \ diff -puN include/asm-i386/mach-bigsmp/mach_apic.h~x445-no-ioapic-check include/asm-i386/mach-bigsmp/mach_apic.h --- 25/include/asm-i386/mach-bigsmp/mach_apic.h~x445-no-ioapic-check 2003-09-17 21:08:52.000000000 -0700 +++ 25-akpm/include/asm-i386/mach-bigsmp/mach_apic.h 2003-09-17 21:08:52.000000000 -0700 @@ -14,6 +14,8 @@ #define NO_BALANCE_IRQ (1) #define esr_disable (1) +#define NO_IOAPIC_CHECK (0) + static inline int apic_id_registered(void) { return (1); diff -puN include/asm-i386/mach-default/mach_apic.h~x445-no-ioapic-check include/asm-i386/mach-default/mach_apic.h --- 25/include/asm-i386/mach-default/mach_apic.h~x445-no-ioapic-check 2003-09-17 21:08:52.000000000 -0700 +++ 25-akpm/include/asm-i386/mach-default/mach_apic.h 2003-09-17 21:08:52.000000000 -0700 @@ -18,6 +18,8 @@ static inline cpumask_t target_cpus(void #define NO_BALANCE_IRQ (0) #define esr_disable (0) +#define NO_IOAPIC_CHECK (0) + #define INT_DELIVERY_MODE dest_LowestPrio #define INT_DEST_MODE 1 /* logical delivery broadcast to all procs */ diff -puN include/asm-i386/mach-generic/mach_apic.h~x445-no-ioapic-check include/asm-i386/mach-generic/mach_apic.h --- 25/include/asm-i386/mach-generic/mach_apic.h~x445-no-ioapic-check 2003-09-17 21:08:52.000000000 -0700 +++ 25-akpm/include/asm-i386/mach-generic/mach_apic.h 2003-09-17 21:08:52.000000000 -0700 @@ -5,6 +5,7 @@ #define esr_disable (genapic->esr_disable) #define NO_BALANCE_IRQ (genapic->no_balance_irq) +#define NO_IOAPIC_CHECK (genapic->no_ioapic_check) #define APIC_BROADCAST_ID (genapic->apic_broadcast_id) #define INT_DELIVERY_MODE (genapic->int_delivery_mode) #define INT_DEST_MODE (genapic->int_dest_mode) diff -puN include/asm-i386/mach-numaq/mach_apic.h~x445-no-ioapic-check include/asm-i386/mach-numaq/mach_apic.h --- 25/include/asm-i386/mach-numaq/mach_apic.h~x445-no-ioapic-check 2003-09-17 21:08:52.000000000 -0700 +++ 25-akpm/include/asm-i386/mach-numaq/mach_apic.h 2003-09-17 21:08:52.000000000 -0700 @@ -17,6 +17,8 @@ static inline cpumask_t target_cpus(void #define NO_BALANCE_IRQ (1) #define esr_disable (1) +#define NO_IOAPIC_CHECK (0) + #define INT_DELIVERY_MODE dest_LowestPrio #define INT_DEST_MODE 0 /* physical delivery on LOCAL quad */ diff -puN include/asm-i386/mach-summit/mach_apic.h~x445-no-ioapic-check include/asm-i386/mach-summit/mach_apic.h --- 25/include/asm-i386/mach-summit/mach_apic.h~x445-no-ioapic-check 2003-09-17 21:08:52.000000000 -0700 +++ 25-akpm/include/asm-i386/mach-summit/mach_apic.h 2003-09-17 21:08:52.000000000 -0700 @@ -7,6 +7,8 @@ #define esr_disable (1) #define NO_BALANCE_IRQ (0) +#define NO_IOAPIC_CHECK (1) /* Don't check I/O APIC ID for xAPIC */ + /* In clustered mode, the high nibble of APIC ID is a cluster number. * The low nibble is a 4-bit bitmap. */ #define XAPIC_DEST_CPUS_SHIFT 4 diff -puN include/asm-i386/mach-visws/mach_apic.h~x445-no-ioapic-check include/asm-i386/mach-visws/mach_apic.h --- 25/include/asm-i386/mach-visws/mach_apic.h~x445-no-ioapic-check 2003-09-17 21:08:52.000000000 -0700 +++ 25-akpm/include/asm-i386/mach-visws/mach_apic.h 2003-09-17 21:08:52.000000000 -0700 @@ -8,6 +8,8 @@ #define no_balance_irq (0) #define esr_disable (0) +#define NO_IOAPIC_CHECK (0) + #define INT_DELIVERY_MODE dest_LowestPrio #define INT_DEST_MODE 1 /* logical delivery broadcast to all procs */ _