]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
vfio/pci: Handle INTx IRQ_NOTCONNECTED
authorAlex Williamson <alex.williamson@redhat.com>
Tue, 11 Mar 2025 23:06:21 +0000 (17:06 -0600)
committerAlex Williamson <alex.williamson@redhat.com>
Mon, 17 Mar 2025 21:15:17 +0000 (15:15 -0600)
Some systems report INTx as not routed by setting pdev->irq to
IRQ_NOTCONNECTED, resulting in a -ENOTCONN error when trying to
setup eventfd signaling.  Include this in the set of conditions
for which the PIN register is virtualized to zero.

Additionally consolidate vfio_pci_get_irq_count() to use this
virtualized value in reporting INTx support via ioctl and sanity
checking ioctl paths since pdev->irq is re-used when the device
is in MSI mode.

The combination of these results in both the config space of the
device and the ioctl interface behaving as if the device does not
support INTx.

Reviewed-by: Kevin Tian <kevin.tian@intel.com>
Link: https://lore.kernel.org/r/20250311230623.1264283-1-alex.williamson@redhat.com
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
drivers/vfio/pci/vfio_pci_config.c
drivers/vfio/pci/vfio_pci_core.c
drivers/vfio/pci/vfio_pci_intrs.c

index 94142581c98ce83f941a9182dd877761bb87cd99..14437396d72118d8b462ad570aa8bb86a253ef04 100644 (file)
@@ -1814,7 +1814,8 @@ int vfio_config_init(struct vfio_pci_core_device *vdev)
                                        cpu_to_le16(PCI_COMMAND_MEMORY);
        }
 
-       if (!IS_ENABLED(CONFIG_VFIO_PCI_INTX) || vdev->nointx)
+       if (!IS_ENABLED(CONFIG_VFIO_PCI_INTX) || vdev->nointx ||
+           vdev->pdev->irq == IRQ_NOTCONNECTED)
                vconfig[PCI_INTERRUPT_PIN] = 0;
 
        ret = vfio_cap_init(vdev);
index 586e49efb81be32ccb50ca554a60cec684c37402..c857630f447b371084bc097fe0e73096418d503c 100644 (file)
@@ -727,15 +727,7 @@ EXPORT_SYMBOL_GPL(vfio_pci_core_finish_enable);
 static int vfio_pci_get_irq_count(struct vfio_pci_core_device *vdev, int irq_type)
 {
        if (irq_type == VFIO_PCI_INTX_IRQ_INDEX) {
-               u8 pin;
-
-               if (!IS_ENABLED(CONFIG_VFIO_PCI_INTX) ||
-                   vdev->nointx || vdev->pdev->is_virtfn)
-                       return 0;
-
-               pci_read_config_byte(vdev->pdev, PCI_INTERRUPT_PIN, &pin);
-
-               return pin ? 1 : 0;
+               return vdev->vconfig[PCI_INTERRUPT_PIN] ? 1 : 0;
        } else if (irq_type == VFIO_PCI_MSI_IRQ_INDEX) {
                u8 pos;
                u16 flags;
index 8382c583433565f9cecbed9fefbd0cbbcbcc809f..565966351dfadc590f6ab59b5cabce1b3a5b09f7 100644 (file)
@@ -259,7 +259,7 @@ static int vfio_intx_enable(struct vfio_pci_core_device *vdev,
        if (!is_irq_none(vdev))
                return -EINVAL;
 
-       if (!pdev->irq)
+       if (!pdev->irq || pdev->irq == IRQ_NOTCONNECTED)
                return -ENODEV;
 
        name = kasprintf(GFP_KERNEL_ACCOUNT, "vfio-intx(%s)", pci_name(pdev));