Merge tag 'irq-urgent-2024-11-03' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull irq fixes from Thomas Gleixner:

- Fix an off-by-one error in the failure path of msi_domain_alloc(),
which causes the cleanup loop to terminate early and leaking the
first allocated interrupt.

- Handle a corner case in GIC-V4 versus a lazily mapped Virtual
Processing Element (VPE). If the VPE has not been mapped because the
guest has not yet emitted a mapping command, then the set_affinity()
callback returns an error code, which causes the vCPU management to
fail.

Return success in this case without touching the hardware. This will
be done later when the guest issues the mapping command.

* tag 'irq-urgent-2024-11-03' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
irqchip/gic-v4: Correctly deal with set_affinity on lazily-mapped VPEs
genirq/msi: Fix off-by-one error in msi_domain_alloc()

+13 -3
+12 -2
drivers/irqchip/irq-gic-v3-its.c
··· 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 /* 3817 * Changing affinity is mega expensive, so let's be as lazy as
··· 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 + if (gic_requires_eager_mapping()) 3815 + return -EINVAL; 3816 + 3817 + /* 3818 + * If we lazily map the VPEs, this isn't an error and 3819 + * we can exit cleanly. 3820 + */ 3821 + cpu = cpumask_first(mask_val); 3822 + irq_data_update_effective_affinity(d, cpumask_of(cpu)); 3823 + return IRQ_SET_MASK_OK_DONE; 3824 + } 3825 3826 /* 3827 * Changing affinity is mega expensive, so let's be as lazy as
+1 -1
kernel/irq/msi.c
··· 718 ret = ops->msi_init(domain, info, virq + i, hwirq + i, arg); 719 if (ret < 0) { 720 if (ops->msi_free) { 721 - for (i--; i > 0; i--) 722 ops->msi_free(domain, info, virq + i); 723 } 724 irq_domain_free_irqs_top(domain, virq, nr_irqs);
··· 718 ret = ops->msi_init(domain, info, virq + i, hwirq + i, arg); 719 if (ret < 0) { 720 if (ops->msi_free) { 721 + for (i--; i >= 0; i--) 722 ops->msi_free(domain, info, virq + i); 723 } 724 irq_domain_free_irqs_top(domain, virq, nr_irqs);