Skip to content

Commit 71c8e2a

Browse files
mrutland-armKAGA-KOKO
authored andcommitted
irqchip/gic-v3: Init SRE before poking sysregs
The GICv3 driver pokes GICv3 system registers in gic_prio_init() before gic_cpu_sys_reg_init() ensures that GICv3 system registers have been enabled by writing to ICC_SRE_EL1.SRE. On arm64 this is benign as has_useable_gicv3_cpuif() runs earlier during cpufeature detection, and this enables the GICv3 system registers. On 32-bit arm when booting on an FVP using the boot-wrapper, the accesses in gic_prio_init() end up being UNDEFINED and crashes the kernel during boot. This is a regression introduced by the addition of gic_prio_init(). Fix this by factoring out the SRE initialization into a new function and calling it early in the three paths where SRE may not have been initialized: (1) gic_init_bases(), before the primary CPU pokes GICv3 sysregs in gic_prio_init(). (2) gic_starting_cpu(), before secondary CPUs initialize GICv3 sysregs in gic_cpu_init(). (3) gic_cpu_pm_notifier(), before CPUs re-initialize GICv3 sysregs in gic_cpu_sys_reg_init(). Fixes: d447bf0 ("irqchip/gic-v3: Detect GICD_CTRL.DS and SCR_EL3.FIQ earlier") Signed-off-by: Mark Rutland <[email protected]> Signed-off-by: Thomas Gleixner <[email protected]> Reviewed-by: Marc Zyngier <[email protected]> Cc: [email protected]
1 parent c5af2c9 commit 71c8e2a

File tree

1 file changed

+14
-7
lines changed

1 file changed

+14
-7
lines changed

drivers/irqchip/irq-gic-v3.c

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1154,14 +1154,8 @@ static void gic_update_rdist_properties(void)
11541154
gic_data.rdists.has_vpend_valid_dirty ? "Valid+Dirty " : "");
11551155
}
11561156

1157-
static void gic_cpu_sys_reg_init(void)
1157+
static void gic_cpu_sys_reg_enable(void)
11581158
{
1159-
int i, cpu = smp_processor_id();
1160-
u64 mpidr = gic_cpu_to_affinity(cpu);
1161-
u64 need_rss = MPIDR_RS(mpidr);
1162-
bool group0;
1163-
u32 pribits;
1164-
11651159
/*
11661160
* Need to check that the SRE bit has actually been set. If
11671161
* not, it means that SRE is disabled at EL2. We're going to
@@ -1172,6 +1166,16 @@ static void gic_cpu_sys_reg_init(void)
11721166
if (!gic_enable_sre())
11731167
pr_err("GIC: unable to set SRE (disabled at EL2), panic ahead\n");
11741168

1169+
}
1170+
1171+
static void gic_cpu_sys_reg_init(void)
1172+
{
1173+
int i, cpu = smp_processor_id();
1174+
u64 mpidr = gic_cpu_to_affinity(cpu);
1175+
u64 need_rss = MPIDR_RS(mpidr);
1176+
bool group0;
1177+
u32 pribits;
1178+
11751179
pribits = gic_get_pribits();
11761180

11771181
group0 = gic_has_group0();
@@ -1333,6 +1337,7 @@ static int gic_check_rdist(unsigned int cpu)
13331337

13341338
static int gic_starting_cpu(unsigned int cpu)
13351339
{
1340+
gic_cpu_sys_reg_enable();
13361341
gic_cpu_init();
13371342

13381343
if (gic_dist_supports_lpis())
@@ -1498,6 +1503,7 @@ static int gic_cpu_pm_notifier(struct notifier_block *self,
14981503
if (cmd == CPU_PM_EXIT) {
14991504
if (gic_dist_security_disabled())
15001505
gic_enable_redist(true);
1506+
gic_cpu_sys_reg_enable();
15011507
gic_cpu_sys_reg_init();
15021508
} else if (cmd == CPU_PM_ENTER && gic_dist_security_disabled()) {
15031509
gic_write_grpen1(0);
@@ -2070,6 +2076,7 @@ static int __init gic_init_bases(phys_addr_t dist_phys_base,
20702076

20712077
gic_update_rdist_properties();
20722078

2079+
gic_cpu_sys_reg_enable();
20732080
gic_prio_init();
20742081
gic_dist_init();
20752082
gic_cpu_init();

0 commit comments

Comments
 (0)