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

Configure Feed

Select the types of activity you want to include in your feed.

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

+73 -32
-7
drivers/irqchip/Kconfig
··· 45 45 select IRQ_MSI_LIB 46 46 default ARM_GIC_V3 47 47 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 - 55 48 config ARM_GIC_V3_ITS_FSL_MC 56 49 bool 57 50 depends on ARM_GIC_V3_ITS
+12 -6
drivers/irqchip/irq-gic-v3-its.c
··· 797 797 its_encode_valid(cmd, desc->its_vmapp_cmd.valid); 798 798 799 799 if (!desc->its_vmapp_cmd.valid) { 800 + alloc = !atomic_dec_return(&desc->its_vmapp_cmd.vpe->vmapp_count); 800 801 if (is_v4_1(its)) { 801 - alloc = !atomic_dec_return(&desc->its_vmapp_cmd.vpe->vmapp_count); 802 802 its_encode_alloc(cmd, alloc); 803 803 /* 804 804 * Unmapping a VPE is self-synchronizing on GICv4.1, ··· 817 817 its_encode_vpt_addr(cmd, vpt_addr); 818 818 its_encode_vpt_size(cmd, LPI_NRBITS - 1); 819 819 820 + alloc = !atomic_fetch_inc(&desc->its_vmapp_cmd.vpe->vmapp_count); 821 + 820 822 if (!is_v4_1(its)) 821 823 goto out; 822 824 823 825 vconf_addr = virt_to_phys(page_address(desc->its_vmapp_cmd.vpe->its_vm->vprop_page)); 824 - 825 - alloc = !atomic_fetch_inc(&desc->its_vmapp_cmd.vpe->vmapp_count); 826 826 827 827 its_encode_alloc(cmd, alloc); 828 828 ··· 3807 3807 unsigned long flags; 3808 3808 3809 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 + 3816 + /* 3810 3817 * Changing affinity is mega expensive, so let's be as lazy as 3811 3818 * we can and only do it if we really have to. Also, if mapped 3812 3819 * into the proxy device, we need to move the doorbell ··· 4470 4463 raw_spin_lock_init(&vpe->vpe_lock); 4471 4464 vpe->vpe_id = vpe_id; 4472 4465 vpe->vpt_page = vpt_page; 4473 - if (gic_rdists->has_rvpeid) 4474 - atomic_set(&vpe->vmapp_count, 0); 4475 - else 4466 + atomic_set(&vpe->vmapp_count, 0); 4467 + if (!gic_rdists->has_rvpeid) 4476 4468 vpe->vpe_proxy_event = -1; 4477 4469 4478 4470 return 0;
+8 -2
drivers/irqchip/irq-mscc-ocelot.c
··· 37 37 .reg_off_ena_clr = 0x1c, 38 38 .reg_off_ena_set = 0x20, 39 39 .reg_off_ident = 0x38, 40 - .reg_off_trigger = 0x5c, 40 + .reg_off_trigger = 0x4, 41 41 .n_irq = 24, 42 42 }; 43 43 ··· 70 70 .reg_off_ena_clr = 0x1c, 71 71 .reg_off_ena_set = 0x20, 72 72 .reg_off_ident = 0x38, 73 - .reg_off_trigger = 0x5c, 73 + .reg_off_trigger = 0x4, 74 74 .n_irq = 29, 75 75 }; 76 76 ··· 84 84 u32 val; 85 85 86 86 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 + */ 87 93 val = irq_reg_readl(gc, ICPU_CFG_INTR_INTR_TRIGGER(p, 0)) | 88 94 irq_reg_readl(gc, ICPU_CFG_INTR_INTR_TRIGGER(p, 1)); 89 95 if (!(val & mask))
+14 -2
drivers/irqchip/irq-renesas-rzg2l.c
··· 8 8 */ 9 9 10 10 #include <linux/bitfield.h> 11 + #include <linux/cleanup.h> 11 12 #include <linux/clk.h> 12 13 #include <linux/err.h> 13 14 #include <linux/io.h> ··· 531 530 static int rzg2l_irqc_common_init(struct device_node *node, struct device_node *parent, 532 531 const struct irq_chip *irq_chip) 533 532 { 533 + struct platform_device *pdev = of_find_device_by_node(node); 534 + struct device *dev __free(put_device) = pdev ? &pdev->dev : NULL; 534 535 struct irq_domain *irq_domain, *parent_domain; 535 - struct platform_device *pdev; 536 536 struct reset_control *resetn; 537 537 int ret; 538 538 539 - pdev = of_find_device_by_node(node); 540 539 if (!pdev) 541 540 return -ENODEV; 542 541 ··· 591 590 } 592 591 593 592 register_syscore_ops(&rzg2l_irqc_syscore_ops); 593 + 594 + /* 595 + * Prevent the cleanup function from invoking put_device by assigning 596 + * NULL to dev. 597 + * 598 + * make coccicheck will complain about missing put_device calls, but 599 + * those are false positives, as dev will be automatically "put" via 600 + * __free_put_device on the failing path. 601 + * On the successful path we don't actually want to "put" dev. 602 + */ 603 + dev = NULL; 594 604 595 605 return 0; 596 606
+1 -1
drivers/irqchip/irq-riscv-imsic-platform.c
··· 341 341 imsic->fwnode, global->hart_index_bits, global->guest_index_bits); 342 342 pr_info("%pfwP: group-index-bits: %d, group-index-shift: %d\n", 343 343 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", 345 345 imsic->fwnode, global->nr_ids, &global->base_addr); 346 346 pr_info("%pfwP: total %d interrupts available\n", 347 347 imsic->fwnode, num_possible_cpus() * (global->nr_ids - 1));
+18 -1
drivers/irqchip/irq-riscv-intc.c
··· 265 265 }; 266 266 267 267 static u32 nr_rintc; 268 - static struct rintc_data *rintc_acpi_data[NR_CPUS]; 268 + static struct rintc_data **rintc_acpi_data; 269 269 270 270 #define for_each_matching_plic(_plic_id) \ 271 271 unsigned int _plic; \ ··· 329 329 return 0; 330 330 } 331 331 332 + static int __init riscv_intc_acpi_match(union acpi_subtable_headers *header, 333 + const unsigned long end) 334 + { 335 + return 0; 336 + } 337 + 332 338 static int __init riscv_intc_acpi_init(union acpi_subtable_headers *header, 333 339 const unsigned long end) 334 340 { 335 341 struct acpi_madt_rintc *rintc; 336 342 struct fwnode_handle *fn; 343 + int count; 337 344 int rc; 345 + 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 + } 338 355 339 356 rintc = (struct acpi_madt_rintc *)header; 340 357 rintc_acpi_data[nr_rintc] = kzalloc(sizeof(*rintc_acpi_data[0]), GFP_KERNEL);
+17 -12
drivers/irqchip/irq-sifive-plic.c
··· 126 126 } 127 127 } 128 128 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 - 139 129 static void plic_irq_unmask(struct irq_data *d) 140 130 { 141 131 struct plic_priv *priv = irq_data_get_irq_chip_data(d); ··· 138 148 struct plic_priv *priv = irq_data_get_irq_chip_data(d); 139 149 140 150 writel(0, priv->regs + PRIORITY_BASE + d->hwirq * PRIORITY_PER_ID); 151 + } 152 + 153 + static void plic_irq_enable(struct irq_data *d) 154 + { 155 + plic_irq_toggle(irq_data_get_effective_affinity_mask(d), d, 1); 156 + plic_irq_unmask(d); 157 + } 158 + 159 + static void plic_irq_disable(struct irq_data *d) 160 + { 161 + plic_irq_toggle(irq_data_get_effective_affinity_mask(d), d, 0); 141 162 } 142 163 143 164 static void plic_irq_eoi(struct irq_data *d) ··· 627 626 628 627 handler->enable_save = kcalloc(DIV_ROUND_UP(nr_irqs, 32), 629 628 sizeof(*handler->enable_save), GFP_KERNEL); 630 - if (!handler->enable_save) 629 + if (!handler->enable_save) { 630 + error = -ENOMEM; 631 631 goto fail_cleanup_contexts; 632 + } 632 633 done: 633 634 for (hwirq = 1; hwirq <= nr_irqs; hwirq++) { 634 635 plic_toggle(handler, hwirq, 0); ··· 642 639 643 640 priv->irqdomain = irq_domain_create_linear(fwnode, nr_irqs + 1, 644 641 &plic_irqdomain_ops, priv); 645 - if (WARN_ON(!priv->irqdomain)) 642 + if (WARN_ON(!priv->irqdomain)) { 643 + error = -ENOMEM; 646 644 goto fail_cleanup_contexts; 645 + } 647 646 648 647 /* 649 648 * We can have multiple PLIC instances so setup global state
+3 -1
include/linux/irqchip/arm-gic-v4.h
··· 66 66 bool enabled; 67 67 bool group; 68 68 } sgi_config[16]; 69 - atomic_t vmapp_count; 70 69 }; 71 70 }; 71 + 72 + /* Track the VPE being mapped */ 73 + atomic_t vmapp_count; 72 74 73 75 /* 74 76 * Ensures mutual exclusion between affinity setting of the