On 1/19/26 18:22, Shameer Kolothum wrote:


-----Original Message-----
From: Eric Auger <[email protected]>
Sent: 19 January 2026 16:17
To: Shameer Kolothum <[email protected]>; qemu-
[email protected]; [email protected]
Cc: [email protected]; Jason Gunthorpe <[email protected]>; Nicolin
Chen <[email protected]>; [email protected]; [email protected];
[email protected]; [email protected]; Nathan Chen <[email protected]>;
Matt Ochs <[email protected]>; [email protected];
[email protected]; [email protected];
[email protected]; [email protected];
[email protected]; [email protected]; Krishnakant Jaju
<[email protected]>
Subject: Re: [PATCH v7 35/36] hw/vfio/pci: Synthesize PASID capability for
vfio-pci devices

External email: Use caution opening links or attachments


Hi Shameer,

On 1/11/26 8:53 PM, Shameer Kolothum wrote:
Add support for synthesizing a PCIe PASID extended capability for
vfio-pci devices when PASID is enabled via a vIOMMU and supported by
the host IOMMU backend.

PASID capability parameters are retrieved via IOMMUFD APIs and the
capability is inserted into the PCIe extended capability list using
the insertion helper. A new x-vpasid-cap-offset property allows
explicit control over the placement; by default the capability is
placed at the end of the PCIe extended configuration space.

If the kernel does not expose PASID information or insertion fails,
the device continues without PASID support.

Signed-off-by: Shameer Kolothum <[email protected]>
---
  hw/vfio/pci.c           | 84
+++++++++++++++++++++++++++++++++++++++++
  hw/vfio/pci.h           |  1 +
  include/hw/core/iommu.h |  1 +
  3 files changed, 86 insertions(+)

diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index c734472721..96990576ac 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -24,6 +24,7 @@
  #include <sys/ioctl.h>

  #include "hw/core/hw-error.h"
+#include "hw/core/iommu.h"
  #include "hw/pci/msi.h"
  #include "hw/pci/msix.h"
  #include "hw/pci/pci_bridge.h"
@@ -2498,9 +2499,71 @@ static int vfio_setup_rebar_ecap(VFIOPCIDevice
*vdev, uint16_t pos)
      return 0;
  }

+/*
+ * Try to retrieve PASID capability information via IOMMUFD APIs and,
+ * if supported, synthesize a PASID PCIe extended capability for the
+ * VFIO device.
+ *
+ * Use user-specified PASID capability offset if provided, otherwise
+ * place it at the end of the PCIe extended configuration space.
+ */
+static void vfio_pci_synthesize_pasid_cap(VFIOPCIDevice *vdev)
+{
+    HostIOMMUDevice *hiod = vdev->vbasedev.hiod;
+    HostIOMMUDeviceClass *hiodc;
+    PasidInfo pasid_info;
+    PCIDevice *pdev = PCI_DEVICE(vdev);
+    uint16_t pasid_offset;
+
+    if (vdev->vbasedev.mdev) {
+        return;
+    }
+
+    hiodc = HOST_IOMMU_DEVICE_GET_CLASS(hiod);
+    if (!hiodc || !hiodc->get_pasid_info ||
+        !hiodc->get_pasid_info(hiod, &pasid_info) ||
+        !(pci_device_get_viommu_flags(pdev) &
VIOMMU_FLAG_PASID_SUPPORTED)) {
+        return;
+    }
+
+    /*
+     * Check if user has specified an offset to place PASID CAP,
+     * else select the last offset as default
+     */
+    if (vdev->vpasid_cap_offset) {
+        if (!QEMU_IS_ALIGNED(vdev->vpasid_cap_offset,
PCI_EXT_CAP_ALIGN) ||
For other checks you put an assert i pcie_insert_capability()
+            vdev->vpasid_cap_offset < PCI_CONFIG_SPACE_SIZE ||
+            vdev->vpasid_cap_offset + PCI_EXT_CAP_PASID_SIZEOF >
+                PCIE_CONFIG_SPACE_SIZE) {
+            error_report("vfio: invalid x-vpasid-cap-offset 0x%x, skipping 
PASID",
+                        vdev->vpasid_cap_offset);
+            return;
+        }
+        pasid_offset = vdev->vpasid_cap_offset;
+    } else {
+        pasid_offset = PCIE_CONFIG_SPACE_SIZE -
PCI_EXT_CAP_PASID_SIZEOF;
+        warn_report("vfio: PASID capability offset(x-vpasid-cap-offset) not
specified, "
+                    "placing at the default offset 0x%x",
+                    pasid_offset);
I am not sure we want a warn_report() if this is a normal behavior. Add
a trace point instead?

Ok. I will replace this with a common trace for this function.

+    }
+
+    if (!pcie_insert_capability(pdev, PCI_EXT_CAP_ID_PASID, PCI_PASID_VER,
+                                pasid_offset, PCI_EXT_CAP_PASID_SIZEOF)) {
+        error_report("vfio: Placing PASID capability at offset 0x%x failed",
+                     pasid_offset);
instead of having asserts in pcie_insert_capability() you could
factorize all checks there including the 4B alignment check and return
false if any fails. Then you could propably get rifd of above checks
which are partially redundant. Thanks Eric

Agreed, will refactor accordingly.
Please add an 'Error *' parameter to vfio_pci_synthesize_pasid_cap() and
propagate the error.

Thanks,

C.


Reply via email to