summaryrefslogtreecommitdiffstats
path: root/drivers/irqchip/irq-gic-v3.c
diff options
context:
space:
mode:
authorDaniel Thompson <daniel.thompson@linaro.org>2016-08-19 18:13:09 +0200
committerMarc Zyngier <marc.zyngier@arm.com>2016-09-12 20:46:19 +0200
commit91ef84428a86b75a52e15c6fe4f56b446ba75f93 (patch)
tree46066d44e3ddccef1b4d0056955eb59ffc67cf54 /drivers/irqchip/irq-gic-v3.c
parentirqchip/gic: Make locking a BL_SWITCHER only feature (diff)
downloadlinux-91ef84428a86b75a52e15c6fe4f56b446ba75f93.tar.xz
linux-91ef84428a86b75a52e15c6fe4f56b446ba75f93.zip
irqchip/gic-v3: Reset BPR during initialization
Currently, when running on FVP, CPU 0 boots up with its BPR changed from the reset value. This renders it impossible to (preemptively) prioritize interrupts on CPU 0. This is harmless on normal systems since Linux typically does not support preemptive interrupts. It does however cause problems in systems with additional changes (such as patches for NMI simulation). Many thanks to Andrew Thoelke for suggesting the BPR as having the potential to harm preemption. Suggested-by: Andrew Thoelke <andrew.thoelke@arm.com> Signed-off-by: Daniel Thompson <daniel.thompson@linaro.org> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Diffstat (limited to 'drivers/irqchip/irq-gic-v3.c')
-rw-r--r--drivers/irqchip/irq-gic-v3.c8
1 files changed, 8 insertions, 0 deletions
diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
index ede5672ab34d..ecc5b2360c7a 100644
--- a/drivers/irqchip/irq-gic-v3.c
+++ b/drivers/irqchip/irq-gic-v3.c
@@ -495,6 +495,14 @@ static void gic_cpu_sys_reg_init(void)
/* Set priority mask register */
gic_write_pmr(DEFAULT_PMR_VALUE);
+ /*
+ * Some firmwares hand over to the kernel with the BPR changed from
+ * its reset value (and with a value large enough to prevent
+ * any pre-emptive interrupts from working at all). Writing a zero
+ * to BPR restores is reset value.
+ */
+ gic_write_bpr1(0);
+
if (static_key_true(&supports_deactivate)) {
/* EOI drops priority only (mode 1) */
gic_write_ctlr(ICC_CTLR_EL1_EOImode_drop);