summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMarc Zyngier <marc.zyngier@arm.com>2016-05-06 19:41:56 +0100
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2016-06-01 12:16:58 -0700
commitf0bbf31d63b86845500f8e2a6fcbe6e35f630636 (patch)
treed90693d754357cba4f6a5f1fcffe0f5dfa8b9aed /drivers
parent066b085d819dd8a1decba6119a7a068e9e5add86 (diff)
downloadlinux-stable-f0bbf31d63b86845500f8e2a6fcbe6e35f630636.tar.gz
linux-stable-f0bbf31d63b86845500f8e2a6fcbe6e35f630636.tar.bz2
linux-stable-f0bbf31d63b86845500f8e2a6fcbe6e35f630636.zip
irqchip/gic-v3: Configure all interrupts as non-secure Group-1
commit 7c9b973061b03af62734f613f6abec46c0dd4a88 upstream. The GICv3 driver wrongly assumes that it runs on the non-secure side of a secure-enabled system, while it could be on a system with a single security state, or a GICv3 with GICD_CTLR.DS set. Either way, it is important to configure this properly, or interrupts will simply not be delivered on this HW. Reported-by: Peter Maydell <peter.maydell@linaro.org> Tested-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/irqchip/irq-gic-v3.c12
1 files changed, 12 insertions, 0 deletions
diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
index e35ab799be12..2fc499a2207e 100644
--- a/drivers/irqchip/irq-gic-v3.c
+++ b/drivers/irqchip/irq-gic-v3.c
@@ -387,6 +387,15 @@ static void __init gic_dist_init(void)
writel_relaxed(0, base + GICD_CTLR);
gic_dist_wait_for_rwp();
+ /*
+ * Configure SPIs as non-secure Group-1. This will only matter
+ * if the GIC only has a single security state. This will not
+ * do the right thing if the kernel is running in secure mode,
+ * but that's not the intended use case anyway.
+ */
+ for (i = 32; i < gic_data.irq_nr; i += 32)
+ writel_relaxed(~0, base + GICD_IGROUPR + i / 8);
+
gic_dist_config(base, gic_data.irq_nr, gic_dist_wait_for_rwp);
/* Enable distributor with ARE, Group1 */
@@ -501,6 +510,9 @@ static void gic_cpu_init(void)
rbase = gic_data_rdist_sgi_base();
+ /* Configure SGIs/PPIs as non-secure Group-1 */
+ writel_relaxed(~0, rbase + GICR_IGROUPR0);
+
gic_cpu_config(rbase, gic_redist_wait_for_rwp);
/* Give LPIs a spin */