mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-04-29 08:12:41 -04:00
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: d447bf09a4 ("irqchip/gic-v3: Detect GICD_CTRL.DS and SCR_EL3.FIQ earlier")
Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Marc Zyngier <maz@kernel.org>
Cc: stable@vger.kernel.org
This commit is contained in:
committed by
Thomas Gleixner
parent
c5af2c90ba
commit
71c8e2a7c8
@@ -1154,14 +1154,8 @@ static void gic_update_rdist_properties(void)
|
||||
gic_data.rdists.has_vpend_valid_dirty ? "Valid+Dirty " : "");
|
||||
}
|
||||
|
||||
static void gic_cpu_sys_reg_init(void)
|
||||
static void gic_cpu_sys_reg_enable(void)
|
||||
{
|
||||
int i, cpu = smp_processor_id();
|
||||
u64 mpidr = gic_cpu_to_affinity(cpu);
|
||||
u64 need_rss = MPIDR_RS(mpidr);
|
||||
bool group0;
|
||||
u32 pribits;
|
||||
|
||||
/*
|
||||
* Need to check that the SRE bit has actually been set. If
|
||||
* 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)
|
||||
if (!gic_enable_sre())
|
||||
pr_err("GIC: unable to set SRE (disabled at EL2), panic ahead\n");
|
||||
|
||||
}
|
||||
|
||||
static void gic_cpu_sys_reg_init(void)
|
||||
{
|
||||
int i, cpu = smp_processor_id();
|
||||
u64 mpidr = gic_cpu_to_affinity(cpu);
|
||||
u64 need_rss = MPIDR_RS(mpidr);
|
||||
bool group0;
|
||||
u32 pribits;
|
||||
|
||||
pribits = gic_get_pribits();
|
||||
|
||||
group0 = gic_has_group0();
|
||||
@@ -1333,6 +1337,7 @@ static int gic_check_rdist(unsigned int cpu)
|
||||
|
||||
static int gic_starting_cpu(unsigned int cpu)
|
||||
{
|
||||
gic_cpu_sys_reg_enable();
|
||||
gic_cpu_init();
|
||||
|
||||
if (gic_dist_supports_lpis())
|
||||
@@ -1498,6 +1503,7 @@ static int gic_cpu_pm_notifier(struct notifier_block *self,
|
||||
if (cmd == CPU_PM_EXIT) {
|
||||
if (gic_dist_security_disabled())
|
||||
gic_enable_redist(true);
|
||||
gic_cpu_sys_reg_enable();
|
||||
gic_cpu_sys_reg_init();
|
||||
} else if (cmd == CPU_PM_ENTER && gic_dist_security_disabled()) {
|
||||
gic_write_grpen1(0);
|
||||
@@ -2070,6 +2076,7 @@ static int __init gic_init_bases(phys_addr_t dist_phys_base,
|
||||
|
||||
gic_update_rdist_properties();
|
||||
|
||||
gic_cpu_sys_reg_enable();
|
||||
gic_prio_init();
|
||||
gic_dist_init();
|
||||
gic_cpu_init();
|
||||
|
||||
Reference in New Issue
Block a user