Skip to content

Commit fe9a708

Browse files
committed
vfio/pci: Disable auto-enable of exclusive INTx IRQ
Currently for devices requiring masking at the irqchip for INTx, ie. devices without DisINTx support, the IRQ is enabled in request_irq() and subsequently disabled as necessary to align with the masked status flag. This presents a window where the interrupt could fire between these events, resulting in the IRQ incrementing the disable depth twice. This would be unrecoverable for a user since the masked flag prevents nested enables through vfio. Instead, invert the logic using IRQF_NO_AUTOEN such that exclusive INTx is never auto-enabled, then unmask as required. Cc: <stable@vger.kernel.org> Fixes: 89e1f7d ("vfio: Add PCI device driver") Reviewed-by: Kevin Tian <kevin.tian@intel.com> Reviewed-by: Eric Auger <eric.auger@redhat.com> Link: https://lore.kernel.org/r/20240308230557.805580-2-alex.williamson@redhat.com Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
1 parent 6a7e448 commit fe9a708

File tree

1 file changed

+10
-7
lines changed

1 file changed

+10
-7
lines changed

drivers/vfio/pci/vfio_pci_intrs.c

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -296,8 +296,15 @@ static int vfio_intx_set_signal(struct vfio_pci_core_device *vdev, int fd)
296296

297297
ctx->trigger = trigger;
298298

299+
/*
300+
* Devices without DisINTx support require an exclusive interrupt,
301+
* IRQ masking is performed at the IRQ chip. The masked status is
302+
* protected by vdev->irqlock. Setup the IRQ without auto-enable and
303+
* unmask as necessary below under lock. DisINTx is unmodified by
304+
* the IRQ configuration and may therefore use auto-enable.
305+
*/
299306
if (!vdev->pci_2_3)
300-
irqflags = 0;
307+
irqflags = IRQF_NO_AUTOEN;
301308

302309
ret = request_irq(pdev->irq, vfio_intx_handler,
303310
irqflags, ctx->name, vdev);
@@ -308,13 +315,9 @@ static int vfio_intx_set_signal(struct vfio_pci_core_device *vdev, int fd)
308315
return ret;
309316
}
310317

311-
/*
312-
* INTx disable will stick across the new irq setup,
313-
* disable_irq won't.
314-
*/
315318
spin_lock_irqsave(&vdev->irqlock, flags);
316-
if (!vdev->pci_2_3 && ctx->masked)
317-
disable_irq_nosync(pdev->irq);
319+
if (!vdev->pci_2_3 && !ctx->masked)
320+
enable_irq(pdev->irq);
318321
spin_unlock_irqrestore(&vdev->irqlock, flags);
319322

320323
return 0;

0 commit comments

Comments
 (0)