Skip to content

Commit 9a75429

Browse files
committed
Merge tag 'irq-urgent-2024-08-25' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull irq fixes from Thomas Gleixner: "A set of fixes for interrupt chip drivers: - Unbreak the PLIC driver for Allwinner D1 systems The recent conversion of the PLIC driver to a platform driver broke Allwinnder D1 systems due to the deferred probing of platform drivers. Due to that the only timer available on D1 systems cannot get an interrupt, which causes the system to hang at boot. Other RISCV platforms are not affected because they provide the architected SBI timer which uses the built in core interrupt controller. Cure this by probing PLIC early on D1 systems - Cure a regression in ARM/GIC-V3 on 32-bit ARM systems caused by the recent addition of a initialization function, which accesses system registers before they are enabled. On 64-bit ARM they are enabled prior to that by sheer luck. Ensure they are enabled. - Cure a use before check problem in the MSI library. The existing NULL pointer check is too late. - Cure a lock order inversion in the ARM/GIC-V4 driver - Fix a IS_ERR() vs. NULL pointer check issue in the RISCV APLIC driver - Plug a reference count leak in the ARM/GIC-V2 driver" * tag 'irq-urgent-2024-08-25' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: irqchip/irq-msi-lib: Check for NULL ops in msi_lib_irq_domain_select() irqchip/gic-v3: Init SRE before poking sysregs irqchip/gic-v2m: Fix refcount leak in gicv2m_of_init() irqchip/riscv-aplic: Fix an IS_ERR() vs NULL bug in probe() irqchip/gic-v4: Fix ordering between vmapp and vpe locks irqchip/sifive-plic: Probe plic driver early for Allwinner D1 platform
2 parents 431c164 + 880799f commit 9a75429

File tree

6 files changed

+104
-63
lines changed

6 files changed

+104
-63
lines changed

drivers/irqchip/irq-gic-v2m.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -407,12 +407,12 @@ static int __init gicv2m_of_init(struct fwnode_handle *parent_handle,
407407

408408
ret = gicv2m_init_one(&child->fwnode, spi_start, nr_spis,
409409
&res, 0);
410-
if (ret) {
411-
of_node_put(child);
410+
if (ret)
412411
break;
413-
}
414412
}
415413

414+
if (ret && child)
415+
of_node_put(child);
416416
if (!ret)
417417
ret = gicv2m_allocate_domains(parent);
418418
if (ret)

drivers/irqchip/irq-gic-v3-its.c

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1329,12 +1329,6 @@ static void its_send_vmovp(struct its_vpe *vpe)
13291329
return;
13301330
}
13311331

1332-
/*
1333-
* Protect against concurrent updates of the mapping state on
1334-
* individual VMs.
1335-
*/
1336-
guard(raw_spinlock_irqsave)(&vpe->its_vm->vmapp_lock);
1337-
13381332
/*
13391333
* Yet another marvel of the architecture. If using the
13401334
* its_list "feature", we need to make sure that all ITSs
@@ -3824,7 +3818,14 @@ static int its_vpe_set_affinity(struct irq_data *d,
38243818
* protect us, and that we must ensure nobody samples vpe->col_idx
38253819
* during the update, hence the lock below which must also be
38263820
* taken on any vLPI handling path that evaluates vpe->col_idx.
3821+
*
3822+
* Finally, we must protect ourselves against concurrent updates of
3823+
* the mapping state on this VM should the ITS list be in use (see
3824+
* the shortcut in its_send_vmovp() otherewise).
38273825
*/
3826+
if (its_list_map)
3827+
raw_spin_lock(&vpe->its_vm->vmapp_lock);
3828+
38283829
from = vpe_to_cpuid_lock(vpe, &flags);
38293830
table_mask = gic_data_rdist_cpu(from)->vpe_table_mask;
38303831

@@ -3854,6 +3855,9 @@ static int its_vpe_set_affinity(struct irq_data *d,
38543855
irq_data_update_effective_affinity(d, cpumask_of(cpu));
38553856
vpe_to_cpuid_unlock(vpe, flags);
38563857

3858+
if (its_list_map)
3859+
raw_spin_unlock(&vpe->its_vm->vmapp_lock);
3860+
38573861
return IRQ_SET_MASK_OK_DONE;
38583862
}
38593863

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();

drivers/irqchip/irq-msi-lib.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,13 +128,16 @@ int msi_lib_irq_domain_select(struct irq_domain *d, struct irq_fwspec *fwspec,
128128
const struct msi_parent_ops *ops = d->msi_parent_ops;
129129
u32 busmask = BIT(bus_token);
130130

131+
if (!ops)
132+
return 0;
133+
131134
if (fwspec->fwnode != d->fwnode || fwspec->param_count != 0)
132135
return 0;
133136

134137
/* Handle pure domain searches */
135138
if (bus_token == ops->bus_select_token)
136139
return 1;
137140

138-
return ops && !!(ops->bus_select_mask & busmask);
141+
return !!(ops->bus_select_mask & busmask);
139142
}
140143
EXPORT_SYMBOL_GPL(msi_lib_irq_domain_select);

drivers/irqchip/irq-riscv-aplic-main.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -175,9 +175,9 @@ static int aplic_probe(struct platform_device *pdev)
175175

176176
/* Map the MMIO registers */
177177
regs = devm_platform_ioremap_resource(pdev, 0);
178-
if (!regs) {
178+
if (IS_ERR(regs)) {
179179
dev_err(dev, "failed map MMIO registers\n");
180-
return -ENOMEM;
180+
return PTR_ERR(regs);
181181
}
182182

183183
/*

0 commit comments

Comments
 (0)