Commit fec67508 authored by Anton Blanchard's avatar Anton Blanchard

ppc64: IPIs must run with interrupts off so tag them with SA_INTERRUPT

parent 4883c96a
...@@ -46,6 +46,7 @@ CONFIG_NR_CPUS=32 ...@@ -46,6 +46,7 @@ CONFIG_NR_CPUS=32
# CONFIG_HMT is not set # CONFIG_HMT is not set
# CONFIG_DISCONTIGMEM is not set # CONFIG_DISCONTIGMEM is not set
# CONFIG_RTAS_FLASH is not set # CONFIG_RTAS_FLASH is not set
CONFIG_SCANLOG=y
CONFIG_PPC_RTAS=y CONFIG_PPC_RTAS=y
# #
...@@ -54,7 +55,6 @@ CONFIG_PPC_RTAS=y ...@@ -54,7 +55,6 @@ CONFIG_PPC_RTAS=y
CONFIG_PCI=y CONFIG_PCI=y
CONFIG_KCORE_ELF=y CONFIG_KCORE_ELF=y
CONFIG_BINFMT_ELF=y CONFIG_BINFMT_ELF=y
CONFIG_BINFMT_ELF32=y
# CONFIG_BINFMT_MISC is not set # CONFIG_BINFMT_MISC is not set
CONFIG_PCI_LEGACY_PROC=y CONFIG_PCI_LEGACY_PROC=y
CONFIG_PCI_NAMES=y CONFIG_PCI_NAMES=y
......
...@@ -555,14 +555,15 @@ void openpic_request_IPIs(void) ...@@ -555,14 +555,15 @@ void openpic_request_IPIs(void)
if (OpenPIC == NULL) if (OpenPIC == NULL)
return; return;
request_irq(openpic_vec_ipi, /* IPIs are marked SA_INTERRUPT as they must run with irqs disabled */
openpic_ipi_action, 0, "IPI0 (call function)", 0); request_irq(openpic_vec_ipi, openpic_ipi_action, SA_INTERRUPT,
request_irq(openpic_vec_ipi+1, "IPI0 (call function)", 0);
openpic_ipi_action, 0, "IPI1 (reschedule)", 0); request_irq(openpic_vec_ipi+1, openpic_ipi_action, SA_INTERRUPT,
request_irq(openpic_vec_ipi+2, "IPI1 (reschedule)", 0);
openpic_ipi_action, 0, "IPI2 (invalidate tlb)", 0); request_irq(openpic_vec_ipi+2, openpic_ipi_action, SA_INTERRUPT,
request_irq(openpic_vec_ipi+3, "IPI2 (invalidate tlb)", 0);
openpic_ipi_action, 0, "IPI3 (xmon break)", 0); request_irq(openpic_vec_ipi+3, openpic_ipi_action, SA_INTERRUPT,
"IPI3 (xmon break)", 0);
for ( i = 0; i < OPENPIC_NUM_IPI ; i++ ) for ( i = 0; i < OPENPIC_NUM_IPI ; i++ )
openpic_enable_ipi(openpic_vec_ipi+i); openpic_enable_ipi(openpic_vec_ipi+i);
...@@ -754,17 +755,12 @@ static void openpic_set_affinity(unsigned int irq_nr, unsigned long cpumask) ...@@ -754,17 +755,12 @@ static void openpic_set_affinity(unsigned int irq_nr, unsigned long cpumask)
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
static void openpic_end_ipi(unsigned int irq_nr) static void openpic_end_ipi(unsigned int irq_nr)
{ {
/* IPIs are marked IRQ_PER_CPU. This has the side effect of /*
* IPIs are marked IRQ_PER_CPU. This has the side effect of
* preventing the IRQ_PENDING/IRQ_INPROGRESS logic from * preventing the IRQ_PENDING/IRQ_INPROGRESS logic from
* applying to them. We EOI them late to avoid re-entering. * applying to them. We EOI them late to avoid re-entering.
* however, I'm wondering if we could simply let them have the * We mark IPI's with SA_INTERRUPT as they must run with
* SA_INTERRUPT flag and let them execute with all interrupts OFF. * irqs disabled.
* This would have the side effect of either running cross-CPU
* functions with interrupts off, or we can re-enable them explicitely
* with a local_irq_enable() in smp_call_function_interrupt(), since
* smp_call_function() is protected by a spinlock.
* Or maybe we shouldn't set the IRQ_PER_CPU flag on cross-CPU
* function calls IPI at all but that would make a special case.
*/ */
openpic_eoi(); openpic_eoi();
} }
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include <linux/irq.h> #include <linux/irq.h>
#include <linux/smp.h> #include <linux/smp.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/signal.h>
#include <asm/prom.h> #include <asm/prom.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/pgtable.h> #include <asm/pgtable.h>
...@@ -423,8 +424,11 @@ xics_init_IRQ( void ) ...@@ -423,8 +424,11 @@ xics_init_IRQ( void )
} }
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
real_irq_to_virt_map[XICS_IPI] = virt_irq_to_real_map[XICS_IPI] = XICS_IPI; real_irq_to_virt_map[XICS_IPI] = virt_irq_to_real_map[XICS_IPI] =
request_irq(XICS_IPI + XICS_IRQ_OFFSET, xics_ipi_action, 0, "IPI", 0); XICS_IPI;
/* IPIs are marked SA_INTERRUPT as they must run with irqs disabled */
request_irq(XICS_IPI + XICS_IRQ_OFFSET, xics_ipi_action, SA_INTERRUPT,
"IPI", 0);
irq_desc[XICS_IPI+XICS_IRQ_OFFSET].status |= IRQ_PER_CPU; irq_desc[XICS_IPI+XICS_IRQ_OFFSET].status |= IRQ_PER_CPU;
#endif #endif
ppc64_boot_msg(0x21, "XICS Done"); ppc64_boot_msg(0x21, "XICS Done");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment