]> git.ipfire.org Git - thirdparty/kernel/stable.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)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 4 Jun 2025 12:37:56 +0000 (14:37 +0200)
[ Upstream commit 860be250fc32de9cb24154bf21b4e36f40925707 ]

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>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/vfio/pci/vfio_pci_config.c
drivers/vfio/pci/vfio_pci_core.c
drivers/vfio/pci/vfio_pci_intrs.c

index 63f6308b0f8c9e66f28d4e9c3958e8e011ddeddb..fdff3359849c18ecddb588b86e412b6b5d71c889 100644 (file)
@@ -1756,7 +1756,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 f3916e6b16b9dd28eab0560c7aec0b14f531801f..ea4e75be1884f29e7eb1112d02edd1df56cc6653 100644 (file)
@@ -481,15 +481,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 f20512c413f760594eee99752c0bd99916641110..5ade5b81a0ffbe046e5d2097e2264547554a4e86 100644 (file)
@@ -173,7 +173,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, "vfio-intx(%s)", pci_name(pdev));