Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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

authored by

Gregory CLEMENT and committed by
Thomas Gleixner
d1cb1437 322a9063

+16 -4
+16 -4
drivers/irqchip/irq-mips-gic.c
··· 141 141 cl = cpu_cluster(&cpu_data[cpu]); 142 142 if (cl == cpu_cluster(&current_cpu_data)) 143 143 return false; 144 - 144 + if (mips_cps_numcores(cl) == 0) 145 + return false; 145 146 mips_cm_lock_other(cl, 0, 0, CM_GCR_Cx_OTHER_BLOCK_GLOBAL); 146 147 return true; 147 148 } ··· 508 507 struct gic_all_vpes_chip_data *cd; 509 508 int intr, cpu; 510 509 510 + if (!mips_cps_multicluster_cpus()) 511 + return; 512 + 511 513 intr = GIC_HWIRQ_TO_LOCAL(d->hwirq); 512 514 cd = irq_data_get_irq_chip_data(d); 513 515 cd->mask = false; ··· 523 519 { 524 520 struct gic_all_vpes_chip_data *cd; 525 521 int intr, cpu; 522 + 523 + if (!mips_cps_multicluster_cpus()) 524 + return; 526 525 527 526 intr = GIC_HWIRQ_TO_LOCAL(d->hwirq); 528 527 cd = irq_data_get_irq_chip_data(d); ··· 694 687 if (!gic_local_irq_is_routable(intr)) 695 688 return -EPERM; 696 689 697 - for_each_online_cpu_gic(cpu, &gic_lock) 698 - write_gic_vo_map(mips_gic_vx_map_reg(intr), map); 690 + if (mips_cps_multicluster_cpus()) { 691 + for_each_online_cpu_gic(cpu, &gic_lock) 692 + write_gic_vo_map(mips_gic_vx_map_reg(intr), map); 693 + } 699 694 700 695 return 0; 701 696 } ··· 991 982 change_gic_trig(i, GIC_TRIG_LEVEL); 992 983 write_gic_rmask(i); 993 984 } 994 - } else { 985 + } else if (mips_cps_numcores(cl) != 0) { 995 986 mips_cm_lock_other(cl, 0, 0, CM_GCR_Cx_OTHER_BLOCK_GLOBAL); 996 987 for (i = 0; i < gic_shared_intrs; i++) { 997 988 change_gic_redir_pol(i, GIC_POL_ACTIVE_HIGH); ··· 999 990 write_gic_redir_rmask(i); 1000 991 } 1001 992 mips_cm_unlock_other(); 993 + 994 + } else { 995 + pr_warn("No CPU cores on the cluster %d skip it\n", cl); 1002 996 } 1003 997 } 1004 998