Skip to content

Commit 949c9ef

Browse files
committed
Merge tag 'irq_urgent_for_v6.12_rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull irq fixes from Borislav Petkov: - Fix a case for sifive-plic where an interrupt gets disabled *and* masked and remains masked when it gets reenabled later - Plug a small race in GIC-v4 where userspace can force an affinity change of a virtual CPU (vPE) in its unmapping path - Do not mix the two sets of ocelot irqchip's registers in the mask calculation of the main interrupt sticky register - Other smaller fixlets and cleanups * tag 'irq_urgent_for_v6.12_rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: irqchip/renesas-rzg2l: Fix missing put_device irqchip/riscv-intc: Fix SMP=n boot with ACPI irqchip/sifive-plic: Unmask interrupt in plic_irq_enable() irqchip/gic-v4: Don't allow a VMOVP on a dying VPE irqchip/sifive-plic: Return error code on failure irqchip/riscv-imsic: Fix output text of base address irqchip/ocelot: Comment sticky register clearing code irqchip/ocelot: Fix trigger register address irqchip: Remove obsolete config ARM_GIC_V3_ITS_PCI
2 parents 2b4d250 + d038109 commit 949c9ef

File tree

8 files changed

+73
-32
lines changed

8 files changed

+73
-32
lines changed

drivers/irqchip/Kconfig

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -45,13 +45,6 @@ config ARM_GIC_V3_ITS
4545
select IRQ_MSI_LIB
4646
default ARM_GIC_V3
4747

