mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2024-12-28 16:52:18 +00:00
irqchip/mips-gic: Prevent indirect access to clusters without CPU cores
It is possible to have zero CPU cores in a cluster; in such cases, it is not possible to access the GIC, and any indirect access leads to an exception. Prevent access to such clusters by checking the number of cores in the cluster at all places which issue indirect cluster access. Signed-off-by: Gregory CLEMENT <gregory.clement@bootlin.com> Signed-off-by: Aleksandar Rikalo <arikalo@gmail.com> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Link: https://lore.kernel.org/all/20241028175935.51250-14-arikalo@gmail.com
This commit is contained in:
parent
322a906387
commit
d1cb1437b7
@ -141,7 +141,8 @@ static bool gic_irq_lock_cluster(struct irq_data *d)
|
||||
cl = cpu_cluster(&cpu_data[cpu]);
|
||||
if (cl == cpu_cluster(¤t_cpu_data))
|
||||
return false;
|
||||
|
||||
if (mips_cps_numcores(cl) == 0)
|
||||
return false;
|
||||
mips_cm_lock_other(cl, 0, 0, CM_GCR_Cx_OTHER_BLOCK_GLOBAL);
|
||||
return true;
|
||||
}
|
||||
@ -507,6 +508,9 @@ static void gic_mask_local_irq_all_vpes(struct irq_data *d)
|
||||
struct gic_all_vpes_chip_data *cd;
|
||||
int intr, cpu;
|
||||
|
||||
if (!mips_cps_multicluster_cpus())
|
||||
return;
|
||||
|
||||
intr = GIC_HWIRQ_TO_LOCAL(d->hwirq);
|
||||
cd = irq_data_get_irq_chip_data(d);
|
||||
cd->mask = false;
|
||||
@ -520,6 +524,9 @@ static void gic_unmask_local_irq_all_vpes(struct irq_data *d)
|
||||
struct gic_all_vpes_chip_data *cd;
|
||||
int intr, cpu;
|
||||
|
||||
if (!mips_cps_multicluster_cpus())
|
||||
return;
|
||||
|
||||
intr = GIC_HWIRQ_TO_LOCAL(d->hwirq);
|
||||
cd = irq_data_get_irq_chip_data(d);
|
||||
cd->mask = true;
|
||||
@ -687,8 +694,10 @@ static int gic_irq_domain_map(struct irq_domain *d, unsigned int virq,
|
||||
if (!gic_local_irq_is_routable(intr))
|
||||
return -EPERM;
|
||||
|
||||
for_each_online_cpu_gic(cpu, &gic_lock)
|
||||
write_gic_vo_map(mips_gic_vx_map_reg(intr), map);
|
||||
if (mips_cps_multicluster_cpus()) {
|
||||
for_each_online_cpu_gic(cpu, &gic_lock)
|
||||
write_gic_vo_map(mips_gic_vx_map_reg(intr), map);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -982,7 +991,7 @@ static int __init gic_of_init(struct device_node *node,
|
||||
change_gic_trig(i, GIC_TRIG_LEVEL);
|
||||
write_gic_rmask(i);
|
||||
}
|
||||
} else {
|
||||
} else if (mips_cps_numcores(cl) != 0) {
|
||||
mips_cm_lock_other(cl, 0, 0, CM_GCR_Cx_OTHER_BLOCK_GLOBAL);
|
||||
for (i = 0; i < gic_shared_intrs; i++) {
|
||||
change_gic_redir_pol(i, GIC_POL_ACTIVE_HIGH);
|
||||
@ -990,6 +999,9 @@ static int __init gic_of_init(struct device_node *node,
|
||||
write_gic_redir_rmask(i);
|
||||
}
|
||||
mips_cm_unlock_other();
|
||||
|
||||
} else {
|
||||
pr_warn("No CPU cores on the cluster %d skip it\n", cl);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user