summaryrefslogtreecommitdiffstats
path: root/drivers/irqchip/irq-gic.c
diff options
context:
space:
mode:
authorWill Deacon2014-02-20 18:42:07 +0100
committerArnd Bergmann2014-02-25 19:36:03 +0100
commit8adbf57fc4294588e9785069215d445a98e6c23a (patch)
treebeb95f1d6e8d29a87a593bf25030404b9d17671b /drivers/irqchip/irq-gic.c
parentLinus 3.14-rc1 (diff)
downloadkernel-qcow2-linux-8adbf57fc4294588e9785069215d445a98e6c23a.tar.gz
kernel-qcow2-linux-8adbf57fc4294588e9785069215d445a98e6c23a.tar.xz
kernel-qcow2-linux-8adbf57fc4294588e9785069215d445a98e6c23a.zip
irqchip: gic: use dmb ishst instead of dsb when raising a softirq
When sending an SGI to another CPU, we require a barrier to ensure that any pending stores to normal memory are made visible to the recipient before the interrupt arrives. Rather than use a vanilla dsb() (which will soon cause an assembly error on arm64) before the writel_relaxed, we can instead use dsb(ishst), since we just need to ensure that any pending normal writes are visible within the inner-shareable domain before we poke the GIC. With this observation, we can then further weaken the barrier to a dmb(ishst), since other CPUs in the inner-shareable domain must observe the write to the distributor before the SGI is generated. Cc: Thomas Gleixner <tglx@linutronix.de> Acked-by: Marc Zyngier <marc.zyngier@arm.com> Acked-by: Catalin Marinas <catalin.marinas@arm.com> Signed-off-by: Will Deacon <will.deacon@arm.com> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Diffstat (limited to 'drivers/irqchip/irq-gic.c')
-rw-r--r--drivers/irqchip/irq-gic.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
index 341c6016812d..500e533b9648 100644
--- a/drivers/irqchip/irq-gic.c
+++ b/drivers/irqchip/irq-gic.c
@@ -661,9 +661,9 @@ void gic_raise_softirq(const struct cpumask *mask, unsigned int irq)
/*
* Ensure that stores to Normal memory are visible to the
- * other CPUs before issuing the IPI.
+ * other CPUs before they observe us issuing the IPI.
*/
- dsb();
+ dmb(ishst);
/* this always happens on GIC0 */
writel_relaxed(map << 16 | irq, gic_data_dist_base(&gic_data[0]) + GIC_DIST_SOFTINT);