48-
config ARM_GIC_V3_ITS_PCI
49-
bool
50-
depends on ARM_GIC_V3_ITS
51-
depends on PCI
52-
depends on PCI_MSI
53-
default ARM_GIC_V3_ITS
54-
5548
config ARM_GIC_V3_ITS_FSL_MC
5649
bool
5750
depends on ARM_GIC_V3_ITS

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

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -797,8 +797,8 @@ static struct its_vpe *its_build_vmapp_cmd(struct its_node *its,
797797
its_encode_valid(cmd, desc->its_vmapp_cmd.valid);
798798

799799
if (!desc->its_vmapp_cmd.valid) {
800+
alloc = !atomic_dec_return(&desc->its_vmapp_cmd.vpe->vmapp_count);
800801
if (is_v4_1(its)) {
801-
alloc = !atomic_dec_return(&desc->its_vmapp_cmd.vpe->vmapp_count);
802802
its_encode_alloc(cmd, alloc);
803803
/*
804804
* Unmapping a VPE is self-synchronizing on GICv4.1,
@@ -817,13 +817,13 @@ static struct its_vpe *its_build_vmapp_cmd(struct its_node *its,
817817
its_encode_vpt_addr(cmd, vpt_addr);
818818
its_encode_vpt_size(cmd, LPI_NRBITS - 1);
819819

820+
alloc = !atomic_fetch_inc(&desc->its_vmapp_cmd.vpe->vmapp_count);
821+
820822
if (!is_v4_1(its))
821823
goto out;
822824

823825
vconf_addr = virt_to_phys(page_address(desc->its_vmapp_cmd.vpe->its_vm->vprop_page));
824826

825-
alloc = !atomic_fetch_inc(&desc->its_vmapp_cmd.vpe->vmapp_count);
826-
827827
its_encode_alloc(cmd, alloc);
828828

829829
/*
@@ -3806,6 +3806,13 @@ static int its_vpe_set_affinity(struct irq_data *d,
38063806
struct cpumask *table_mask;
38073807
unsigned long flags;
38083808

3809+
/*
3810+
* Check if we're racing against a VPE being destroyed, for
3811+
* which we don't want to allow a VMOVP.
3812+
*/
3813+
if (!atomic_read(&vpe->vmapp_count))
3814+
return -EINVAL;
3815+
38093816
/*
38103817
* Changing affinity is mega expensive, so let's be as lazy as
38113818
* we can and only do it if we really have to. Also, if mapped
@@ -4463,9 +4470,8 @@ static int its_vpe_init(struct its_vpe *vpe)
44634470
raw_spin_lock_init(&vpe->vpe_lock);
44644471
vpe->vpe_id = vpe_id;
44654472
vpe->vpt_page = vpt_page;
4466-
if (gic_rdists->has_rvpeid)
4467-
atomic_set(&vpe->vmapp_count, 0);
4468-
else
4473+
atomic_set(&vpe->vmapp_count, 0);
4474+
if (!gic_rdists->has_rvpeid)
44694475
vpe->vpe_proxy_event = -1;
44704476

44714477
return 0;

drivers/irqchip/irq-mscc-ocelot.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ static struct chip_props ocelot_props = {
3737
.reg_off_ena_clr = 0x1c,
3838
.reg_off_ena_set = 0x20,
3939
.reg_off_ident = 0x38,
40-
.reg_off_trigger = 0x5c,
40+
.reg_off_trigger = 0x4,
4141
.n_irq = 24,
4242
};
4343

@@ -70,7 +70,7 @@ static struct chip_props jaguar2_props = {
7070
.reg_off_ena_clr = 0x1c,
7171
.reg_off_ena_set = 0x20,
7272
.reg_off_ident = 0x38,
73-
.reg_off_trigger = 0x5c,
73+
.reg_off_trigger = 0x4,
7474
.n_irq = 29,
7575
};
7676

@@ -84,6 +84,12 @@ static void ocelot_irq_unmask(struct irq_data *data)
8484
u32 val;
8585

8686
irq_gc_lock(gc);
87+
/*
88+
* Clear sticky bits for edge mode interrupts.
89+
* Serval has only one trigger register replication, but the adjacent
90+
* register is always read as zero, so there's no need to handle this
91+
* case separately.
92+
*/
8793
val = irq_reg_readl(gc, ICPU_CFG_INTR_INTR_TRIGGER(p, 0)) |
8894
irq_reg_readl(gc, ICPU_CFG_INTR_INTR_TRIGGER(p, 1));
8995
if (!(val & mask))

drivers/irqchip/irq-renesas-rzg2l.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
*/
99

1010
#include <linux/bitfield.h>
11+
#include <linux/cleanup.h>
1112
#include <linux/clk.h>
1213
#include <linux/err.h>
1314
#include <linux/io.h>
@@ -530,12 +531,12 @@ static int rzg2l_irqc_parse_interrupts(struct rzg2l_irqc_priv *priv,
530531
static int rzg2l_irqc_common_init(struct device_node *node, struct device_node *parent,
531532
const struct irq_chip *irq_chip)
532533
{
534+
struct platform_device *pdev = of_find_device_by_node(node);
535+
struct device *dev __free(put_device) = pdev ? &pdev->dev : NULL;
533536
struct irq_domain *irq_domain, *parent_domain;
534-
struct platform_device *pdev;
535537
struct reset_control *resetn;
536538
int ret;
537539

538-
pdev = of_find_device_by_node(node);
539540
if (!pdev)
540541
return -ENODEV;
541542

@@ -591,6 +592,17 @@ static int rzg2l_irqc_common_init(struct device_node *node, struct device_node *
591592

592593
register_syscore_ops(&rzg2l_irqc_syscore_ops);
593594

595+
/*
596+
* Prevent the cleanup function from invoking put_device by assigning
597+
* NULL to dev.
598+
*
599+
* make coccicheck will complain about missing put_device calls, but
600+
* those are false positives, as dev will be automatically "put" via
601+
* __free_put_device on the failing path.
602+
* On the successful path we don't actually want to "put" dev.
603+
*/
604+
dev = NULL;
605+
594606
return 0;
595607

596608
pm_put:

drivers/irqchip/irq-riscv-imsic-platform.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -341,7 +341,7 @@ int imsic_irqdomain_init(void)
341341
imsic->fwnode, global->hart_index_bits, global->guest_index_bits);
342342
pr_info("%pfwP: group-index-bits: %d, group-index-shift: %d\n",
343343
imsic->fwnode, global->group_index_bits, global->group_index_shift);
344-
pr_info("%pfwP: per-CPU IDs %d at base PPN %pa\n",
344+
pr_info("%pfwP: per-CPU IDs %d at base address %pa\n",
345345
imsic->fwnode, global->nr_ids, &global->base_addr);
346346
pr_info("%pfwP: total %d interrupts available\n",
347347
imsic->fwnode, num_possible_cpus() * (global->nr_ids - 1));

drivers/irqchip/irq-riscv-intc.c

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,7 @@ struct rintc_data {
265265
};
266266

267267
static u32 nr_rintc;
268-
static struct rintc_data *rintc_acpi_data[NR_CPUS];
268+
static struct rintc_data **rintc_acpi_data;
269269

270270
#define for_each_matching_plic(_plic_id) \
271271
unsigned int _plic; \
@@ -329,13 +329,30 @@ int acpi_rintc_get_imsic_mmio_info(u32 index, struct resource *res)
329329
return 0;
330330
}
331331

332+
static int __init riscv_intc_acpi_match(union acpi_subtable_headers *header,
333+
const unsigned long end)
334+
{
335+
return 0;
336+
}
337+
332338
static int __init riscv_intc_acpi_init(union acpi_subtable_headers *header,
333339
const unsigned long end)
334340
{
335341
struct acpi_madt_rintc *rintc;
336342
struct fwnode_handle *fn;
343+
int count;
337344
int rc;
338345

346+
if (!rintc_acpi_data) {
347+
count = acpi_table_parse_madt(ACPI_MADT_TYPE_RINTC, riscv_intc_acpi_match, 0);
348+
if (count <= 0)
349+
return -EINVAL;
350+
351+
rintc_acpi_data = kcalloc(count, sizeof(*rintc_acpi_data), GFP_KERNEL);
352+
if (!rintc_acpi_data)
353+
return -ENOMEM;
354+
}
355+
339356
rintc = (struct acpi_madt_rintc *)header;
340357
rintc_acpi_data[nr_rintc] = kzalloc(sizeof(*rintc_acpi_data[0]), GFP_KERNEL);
341358
if (!rintc_acpi_data[nr_rintc])

drivers/irqchip/irq-sifive-plic.c

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -126,16 +126,6 @@ static inline void plic_irq_toggle(const struct cpumask *mask,
126126
}
127127
}
128128

129-
static void plic_irq_enable(struct irq_data *d)
130-
{
131-
plic_irq_toggle(irq_data_get_effective_affinity_mask(d), d, 1);
132-
}
133-
134-
static void plic_irq_disable(struct irq_data *d)
135-
{
136-
plic_irq_toggle(irq_data_get_effective_affinity_mask(d), d, 0);
137-
}
138-
139129
static void plic_irq_unmask(struct irq_data *d)
140130
{
141131
struct plic_priv *priv = irq_data_get_irq_chip_data(d);
@@ -150,6 +140,17 @@ static void plic_irq_mask(struct irq_data *d)
150140
writel(0, priv->regs + PRIORITY_BASE + d->hwirq * PRIORITY_PER_ID);
151141
}
152142

143+
static void plic_irq_enable(struct irq_data *d)
144+
{
145+
plic_irq_toggle(irq_data_get_effective_affinity_mask(d), d, 1);
146+
plic_irq_unmask(d);
147+
}
148+
149+
static void plic_irq_disable(struct irq_data *d)
150+
{
151+
plic_irq_toggle(irq_data_get_effective_affinity_mask(d), d, 0);
152+
}
153+
153154
static void plic_irq_eoi(struct irq_data *d)
154155
{
155156
struct plic_handler *handler = this_cpu_ptr(&plic_handlers);
@@ -626,8 +627,10 @@ static int plic_probe(struct fwnode_handle *fwnode)
626627

627628
handler->enable_save = kcalloc(DIV_ROUND_UP(nr_irqs, 32),
628629
sizeof(*handler->enable_save), GFP_KERNEL);
629-
if (!handler->enable_save)
630+
if (!handler->enable_save) {
631+
error = -ENOMEM;
630632
goto fail_cleanup_contexts;
633+
}
631634
done:
632635
for (hwirq = 1; hwirq <= nr_irqs; hwirq++) {
633636
plic_toggle(handler, hwirq, 0);
@@ -639,8 +642,10 @@ static int plic_probe(struct fwnode_handle *fwnode)
639642

640643
priv->irqdomain = irq_domain_create_linear(fwnode, nr_irqs + 1,
641644
&plic_irqdomain_ops, priv);
642-
if (WARN_ON(!priv->irqdomain))
645+
if (WARN_ON(!priv->irqdomain)) {
646+
error = -ENOMEM;
643647
goto fail_cleanup_contexts;
648+
}
644649

645650
/*
646651
* We can have multiple PLIC instances so setup global state

include/linux/irqchip/arm-gic-v4.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,10 +66,12 @@ struct its_vpe {
6666
bool enabled;
6767
bool group;
6868
} sgi_config[16];
69-
atomic_t vmapp_count;
7069
};
7170
};
7271

72+
/* Track the VPE being mapped */
73+
atomic_t vmapp_count;
74+
7375
/*
7476
* Ensures mutual exclusion between affinity setting of the
7577
* vPE and vLPI operations using vpe->col_idx.

0 commit comments

Comments
 (0)