On 4/11/25 12:17, Zhenzhong Duan wrote:
The saved caps copy can be used to check dirty tracking capability.

The capabilities is gotten through IOMMUFD interface, so define a
new structure HostIOMMUDeviceIOMMUFDCaps which contains vendor
caps raw data in "include/system/iommufd.h".

This is a prepare work for moving .realize() after .attach_device().

Suggested-by: Cédric Le Goater <c...@redhat.com>
Suggested-by: Eric Auger <eric.au...@redhat.com>
Suggested-by: Nicolin Chen <nicol...@nvidia.com>
Signed-off-by: Zhenzhong Duan <zhenzhong.d...@intel.com>
---
  include/hw/vfio/vfio-device.h |  1 +
  include/system/iommufd.h      | 22 ++++++++++++++++++++++
  hw/vfio/iommufd.c             | 10 +++++++++-
  3 files changed, 32 insertions(+), 1 deletion(-)

diff --git a/include/hw/vfio/vfio-device.h b/include/hw/vfio/vfio-device.h
index 66797b4c92..09a7af891a 100644
--- a/include/hw/vfio/vfio-device.h
+++ b/include/hw/vfio/vfio-device.h
@@ -77,6 +77,7 @@ typedef struct VFIODevice {
      bool dirty_tracking; /* Protected by BQL */
      bool iommu_dirty_tracking;
      HostIOMMUDevice *hiod;
+    HostIOMMUDeviceIOMMUFDCaps caps;

IMO, these capabilities belong to HostIOMMUDevice and not VFIODevice.

I would simply call iommufd_backend_get_device_info() twice where needed :
iommufd_cdev_autodomains_get() and  hiod_iommufd_vfio_realize()


Thanks,

C.



      int devid;
      IOMMUFDBackend *iommufd;
      VFIOIOASHwpt *hwpt;
diff --git a/include/system/iommufd.h b/include/system/iommufd.h
index cbab75bfbf..0f337585c9 100644
--- a/include/system/iommufd.h
+++ b/include/system/iommufd.h
@@ -18,6 +18,9 @@
  #include "exec/hwaddr.h"
  #include "exec/cpu-common.h"
  #include "system/host_iommu_device.h"
+#ifdef CONFIG_LINUX
+#include <linux/iommufd.h>
+#endif
#define TYPE_IOMMUFD_BACKEND "iommufd"
  OBJECT_DECLARE_TYPE(IOMMUFDBackend, IOMMUFDBackendClass, IOMMUFD_BACKEND)
@@ -63,4 +66,23 @@ bool iommufd_backend_get_dirty_bitmap(IOMMUFDBackend *be, 
uint32_t hwpt_id,
                                        Error **errp);
#define TYPE_HOST_IOMMU_DEVICE_IOMMUFD TYPE_HOST_IOMMU_DEVICE "-iommufd"
+
+typedef union VendorCaps {
+    struct iommu_hw_info_vtd vtd;
+    struct iommu_hw_info_arm_smmuv3 smmuv3;
+} VendorCaps;
+
+/**
+ * struct HostIOMMUDeviceIOMMUFDCaps - Define host IOMMU device capabilities.
+ *
+ * @type: host platform IOMMU type.
+ *
+ * @hw_caps: host platform IOMMU capabilities (e.g. on IOMMUFD this represents
+ *           the @out_capabilities value returned from IOMMU_GET_HW_INFO ioctl)
+ */
+typedef struct HostIOMMUDeviceIOMMUFDCaps {
+    uint32_t type;
+    uint64_t hw_caps;
+    VendorCaps vendor_caps;
+} HostIOMMUDeviceIOMMUFDCaps;
  #endif
diff --git a/hw/vfio/iommufd.c b/hw/vfio/iommufd.c
index 48db105422..530cde6740 100644
--- a/hw/vfio/iommufd.c
+++ b/hw/vfio/iommufd.c
@@ -324,7 +324,7 @@ static bool iommufd_cdev_autodomains_get(VFIODevice 
*vbasedev,
       * vfio_migration_realize() may decide to use VF dirty tracking
       * instead.
       */
-    if (vbasedev->hiod->caps.hw_caps & IOMMU_HW_CAP_DIRTY_TRACKING) {
+    if (vbasedev->caps.hw_caps & IOMMU_HW_CAP_DIRTY_TRACKING) {
          flags = IOMMU_HWPT_ALLOC_DIRTY_TRACKING;
      }
@@ -475,6 +475,7 @@ static bool iommufd_cdev_attach(const char *name, VFIODevice *vbasedev,
      int ret, devfd;
      uint32_t ioas_id;
      Error *err = NULL;
+    HostIOMMUDeviceIOMMUFDCaps *caps = &vbasedev->caps;
      const VFIOIOMMUClass *iommufd_vioc =
          VFIO_IOMMU_CLASS(object_class_by_name(TYPE_VFIO_IOMMU_IOMMUFD));
@@ -505,6 +506,13 @@ static bool iommufd_cdev_attach(const char *name, VFIODevice *vbasedev,
          goto err_alloc_ioas;
      }
+ if (!iommufd_backend_get_device_info(vbasedev->iommufd, vbasedev->devid,
+                                         &caps->type, &caps->vendor_caps,
+                                         sizeof(VendorCaps), &caps->hw_caps,
+                                         errp)) {
+        goto err_alloc_ioas;
+    }
+
      /* try to attach to an existing container in this space */
      QLIST_FOREACH(bcontainer, &space->containers, next) {
          container = container_of(bcontainer, VFIOIOMMUFDContainer, 
bcontainer);


Reply via email to