@samitouri / QOSamiQemu / commits / 1179c4dfc0

vfio/iommufd: Extend attach/detach_hwpt callback implementations with pasid

For attachment with pasid, pasid together with flag VFIO_DEVICE_ATTACH_PASID should be passed in. Define IOMMU_NO_PASID to represent device attachment without pasid same as in kernel. The implementation is similar for detachment. Suggested-by: Shameer Kolothum Thodi <skolothumtho@nvidia.com> Suggested-by: Nicolin Chen <nicolinc@nvidia.com> Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com> Reviewed-by: Yi Liu <yi.l.liu@intel.com> Reviewed-by: Nicolin Chen <nicolinc@nvidia.com> Reviewed-by: Cédric Le Goater <clg@redhat.com> Reviewed-by: Shameer Kolothum <skolothumtho@nvidia.com> Tested-by: Xudong Hao <xudong.hao@intel.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com> Message-Id: <20260527054658.1021096-2-zhenzhong.duan@intel.com>

Zhenzhong Duan committed May 27, 2026 at 01:46 UTC 1179c4dfc04915b13fe5c9158a07dce3470c8b3c
3 files changed +32 -19
hw/vfio/iommufd.c
+27 -17
@@ -20,6 +20,7 @@
20 #include "trace.h"
21 #include "qapi/error.h"
22 #include "system/iommufd.h"
23 +#include "hw/core/iommu.h"
24 #include "hw/core/qdev.h"
25 #include "hw/vfio/vfio-cpr.h"
26 #include "system/reset.h"
@@ -305,43 +306,48 @@ out:
306 return ret;
307 }
308
308 -static int iommufd_cdev_attach_ioas_hwpt(VFIODevice *vbasedev, uint32_t id,
309 - Error **errp)
309 +static int iommufd_cdev_pasid_attach_ioas_hwpt(VFIODevice *vbasedev,
310 + uint32_t pasid, uint32_t id,
311 + Error **errp)
312 {
313 int iommufd = vbasedev->iommufd->fd;
314 struct vfio_device_attach_iommufd_pt attach_data = {
315 .argsz = sizeof(attach_data),
314 - .flags = 0,
316 + .flags = pasid == IOMMU_NO_PASID ? 0 : VFIO_DEVICE_ATTACH_PASID,
317 + .pasid = pasid,
318 .pt_id = id,
319 };
320
321 /* Attach device to an IOAS or hwpt within iommufd */
322 if (ioctl(vbasedev->fd, VFIO_DEVICE_ATTACH_IOMMUFD_PT, &attach_data)) {
323 error_setg_errno(errp, errno,
321 - "[iommufd=%d] error attach %s (%d) to id=%d",
322 - iommufd, vbasedev->name, vbasedev->fd, id);
324 + "[iommufd=%d] error attach %s (%d) pasid %d to id=%d",
325 + iommufd, vbasedev->name, vbasedev->fd, pasid, id);
326 return -errno;
327 }
328
326 - trace_iommufd_cdev_attach_ioas_hwpt(iommufd, vbasedev->name,
327 - vbasedev->fd, id);
329 + trace_iommufd_cdev_pasid_attach_ioas_hwpt(iommufd, vbasedev->name,
330 + vbasedev->fd, pasid, id);
331 return 0;
332 }
333
331 -static bool iommufd_cdev_detach_ioas_hwpt(VFIODevice *vbasedev, Error **errp)
334 +static bool iommufd_cdev_pasid_detach_ioas_hwpt(VFIODevice *vbasedev,
335 + uint32_t pasid, Error **errp)
336 {
337 int iommufd = vbasedev->iommufd->fd;
338 struct vfio_device_detach_iommufd_pt detach_data = {
339 .argsz = sizeof(detach_data),
336 - .flags = 0,
340 + .flags = pasid == IOMMU_NO_PASID ? 0 : VFIO_DEVICE_DETACH_PASID,
341 + .pasid = pasid,
342 };
343
344 if (ioctl(vbasedev->fd, VFIO_DEVICE_DETACH_IOMMUFD_PT, &detach_data)) {
340 - error_setg_errno(errp, errno, "detach %s failed", vbasedev->name);
345 + error_setg_errno(errp, errno, "detach %s pasid %d failed",
346 + vbasedev->name, pasid);
347 return false;
348 }
349
344 - trace_iommufd_cdev_detach_ioas_hwpt(iommufd, vbasedev->name);
350 + trace_iommufd_cdev_pasid_detach_ioas_hwpt(iommufd, vbasedev->name, pasid);
351 return true;
352 }
353
@@ -363,7 +369,8 @@ static bool iommufd_cdev_autodomains_get(VFIODevice *vbasedev,
369 /* Try to find a domain */
370 QLIST_FOREACH(hwpt, &container->hwpt_list, next) {
371 if (!cpr_is_incoming()) {
366 - ret = iommufd_cdev_attach_ioas_hwpt(vbasedev, hwpt->hwpt_id, errp);
372 + ret = iommufd_cdev_pasid_attach_ioas_hwpt(vbasedev, IOMMU_NO_PASID,
373 + hwpt->hwpt_id, errp);
374 } else if (vbasedev->cpr.hwpt_id == hwpt->hwpt_id) {
375 ret = 0;
376 } else {
@@ -442,7 +449,8 @@ static bool iommufd_cdev_autodomains_get(VFIODevice *vbasedev,
449 return false;
450 }
451
445 - ret = iommufd_cdev_attach_ioas_hwpt(vbasedev, hwpt_id, errp);
452 + ret = iommufd_cdev_pasid_attach_ioas_hwpt(vbasedev, IOMMU_NO_PASID, hwpt_id,
453 + errp);
454 if (ret) {
455 iommufd_backend_free_id(container->be, hwpt_id);
456 return false;
@@ -495,7 +503,8 @@ static bool iommufd_cdev_attach_container(VFIODevice *vbasedev,
503
504 /* If CPR, we are already attached to ioas_id. */
505 return cpr_is_incoming() ||
498 - !iommufd_cdev_attach_ioas_hwpt(vbasedev, container->ioas_id, errp);
506 + !iommufd_cdev_pasid_attach_ioas_hwpt(vbasedev, IOMMU_NO_PASID,
507 + container->ioas_id, errp);
508 }
509
510 static void iommufd_cdev_detach_container(VFIODevice *vbasedev,
@@ -503,7 +512,7 @@ static void iommufd_cdev_detach_container(VFIODevice *vbasedev,
512 {
513 Error *err = NULL;
514
506 - if (!iommufd_cdev_detach_ioas_hwpt(vbasedev, &err)) {
515 + if (!iommufd_cdev_pasid_detach_ioas_hwpt(vbasedev, IOMMU_NO_PASID, &err)) {
516 error_report_err(err);
517 }
518
@@ -929,7 +938,8 @@ host_iommu_device_iommufd_vfio_attach_hwpt(HostIOMMUDeviceIOMMUFD *hiodi,
938 {
939 VFIODevice *vbasedev = HOST_IOMMU_DEVICE(hiodi)->agent;
940
932 - return !iommufd_cdev_attach_ioas_hwpt(vbasedev, hwpt_id, errp);
941 + return !iommufd_cdev_pasid_attach_ioas_hwpt(vbasedev, IOMMU_NO_PASID,
942 + hwpt_id, errp);
943 }
944
945 static bool
@@ -938,7 +948,7 @@ host_iommu_device_iommufd_vfio_detach_hwpt(HostIOMMUDeviceIOMMUFD *hiodi,
948 {
949 VFIODevice *vbasedev = HOST_IOMMU_DEVICE(hiodi)->agent;
950
941 - return iommufd_cdev_detach_ioas_hwpt(vbasedev, errp);
951 + return iommufd_cdev_pasid_detach_ioas_hwpt(vbasedev, IOMMU_NO_PASID, errp);
952 }
953
954 static bool hiod_iommufd_vfio_realize(HostIOMMUDevice *hiod, void *opaque,
hw/vfio/trace-events
+2 -2
@@ -183,8 +183,8 @@ vfio_vmstate_change_prepare(const char *name, int running, const char *reason, c
183
184 iommufd_cdev_connect_and_bind(int iommufd, const char *name, int devfd, int devid) " [iommufd=%d] Successfully bound device %s (fd=%d): output devid=%d"
185 iommufd_cdev_getfd(const char *dev, int devfd) " %s (fd=%d)"
186 -iommufd_cdev_attach_ioas_hwpt(int iommufd, const char *name, int devfd, int id) " [iommufd=%d] Successfully attached device %s (%d) to id=%d"
187 -iommufd_cdev_detach_ioas_hwpt(int iommufd, const char *name) " [iommufd=%d] Successfully detached %s"
186 +iommufd_cdev_pasid_attach_ioas_hwpt(int iommufd, const char *name, int devfd, uint32_t pasid, int id) " [iommufd=%d] Successfully attached device %s (%d) pasid %u to id=%d"
187 +iommufd_cdev_pasid_detach_ioas_hwpt(int iommufd, const char *name, uint32_t pasid) " [iommufd=%d] Successfully detached %s pasid %u"
188 iommufd_cdev_fail_attach_existing_container(const char *msg) " %s"
189 iommufd_cdev_alloc_ioas(int iommufd, int ioas_id) " [iommufd=%d] new IOMMUFD container with ioasid=%d"
190 iommufd_cdev_device_info(char *name, int devfd, int num_irqs, int num_regions, int flags) " %s (%d) num_irqs=%d num_regions=%d flags=%d"
include/hw/core/iommu.h
+3
@@ -30,4 +30,7 @@ enum host_iommu_quirks {
30 HOST_IOMMU_QUIRK_NESTING_PARENT_BYPASS_RO = BIT_ULL(0),
31 };
32
33 +/* ABI constant: IOMMU_NO_PASID must always be 0 (keep in sync with kernel) */
34 +#define IOMMU_NO_PASID 0
35 +
36 #endif /* HW_IOMMU_H */