aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarc Zyngier <marc.zyngier@arm.com>2018-03-09 09:53:19 -0500
committerMarc Zyngier <marc.zyngier@arm.com>2018-03-14 07:11:29 -0400
commitd6062a6d62c643a06c393745d032da3e6441d4bd (patch)
treeecc4745282e90a4eab388ab137307ff22bc4fe94
parentc5e1035c9687025373b7c48a08efb37f5329916b (diff)
irqchip/gic-v3: Reset APgRn registers at boot time
Booting a crash kernel while in an interrupt handler is likely to leave the Active Priority Registers with some state that is not relevant to the new kernel, and is likely to lead to erratic behaviours such as interrupts not firing as their priority is already active. As a sanity measure, wipe the APRs clean on startup. We make sure to wipe both group 0 and 1 registers in order to avoid any surprise. Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
-rw-r--r--arch/arm/include/asm/arch_gicv3.h41
-rw-r--r--drivers/irqchip/irq-gic-v3.c23
2 files changed, 54 insertions, 10 deletions
diff --git a/arch/arm/include/asm/arch_gicv3.h b/arch/arm/include/asm/arch_gicv3.h
index 1070044f5c3f..27288bdbd840 100644
--- a/arch/arm/include/asm/arch_gicv3.h
+++ b/arch/arm/include/asm/arch_gicv3.h
@@ -35,6 +35,18 @@
35#define ICC_IGRPEN1 __ACCESS_CP15(c12, 0, c12, 7) 35#define ICC_IGRPEN1 __ACCESS_CP15(c12, 0, c12, 7)
36#define ICC_BPR1 __ACCESS_CP15(c12, 0, c12, 3) 36#define ICC_BPR1 __ACCESS_CP15(c12, 0, c12, 3)
37 37
38#define __ICC_AP0Rx(x) __ACCESS_CP15(c12, 0, c8, 4 | x)
39#define ICC_AP0R0 __ICC_AP0Rx(0)
40#define ICC_AP0R1 __ICC_AP0Rx(1)
41#define ICC_AP0R2 __ICC_AP0Rx(2)
42#define ICC_AP0R3 __ICC_AP0Rx(3)
43
44#define __ICC_AP1Rx(x) __ACCESS_CP15(c12, 0, c9, x)
45#define ICC_AP1R0 __ICC_AP1Rx(0)
46#define ICC_AP1R1 __ICC_AP1Rx(1)
47#define ICC_AP1R2 __ICC_AP1Rx(2)
48#define ICC_AP1R3 __ICC_AP1Rx(3)
49
38#define ICC_HSRE __ACCESS_CP15(c12, 4, c9, 5) 50#define ICC_HSRE __ACCESS_CP15(c12, 4, c9, 5)
39 51
40#define ICH_VSEIR __ACCESS_CP15(c12, 4, c9, 4) 52#define ICH_VSEIR __ACCESS_CP15(c12, 4, c9, 4)
@@ -86,17 +98,17 @@
86#define ICH_LRC14 __LRC8(6) 98#define ICH_LRC14 __LRC8(6)
87#define ICH_LRC15 __LRC8(7) 99#define ICH_LRC15 __LRC8(7)
88 100
89#define __AP0Rx(x) __ACCESS_CP15(c12, 4, c8, x) 101#define __ICH_AP0Rx(x) __ACCESS_CP15(c12, 4, c8, x)
90#define ICH_AP0R0 __AP0Rx(0) 102#define ICH_AP0R0 __ICH_AP0Rx(0)
91#define ICH_AP0R1 __AP0Rx(1) 103#define ICH_AP0R1 __ICH_AP0Rx(1)
92#define ICH_AP0R2 __AP0Rx(2) 104#define ICH_AP0R2 __ICH_AP0Rx(2)
93#define ICH_AP0R3 __AP0Rx(3) 105#define ICH_AP0R3 __ICH_AP0Rx(3)
94 106
95#define __AP1Rx(x) __ACCESS_CP15(c12, 4, c9, x) 107#define __ICH_AP1Rx(x) __ACCESS_CP15(c12, 4, c9, x)
96#define ICH_AP1R0 __AP1Rx(0) 108#define ICH_AP1R0 __ICH_AP1Rx(0)
97#define ICH_AP1R1 __AP1Rx(1) 109#define ICH_AP1R1 __ICH_AP1Rx(1)
98#define ICH_AP1R2 __AP1Rx(2) 110#define ICH_AP1R2 __ICH_AP1Rx(2)
99#define ICH_AP1R3 __AP1Rx(3) 111#define ICH_AP1R3 __ICH_AP1Rx(3)
100 112
101/* A32-to-A64 mappings used by VGIC save/restore */ 113/* A32-to-A64 mappings used by VGIC save/restore */
102 114
@@ -125,6 +137,15 @@ static inline u64 read_ ## a64(void) \
125 return val; \ 137 return val; \
126} 138}
127 139
140CPUIF_MAP(ICC_AP0R0, ICC_AP0R0_EL1)
141CPUIF_MAP(ICC_AP0R1, ICC_AP0R1_EL1)
142CPUIF_MAP(ICC_AP0R2, ICC_AP0R2_EL1)
143CPUIF_MAP(ICC_AP0R3, ICC_AP0R3_EL1)
144CPUIF_MAP(ICC_AP1R0, ICC_AP1R0_EL1)
145CPUIF_MAP(ICC_AP1R1, ICC_AP1R1_EL1)
146CPUIF_MAP(ICC_AP1R2, ICC_AP1R2_EL1)
147CPUIF_MAP(ICC_AP1R3, ICC_AP1R3_EL1)
148
128CPUIF_MAP(ICH_HCR, ICH_HCR_EL2) 149CPUIF_MAP(ICH_HCR, ICH_HCR_EL2)
129CPUIF_MAP(ICH_VTR, ICH_VTR_EL2) 150CPUIF_MAP(ICH_VTR, ICH_VTR_EL2)
130CPUIF_MAP(ICH_MISR, ICH_MISR_EL2) 151CPUIF_MAP(ICH_MISR, ICH_MISR_EL2)
diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
index d99cc07903ec..0ea02504115d 100644
--- a/drivers/irqchip/irq-gic-v3.c
+++ b/drivers/irqchip/irq-gic-v3.c
@@ -532,6 +532,7 @@ static void gic_cpu_sys_reg_init(void)
532 int i, cpu = smp_processor_id(); 532 int i, cpu = smp_processor_id();
533 u64 mpidr = cpu_logical_map(cpu); 533 u64 mpidr = cpu_logical_map(cpu);
534 u64 need_rss = MPIDR_RS(mpidr); 534 u64 need_rss = MPIDR_RS(mpidr);
535 u32 val;
535 536
536 /* 537 /*
537 * Need to check that the SRE bit has actually been set. If 538 * Need to check that the SRE bit has actually been set. If
@@ -562,6 +563,28 @@ static void gic_cpu_sys_reg_init(void)
562 gic_write_ctlr(ICC_CTLR_EL1_EOImode_drop_dir); 563 gic_write_ctlr(ICC_CTLR_EL1_EOImode_drop_dir);
563 } 564 }
564 565
566 val = gic_read_ctlr();
567 val &= ICC_CTLR_EL1_PRI_BITS_MASK;
568 val >>= ICC_CTLR_EL1_PRI_BITS_SHIFT;
569
570 switch(val + 1) {
571 case 8:
572 case 7:
573 write_gicreg(0, ICC_AP0R3_EL1);
574 write_gicreg(0, ICC_AP1R3_EL1);
575 write_gicreg(0, ICC_AP0R2_EL1);
576 write_gicreg(0, ICC_AP1R2_EL1);
577 case 6:
578 write_gicreg(0, ICC_AP0R1_EL1);
579 write_gicreg(0, ICC_AP1R1_EL1);
580 case 5:
581 case 4:
582 write_gicreg(0, ICC_AP0R0_EL1);
583 write_gicreg(0, ICC_AP1R0_EL1);
584 }
585
586 isb();
587
565 /* ... and let's hit the road... */ 588 /* ... and let's hit the road... */
566 gic_write_grpen1(1); 589 gic_write_grpen1(1);
567 590