diff options
-rw-r--r-- | drivers/irqchip/irq-gic-v3.c | 7 | ||||
-rw-r--r-- | drivers/irqchip/irq-gic.c | 8 |
2 files changed, 15 insertions, 0 deletions
diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c index aa17ae805a70..a94342f4a3ef 100644 --- a/drivers/irqchip/irq-gic-v3.c +++ b/drivers/irqchip/irq-gic-v3.c @@ -283,6 +283,13 @@ static asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs if (irqnr < 16) { gic_write_eoir(irqnr); #ifdef CONFIG_SMP + /* + * Unlike GICv2, we don't need an smp_rmb() here. + * The control dependency from gic_read_iar to + * the ISB in gic_write_eoir is enough to ensure + * that any shared data read by handle_IPI will + * be read after the ACK. + */ handle_IPI(irqnr, regs); #else WARN_ONCE(true, "Unexpected SGI received!\n"); diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c index 38493ff28fa5..1107051df379 100644 --- a/drivers/irqchip/irq-gic.c +++ b/drivers/irqchip/irq-gic.c @@ -276,6 +276,14 @@ static void __exception_irq_entry gic_handle_irq(struct pt_regs *regs) if (irqnr < 16) { writel_relaxed(irqstat, cpu_base + GIC_CPU_EOI); #ifdef CONFIG_SMP + /* + * Ensure any shared data written by the CPU sending + * the IPI is read after we've read the ACK register + * on the GIC. + * + * Pairs with the write barrier in gic_raise_softirq + */ + smp_rmb(); handle_IPI(irqnr, regs); #endif continue; |