From: Anton Blanchard It turns out we were passing in the wrong thing to the rtas_set_indicator call. Luckily we got away with it because it looks like firmware does not check arguments and just inserts or removes the current cpu from the global server group. Fix it. Signed-off-by: Anton Blanchard Signed-off-by: Andrew Morton --- 25-akpm/arch/ppc64/kernel/pSeries_smp.c | 3 ++- 25-akpm/arch/ppc64/kernel/xics.c | 9 +++++++-- 25-akpm/include/asm-ppc64/xics.h | 1 + 3 files changed, 10 insertions(+), 3 deletions(-) diff -puN arch/ppc64/kernel/pSeries_smp.c~ppc64-fix-rtas_set_indicator9005 arch/ppc64/kernel/pSeries_smp.c --- 25/arch/ppc64/kernel/pSeries_smp.c~ppc64-fix-rtas_set_indicator9005 2005-01-10 20:02:08.574011344 -0800 +++ 25-akpm/arch/ppc64/kernel/pSeries_smp.c 2005-01-10 20:02:08.582010128 -0800 @@ -265,7 +265,8 @@ static void __devinit smp_xics_setup_cpu * necessary from a secondary thread as the OF start-cpu interface * performs this function for us on primary threads. */ - rtas_set_indicator(GLOBAL_INTERRUPT_QUEUE, default_distrib_server, 1); + rtas_set_indicator(GLOBAL_INTERRUPT_QUEUE, + (1UL << interrupt_server_size) - 1 - default_distrib_server, 1); #endif } diff -puN arch/ppc64/kernel/xics.c~ppc64-fix-rtas_set_indicator9005 arch/ppc64/kernel/xics.c --- 25/arch/ppc64/kernel/xics.c~ppc64-fix-rtas_set_indicator9005 2005-01-10 20:02:08.576011040 -0800 +++ 25-akpm/arch/ppc64/kernel/xics.c 2005-01-10 20:02:08.583009976 -0800 @@ -91,6 +91,7 @@ static int xics_irq_8259_cascade_real = static unsigned int default_server = 0xFF; /* also referenced in smp.c... */ unsigned int default_distrib_server = 0; +unsigned int interrupt_server_size = 8; /* * XICS only has a single IPI, so encode the messages per CPU @@ -511,6 +512,10 @@ nextnode: default_server = ireg[0]; default_distrib_server = ireg[i-1]; /* take last element */ } + ireg = (uint *)get_property(np, + "ibm,interrupt-server#-size", NULL); + if (ireg) + interrupt_server_size = *ireg; break; } } @@ -650,9 +655,9 @@ void xics_migrate_irqs_away(void) ops->cppr_info(cpu, 0); iosync(); - /* Refuse any new interrupts... */ + /* remove ourselves from the global interrupt queue */ status = rtas_set_indicator(GLOBAL_INTERRUPT_QUEUE, - hard_smp_processor_id(), 0); + (1UL << interrupt_server_size) - 1 - default_distrib_server, 0); WARN_ON(status != 0); /* Allow IPIs again... */ diff -puN include/asm-ppc64/xics.h~ppc64-fix-rtas_set_indicator9005 include/asm-ppc64/xics.h --- 25/include/asm-ppc64/xics.h~ppc64-fix-rtas_set_indicator9005 2005-01-10 20:02:08.577010888 -0800 +++ 25-akpm/include/asm-ppc64/xics.h 2005-01-10 20:02:08.583009976 -0800 @@ -31,5 +31,6 @@ struct xics_ipi_struct { extern struct xics_ipi_struct xics_ipi_message[NR_CPUS] __cacheline_aligned; extern unsigned int default_distrib_server; +extern unsigned int interrupt_server_size; #endif /* _PPC64_KERNEL_XICS_H */ _