Skip to content

Commit

Permalink
Merge tag 'irq-urgent-2024-08-25' of git://git.kernel.org/pub/scm/lin…
Browse files Browse the repository at this point in the history
…ux/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
  • Loading branch information
Linus Torvalds committed Sep 1, 2024
2 parents 431c164 + 880799f commit 9a75429
Show file tree
Hide file tree
Showing 6 changed files with 104 additions and 63 deletions.
6 changes: 3 additions & 3 deletions drivers/irqchip/irq-gic-v2m.c
Original file line number Diff line number Diff line change
Expand Up @@ -407,12 +407,12 @@ static int __init gicv2m_of_init(struct fwnode_handle *parent_handle,

ret = gicv2m_init_one(&child->fwnode, spi_start, nr_spis,
&res, 0);
if (ret) {
of_node_put(child);
if (ret)
break;
}
}

if (ret && child)
of_node_put(child);
if (!ret)
ret = gicv2m_allocate_domains(parent);
if (ret)
Expand Down
16 changes: 10 additions & 6 deletions drivers/irqchip/irq-gic-v3-its.c
Original file line number Diff line number Diff line change
Expand Up @@ -1329,12 +1329,6 @@ static void its_send_vmovp(struct its_vpe *vpe)
return;
}

/*
* Protect against concurrent updates of the mapping state on
* individual VMs.
*/
guard(raw_spinlock_irqsave)(&vpe->its_vm->vmapp_lock);

/*
* Yet another marvel of the architecture. If using the
* its_list "feature", we need to make sure that all ITSs
Expand Down Expand Up @@ -3824,7 +3818,14 @@ static int its_vpe_set_affinity(struct irq_data *d,
* protect us, and that we must ensure nobody samples vpe->col_idx
* during the update, hence the lock below which must also be
* taken on any vLPI handling path that evaluates vpe->col_idx.
*
* Finally, we must protect ourselves against concurrent updates of
* the mapping state on this VM should the ITS list be in use (see
* the shortcut in its_send_vmovp() otherewise).
*/
if (its_list_map)
raw_spin_lock(&vpe->its_vm->vmapp_lock);

from = vpe_to_cpuid_lock(vpe, &flags);
table_mask = gic_data_rdist_cpu(from)->vpe_table_mask;

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

if (its_list_map)
raw_spin_unlock(&vpe->its_vm->vmapp_lock);

return IRQ_SET_MASK_OK_DONE;
}

Expand Down
21 changes: 14 additions & 7 deletions drivers/irqchip/irq-gic-v3.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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();
Expand Down Expand Up @@ -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())
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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();
Expand Down
5 changes: 4 additions & 1 deletion drivers/irqchip/irq-msi-lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -128,13 +128,16 @@ int msi_lib_irq_domain_select(struct irq_domain *d, struct irq_fwspec *fwspec,
const struct msi_parent_ops *ops = d->msi_parent_ops;
u32 busmask = BIT(bus_token);

if (!ops)
return 0;

if (fwspec->fwnode != d->fwnode || fwspec->param_count != 0)
return 0;

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

return ops && !!(ops->bus_select_mask & busmask);
return !!(ops->bus_select_mask & busmask);
}
EXPORT_SYMBOL_GPL(msi_lib_irq_domain_select);
4 changes: 2 additions & 2 deletions drivers/irqchip/irq-riscv-aplic-main.c
Original file line number Diff line number Diff line change
Expand Up @@ -175,9 +175,9 @@ static int aplic_probe(struct platform_device *pdev)

/* Map the MMIO registers */
regs = devm_platform_ioremap_resource(pdev, 0);
if (!regs) {
if (IS_ERR(regs)) {
dev_err(dev, "failed map MMIO registers\n");
return -ENOMEM;
return PTR_ERR(regs);
}

/*
Expand Down
Loading

0 comments on commit 9a75429

Please sign in to comment.