On 2/5/26 04:11, Zhenzhong Duan wrote:
When both host device and vIOMMU have PASID enabled, then guest may
setup pasid attached translation.

We need to create the nesting parent hwpt with IOMMU_HWPT_ALLOC_PASID
flag because according to uAPI, any domain attached to the non-PASID
part of the device must also be flagged, otherwise attaching a PASID
will blocked.

Introduce a vfio_device_get_viommu_flags_pasid_supported() helper to
facilitate this implementation.

Signed-off-by: Zhenzhong Duan <[email protected]>
---
  include/hw/vfio/vfio-device.h |  1 +
  hw/vfio/device.c              | 11 +++++++++++
  hw/vfio/iommufd.c             |  8 +++++++-
  3 files changed, 19 insertions(+), 1 deletion(-)

diff --git a/include/hw/vfio/vfio-device.h b/include/hw/vfio/vfio-device.h
index 35a5ec6d92..983eb0ecce 100644
--- a/include/hw/vfio/vfio-device.h
+++ b/include/hw/vfio/vfio-device.h
@@ -268,6 +268,7 @@ void vfio_device_prepare(VFIODevice *vbasedev, 
VFIOContainer *bcontainer,
  void vfio_device_unprepare(VFIODevice *vbasedev);
bool vfio_device_get_viommu_flags_want_nesting(VFIODevice *vbasedev);
+bool vfio_device_get_viommu_flags_pasid_supported(VFIODevice *vbasedev);
  bool vfio_device_get_host_iommu_quirk_bypass_ro(VFIODevice *vbasedev,
                                                  uint32_t type, void *caps,
                                                  uint32_t size);
diff --git a/hw/vfio/device.c b/hw/vfio/device.c
index 973fc35b59..b15ca6ef0a 100644
--- a/hw/vfio/device.c
+++ b/hw/vfio/device.c
@@ -533,6 +533,17 @@ bool vfio_device_get_viommu_flags_want_nesting(VFIODevice 
*vbasedev)
      return false;
  }
+bool vfio_device_get_viommu_flags_pasid_supported(VFIODevice *vbasedev)
+{
+    VFIOPCIDevice *vdev = vfio_pci_from_vfio_device(vbasedev);
+
+    if (vdev) {
+        return !!(pci_device_get_viommu_flags(PCI_DEVICE(vdev)) &
+                  VIOMMU_FLAG_PASID_SUPPORTED);
+    }
+    return false;
+}
+
  bool vfio_device_get_host_iommu_quirk_bypass_ro(VFIODevice *vbasedev,
                                                  uint32_t type, void *caps,
                                                  uint32_t size)
diff --git a/hw/vfio/iommufd.c b/hw/vfio/iommufd.c
index 96735f1fc8..9605bf73b7 100644
--- a/hw/vfio/iommufd.c
+++ b/hw/vfio/iommufd.c
@@ -354,6 +354,7 @@ static bool iommufd_cdev_autodomains_get(VFIODevice 
*vbasedev,
      VendorCaps caps;
      VFIOIOASHwpt *hwpt;
      uint32_t hwpt_id;
+    uint8_t max_pasid_log2;

I think this should be initialized to some default value.

      int ret;
/* Try to find a domain */
@@ -398,7 +399,7 @@ static bool iommufd_cdev_autodomains_get(VFIODevice 
*vbasedev,
       */
      if (!iommufd_backend_get_device_info(vbasedev->iommufd, vbasedev->devid,
                                           &type, &caps, sizeof(caps), &hw_caps,
-                                         NULL, errp)) {
+                                         &max_pasid_log2, errp)) {
          return false;
      }
@@ -420,6 +421,11 @@ static bool iommufd_cdev_autodomains_get(VFIODevice *vbasedev,
          }
      }
+ if (max_pasid_log2 &&
+        vfio_device_get_viommu_flags_pasid_supported(vbasedev)) {

Can an IOMMU backend not support PASID while the vIOMMU device does ?
That would be a problem no ?

+        flags |= IOMMU_HWPT_ALLOC_PASID;
+    }
+
      if (cpr_is_incoming()) {
          hwpt_id = vbasedev->cpr.hwpt_id;
          goto skip_alloc;


Reply via email to