[PATCH v1 01/13] vfio/iommufd: Extend attach/detach_hwpt callback implementations with pasid

Zhenzhong Duan posted 13 patches 1 month ago
Maintainers: Yi Liu <yi.l.liu@intel.com>, Eric Auger <eric.auger@redhat.com>, Zhenzhong Duan <zhenzhong.duan@intel.com>, Peter Maydell <peter.maydell@linaro.org>, "Michael S. Tsirkin" <mst@redhat.com>, Jason Wang <jasowang@redhat.com>, "Clément Mathieu--Drif" <clement.mathieu--drif@eviden.com>, Marcel Apfelbaum <marcel.apfelbaum@gmail.com>, Paolo Bonzini <pbonzini@redhat.com>, Richard Henderson <richard.henderson@linaro.org>, Eduardo Habkost <eduardo@habkost.net>, Alex Williamson <alex@shazbot.org>, "Cédric Le Goater" <clg@redhat.com>
There is a newer version of this series
[PATCH v1 01/13] vfio/iommufd: Extend attach/detach_hwpt callback implementations with pasid
Posted by Zhenzhong Duan 1 month ago
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>
---
 include/hw/core/iommu.h |  2 ++
 hw/vfio/iommufd.c       | 44 +++++++++++++++++++++++++----------------
 hw/vfio/trace-events    |  4 ++--
 3 files changed, 31 insertions(+), 19 deletions(-)

diff --git a/include/hw/core/iommu.h b/include/hw/core/iommu.h
index 86af315c15..bfcd511013 100644
--- a/include/hw/core/iommu.h
+++ b/include/hw/core/iommu.h
@@ -28,4 +28,6 @@ enum host_iommu_quirks {
     HOST_IOMMU_QUIRK_NESTING_PARENT_BYPASS_RO = BIT_ULL(0),
 };
 
+#define IOMMU_NO_PASID 0
+
 #endif /* HW_IOMMU_H */
diff --git a/hw/vfio/iommufd.c b/hw/vfio/iommufd.c
index 131612eb83..b4c5e81b1d 100644
--- a/hw/vfio/iommufd.c
+++ b/hw/vfio/iommufd.c
@@ -21,6 +21,7 @@
 #include "qapi/error.h"
 #include "system/iommufd.h"
 #include "hw/core/qdev.h"
+#include "hw/core/iommu.h"
 #include "hw/vfio/vfio-cpr.h"
 #include "system/reset.h"
 #include "qemu/cutils.h"
@@ -302,43 +303,48 @@ out:
     return ret;
 }
 
-static int iommufd_cdev_attach_ioas_hwpt(VFIODevice *vbasedev, uint32_t id,
-                                         Error **errp)
+static int iommufd_cdev_pasid_attach_ioas_hwpt(VFIODevice *vbasedev,
+                                               uint32_t pasid, uint32_t id,
+                                               Error **errp)
 {
     int iommufd = vbasedev->iommufd->fd;
     struct vfio_device_attach_iommufd_pt attach_data = {
         .argsz = sizeof(attach_data),
-        .flags = 0,
+        .flags = pasid == IOMMU_NO_PASID ? 0 : VFIO_DEVICE_ATTACH_PASID,
+        .pasid = pasid,
         .pt_id = id,
     };
 
     /* Attach device to an IOAS or hwpt within iommufd */
     if (ioctl(vbasedev->fd, VFIO_DEVICE_ATTACH_IOMMUFD_PT, &attach_data)) {
         error_setg_errno(errp, errno,
-                         "[iommufd=%d] error attach %s (%d) to id=%d",
-                         iommufd, vbasedev->name, vbasedev->fd, id);
+                         "[iommufd=%d] error attach %s (%d) pasid %d to id=%d",
+                         iommufd, vbasedev->name, vbasedev->fd, pasid, id);
         return -errno;
     }
 
-    trace_iommufd_cdev_attach_ioas_hwpt(iommufd, vbasedev->name,
-                                        vbasedev->fd, id);
+    trace_iommufd_cdev_pasid_attach_ioas_hwpt(iommufd, vbasedev->name,
+                                              vbasedev->fd, pasid, id);
     return 0;
 }
 
-static bool iommufd_cdev_detach_ioas_hwpt(VFIODevice *vbasedev, Error **errp)
+static bool iommufd_cdev_pasid_detach_ioas_hwpt(VFIODevice *vbasedev,
+                                                uint32_t pasid, Error **errp)
 {
     int iommufd = vbasedev->iommufd->fd;
     struct vfio_device_detach_iommufd_pt detach_data = {
         .argsz = sizeof(detach_data),
-        .flags = 0,
+        .flags = pasid == IOMMU_NO_PASID ? 0 : VFIO_DEVICE_DETACH_PASID,
+        .pasid = pasid,
     };
 
     if (ioctl(vbasedev->fd, VFIO_DEVICE_DETACH_IOMMUFD_PT, &detach_data)) {
-        error_setg_errno(errp, errno, "detach %s failed", vbasedev->name);
+        error_setg_errno(errp, errno, "detach %s pasid %d failed",
+                         vbasedev->name, pasid);
         return false;
     }
 
-    trace_iommufd_cdev_detach_ioas_hwpt(iommufd, vbasedev->name);
+    trace_iommufd_cdev_pasid_detach_ioas_hwpt(iommufd, vbasedev->name, pasid);
     return true;
 }
 
@@ -359,7 +365,8 @@ static bool iommufd_cdev_autodomains_get(VFIODevice *vbasedev,
     /* Try to find a domain */
     QLIST_FOREACH(hwpt, &container->hwpt_list, next) {
         if (!cpr_is_incoming()) {
-            ret = iommufd_cdev_attach_ioas_hwpt(vbasedev, hwpt->hwpt_id, errp);
+            ret = iommufd_cdev_pasid_attach_ioas_hwpt(vbasedev, IOMMU_NO_PASID,
+                                                      hwpt->hwpt_id, errp);
         } else if (vbasedev->cpr.hwpt_id == hwpt->hwpt_id) {
             ret = 0;
         } else {
@@ -432,7 +439,8 @@ static bool iommufd_cdev_autodomains_get(VFIODevice *vbasedev,
         return false;
     }
 
-    ret = iommufd_cdev_attach_ioas_hwpt(vbasedev, hwpt_id, errp);
+    ret = iommufd_cdev_pasid_attach_ioas_hwpt(vbasedev, IOMMU_NO_PASID, hwpt_id,
+                                              errp);
     if (ret) {
         iommufd_backend_free_id(container->be, hwpt_id);
         return false;
@@ -485,7 +493,8 @@ static bool iommufd_cdev_attach_container(VFIODevice *vbasedev,
 
     /* If CPR, we are already attached to ioas_id. */
     return cpr_is_incoming() ||
-           !iommufd_cdev_attach_ioas_hwpt(vbasedev, container->ioas_id, errp);
+           !iommufd_cdev_pasid_attach_ioas_hwpt(vbasedev, IOMMU_NO_PASID,
+                                                container->ioas_id, errp);
 }
 
 static void iommufd_cdev_detach_container(VFIODevice *vbasedev,
@@ -493,7 +502,7 @@ static void iommufd_cdev_detach_container(VFIODevice *vbasedev,
 {
     Error *err = NULL;
 
-    if (!iommufd_cdev_detach_ioas_hwpt(vbasedev, &err)) {
+    if (!iommufd_cdev_pasid_detach_ioas_hwpt(vbasedev, IOMMU_NO_PASID, &err)) {
         error_report_err(err);
     }
 
@@ -919,7 +928,8 @@ host_iommu_device_iommufd_vfio_attach_hwpt(HostIOMMUDeviceIOMMUFD *idev,
 {
     VFIODevice *vbasedev = HOST_IOMMU_DEVICE(idev)->agent;
 
-    return !iommufd_cdev_attach_ioas_hwpt(vbasedev, hwpt_id, errp);
+    return !iommufd_cdev_pasid_attach_ioas_hwpt(vbasedev, IOMMU_NO_PASID,
+                                                hwpt_id, errp);
 }
 
 static bool
@@ -928,7 +938,7 @@ host_iommu_device_iommufd_vfio_detach_hwpt(HostIOMMUDeviceIOMMUFD *idev,
 {
     VFIODevice *vbasedev = HOST_IOMMU_DEVICE(idev)->agent;
 
-    return iommufd_cdev_detach_ioas_hwpt(vbasedev, errp);
+    return iommufd_cdev_pasid_detach_ioas_hwpt(vbasedev, IOMMU_NO_PASID, errp);
 }
 
 static bool hiod_iommufd_vfio_realize(HostIOMMUDevice *hiod, void *opaque,
diff --git a/hw/vfio/trace-events b/hw/vfio/trace-events
index 846e3625c5..764a3e4855 100644
--- a/hw/vfio/trace-events
+++ b/hw/vfio/trace-events
@@ -182,8 +182,8 @@ vfio_vmstate_change_prepare(const char *name, int running, const char *reason, c
 
 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"
 iommufd_cdev_getfd(const char *dev, int devfd) " %s (fd=%d)"
-iommufd_cdev_attach_ioas_hwpt(int iommufd, const char *name, int devfd, int id) " [iommufd=%d] Successfully attached device %s (%d) to id=%d"
-iommufd_cdev_detach_ioas_hwpt(int iommufd, const char *name) " [iommufd=%d] Successfully detached %s"
+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 %d to id=%d"
+iommufd_cdev_pasid_detach_ioas_hwpt(int iommufd, const char *name, uint32_t pasid) " [iommufd=%d] Successfully detached %s pasid %d"
 iommufd_cdev_fail_attach_existing_container(const char *msg) " %s"
 iommufd_cdev_alloc_ioas(int iommufd, int ioas_id) " [iommufd=%d] new IOMMUFD container with ioasid=%d"
 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"
-- 
2.47.3
Re: [PATCH v1 01/13] vfio/iommufd: Extend attach/detach_hwpt callback implementations with pasid
Posted by Yi Liu 3 weeks, 3 days ago
On 3/6/26 11:43, Zhenzhong Duan wrote:
> 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>
> ---
>   include/hw/core/iommu.h |  2 ++
>   hw/vfio/iommufd.c       | 44 +++++++++++++++++++++++++----------------
>   hw/vfio/trace-events    |  4 ++--
>   3 files changed, 31 insertions(+), 19 deletions(-)
> 
> diff --git a/include/hw/core/iommu.h b/include/hw/core/iommu.h
> index 86af315c15..bfcd511013 100644
> --- a/include/hw/core/iommu.h
> +++ b/include/hw/core/iommu.h
> @@ -28,4 +28,6 @@ enum host_iommu_quirks {
>       HOST_IOMMU_QUIRK_NESTING_PARENT_BYPASS_RO = BIT_ULL(0),
>   };
>   
> +#define IOMMU_NO_PASID 0
> +
>   #endif /* HW_IOMMU_H */
> diff --git a/hw/vfio/iommufd.c b/hw/vfio/iommufd.c
> index 131612eb83..b4c5e81b1d 100644
> --- a/hw/vfio/iommufd.c
> +++ b/hw/vfio/iommufd.c
> @@ -21,6 +21,7 @@
>   #include "qapi/error.h"
>   #include "system/iommufd.h"
>   #include "hw/core/qdev.h"
> +#include "hw/core/iommu.h"

nit: move this line before qdev.h. Other parts LGTM.

Reviewed-by: Yi Liu <yi.l.liu@intel.com>

>   #include "hw/vfio/vfio-cpr.h"
>   #include "system/reset.h"
>   #include "qemu/cutils.h"
> @@ -302,43 +303,48 @@ out:
>       return ret;
>   }
>   
> -static int iommufd_cdev_attach_ioas_hwpt(VFIODevice *vbasedev, uint32_t id,
> -                                         Error **errp)
> +static int iommufd_cdev_pasid_attach_ioas_hwpt(VFIODevice *vbasedev,
> +                                               uint32_t pasid, uint32_t id,
> +                                               Error **errp)
>   {
>       int iommufd = vbasedev->iommufd->fd;
>       struct vfio_device_attach_iommufd_pt attach_data = {
>           .argsz = sizeof(attach_data),
> -        .flags = 0,
> +        .flags = pasid == IOMMU_NO_PASID ? 0 : VFIO_DEVICE_ATTACH_PASID,
> +        .pasid = pasid,
>           .pt_id = id,
>       };
>   
>       /* Attach device to an IOAS or hwpt within iommufd */
>       if (ioctl(vbasedev->fd, VFIO_DEVICE_ATTACH_IOMMUFD_PT, &attach_data)) {
>           error_setg_errno(errp, errno,
> -                         "[iommufd=%d] error attach %s (%d) to id=%d",
> -                         iommufd, vbasedev->name, vbasedev->fd, id);
> +                         "[iommufd=%d] error attach %s (%d) pasid %d to id=%d",
> +                         iommufd, vbasedev->name, vbasedev->fd, pasid, id);
>           return -errno;
>       }
>   
> -    trace_iommufd_cdev_attach_ioas_hwpt(iommufd, vbasedev->name,
> -                                        vbasedev->fd, id);
> +    trace_iommufd_cdev_pasid_attach_ioas_hwpt(iommufd, vbasedev->name,
> +                                              vbasedev->fd, pasid, id);
>       return 0;
>   }
>   
> -static bool iommufd_cdev_detach_ioas_hwpt(VFIODevice *vbasedev, Error **errp)
> +static bool iommufd_cdev_pasid_detach_ioas_hwpt(VFIODevice *vbasedev,
> +                                                uint32_t pasid, Error **errp)
>   {
>       int iommufd = vbasedev->iommufd->fd;
>       struct vfio_device_detach_iommufd_pt detach_data = {
>           .argsz = sizeof(detach_data),
> -        .flags = 0,
> +        .flags = pasid == IOMMU_NO_PASID ? 0 : VFIO_DEVICE_DETACH_PASID,
> +        .pasid = pasid,
>       };
>   
>       if (ioctl(vbasedev->fd, VFIO_DEVICE_DETACH_IOMMUFD_PT, &detach_data)) {
> -        error_setg_errno(errp, errno, "detach %s failed", vbasedev->name);
> +        error_setg_errno(errp, errno, "detach %s pasid %d failed",
> +                         vbasedev->name, pasid);
>           return false;
>       }
>   
> -    trace_iommufd_cdev_detach_ioas_hwpt(iommufd, vbasedev->name);
> +    trace_iommufd_cdev_pasid_detach_ioas_hwpt(iommufd, vbasedev->name, pasid);
>       return true;
>   }
>   
> @@ -359,7 +365,8 @@ static bool iommufd_cdev_autodomains_get(VFIODevice *vbasedev,
>       /* Try to find a domain */
>       QLIST_FOREACH(hwpt, &container->hwpt_list, next) {
>           if (!cpr_is_incoming()) {
> -            ret = iommufd_cdev_attach_ioas_hwpt(vbasedev, hwpt->hwpt_id, errp);
> +            ret = iommufd_cdev_pasid_attach_ioas_hwpt(vbasedev, IOMMU_NO_PASID,
> +                                                      hwpt->hwpt_id, errp);
>           } else if (vbasedev->cpr.hwpt_id == hwpt->hwpt_id) {
>               ret = 0;
>           } else {
> @@ -432,7 +439,8 @@ static bool iommufd_cdev_autodomains_get(VFIODevice *vbasedev,
>           return false;
>       }
>   
> -    ret = iommufd_cdev_attach_ioas_hwpt(vbasedev, hwpt_id, errp);
> +    ret = iommufd_cdev_pasid_attach_ioas_hwpt(vbasedev, IOMMU_NO_PASID, hwpt_id,
> +                                              errp);
>       if (ret) {
>           iommufd_backend_free_id(container->be, hwpt_id);
>           return false;
> @@ -485,7 +493,8 @@ static bool iommufd_cdev_attach_container(VFIODevice *vbasedev,
>   
>       /* If CPR, we are already attached to ioas_id. */
>       return cpr_is_incoming() ||
> -           !iommufd_cdev_attach_ioas_hwpt(vbasedev, container->ioas_id, errp);
> +           !iommufd_cdev_pasid_attach_ioas_hwpt(vbasedev, IOMMU_NO_PASID,
> +                                                container->ioas_id, errp);
>   }
>   
>   static void iommufd_cdev_detach_container(VFIODevice *vbasedev,
> @@ -493,7 +502,7 @@ static void iommufd_cdev_detach_container(VFIODevice *vbasedev,
>   {
>       Error *err = NULL;
>   
> -    if (!iommufd_cdev_detach_ioas_hwpt(vbasedev, &err)) {
> +    if (!iommufd_cdev_pasid_detach_ioas_hwpt(vbasedev, IOMMU_NO_PASID, &err)) {
>           error_report_err(err);
>       }
>   
> @@ -919,7 +928,8 @@ host_iommu_device_iommufd_vfio_attach_hwpt(HostIOMMUDeviceIOMMUFD *idev,
>   {
>       VFIODevice *vbasedev = HOST_IOMMU_DEVICE(idev)->agent;
>   
> -    return !iommufd_cdev_attach_ioas_hwpt(vbasedev, hwpt_id, errp);
> +    return !iommufd_cdev_pasid_attach_ioas_hwpt(vbasedev, IOMMU_NO_PASID,
> +                                                hwpt_id, errp);
>   }
>   
>   static bool
> @@ -928,7 +938,7 @@ host_iommu_device_iommufd_vfio_detach_hwpt(HostIOMMUDeviceIOMMUFD *idev,
>   {
>       VFIODevice *vbasedev = HOST_IOMMU_DEVICE(idev)->agent;
>   
> -    return iommufd_cdev_detach_ioas_hwpt(vbasedev, errp);
> +    return iommufd_cdev_pasid_detach_ioas_hwpt(vbasedev, IOMMU_NO_PASID, errp);
>   }
>   
>   static bool hiod_iommufd_vfio_realize(HostIOMMUDevice *hiod, void *opaque,
> diff --git a/hw/vfio/trace-events b/hw/vfio/trace-events
> index 846e3625c5..764a3e4855 100644
> --- a/hw/vfio/trace-events
> +++ b/hw/vfio/trace-events
> @@ -182,8 +182,8 @@ vfio_vmstate_change_prepare(const char *name, int running, const char *reason, c
>   
>   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"
>   iommufd_cdev_getfd(const char *dev, int devfd) " %s (fd=%d)"
> -iommufd_cdev_attach_ioas_hwpt(int iommufd, const char *name, int devfd, int id) " [iommufd=%d] Successfully attached device %s (%d) to id=%d"
> -iommufd_cdev_detach_ioas_hwpt(int iommufd, const char *name) " [iommufd=%d] Successfully detached %s"
> +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 %d to id=%d"
> +iommufd_cdev_pasid_detach_ioas_hwpt(int iommufd, const char *name, uint32_t pasid) " [iommufd=%d] Successfully detached %s pasid %d"
>   iommufd_cdev_fail_attach_existing_container(const char *msg) " %s"
>   iommufd_cdev_alloc_ioas(int iommufd, int ioas_id) " [iommufd=%d] new IOMMUFD container with ioasid=%d"
>   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"
RE: [PATCH v1 01/13] vfio/iommufd: Extend attach/detach_hwpt callback implementations with pasid
Posted by Duan, Zhenzhong 3 weeks, 2 days ago

>-----Original Message-----
>From: Liu, Yi L <yi.l.liu@intel.com>
>Subject: Re: [PATCH v1 01/13] vfio/iommufd: Extend attach/detach_hwpt callback
>implementations with pasid
>
>On 3/6/26 11:43, Zhenzhong Duan wrote:
>> 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>
>> ---
>>   include/hw/core/iommu.h |  2 ++
>>   hw/vfio/iommufd.c       | 44 +++++++++++++++++++++++++----------------
>>   hw/vfio/trace-events    |  4 ++--
>>   3 files changed, 31 insertions(+), 19 deletions(-)
>>
>> diff --git a/include/hw/core/iommu.h b/include/hw/core/iommu.h
>> index 86af315c15..bfcd511013 100644
>> --- a/include/hw/core/iommu.h
>> +++ b/include/hw/core/iommu.h
>> @@ -28,4 +28,6 @@ enum host_iommu_quirks {
>>       HOST_IOMMU_QUIRK_NESTING_PARENT_BYPASS_RO = BIT_ULL(0),
>>   };
>>
>> +#define IOMMU_NO_PASID 0
>> +
>>   #endif /* HW_IOMMU_H */
>> diff --git a/hw/vfio/iommufd.c b/hw/vfio/iommufd.c
>> index 131612eb83..b4c5e81b1d 100644
>> --- a/hw/vfio/iommufd.c
>> +++ b/hw/vfio/iommufd.c
>> @@ -21,6 +21,7 @@
>>   #include "qapi/error.h"
>>   #include "system/iommufd.h"
>>   #include "hw/core/qdev.h"
>> +#include "hw/core/iommu.h"
>
>nit: move this line before qdev.h. Other parts LGTM.

Will do.

Thanks
Zhenzhong

>
>Reviewed-by: Yi Liu <yi.l.liu@intel.com>
>
>>   #include "hw/vfio/vfio-cpr.h"
>>   #include "system/reset.h"
>>   #include "qemu/cutils.h"
>> @@ -302,43 +303,48 @@ out:
>>       return ret;
>>   }
>>
>> -static int iommufd_cdev_attach_ioas_hwpt(VFIODevice *vbasedev, uint32_t id,
>> -                                         Error **errp)
>> +static int iommufd_cdev_pasid_attach_ioas_hwpt(VFIODevice *vbasedev,
>> +                                               uint32_t pasid, uint32_t id,
>> +                                               Error **errp)
>>   {
>>       int iommufd = vbasedev->iommufd->fd;
>>       struct vfio_device_attach_iommufd_pt attach_data = {
>>           .argsz = sizeof(attach_data),
>> -        .flags = 0,
>> +        .flags = pasid == IOMMU_NO_PASID ? 0 : VFIO_DEVICE_ATTACH_PASID,
>> +        .pasid = pasid,
>>           .pt_id = id,
>>       };
>>
>>       /* Attach device to an IOAS or hwpt within iommufd */
>>       if (ioctl(vbasedev->fd, VFIO_DEVICE_ATTACH_IOMMUFD_PT, &attach_data))
>{
>>           error_setg_errno(errp, errno,
>> -                         "[iommufd=%d] error attach %s (%d) to id=%d",
>> -                         iommufd, vbasedev->name, vbasedev->fd, id);
>> +                         "[iommufd=%d] error attach %s (%d) pasid %d to id=%d",
>> +                         iommufd, vbasedev->name, vbasedev->fd, pasid, id);
>>           return -errno;
>>       }
>>
>> -    trace_iommufd_cdev_attach_ioas_hwpt(iommufd, vbasedev->name,
>> -                                        vbasedev->fd, id);
>> +    trace_iommufd_cdev_pasid_attach_ioas_hwpt(iommufd, vbasedev->name,
>> +                                              vbasedev->fd, pasid, id);
>>       return 0;
>>   }
>>
>> -static bool iommufd_cdev_detach_ioas_hwpt(VFIODevice *vbasedev, Error
>**errp)
>> +static bool iommufd_cdev_pasid_detach_ioas_hwpt(VFIODevice *vbasedev,
>> +                                                uint32_t pasid, Error **errp)
>>   {
>>       int iommufd = vbasedev->iommufd->fd;
>>       struct vfio_device_detach_iommufd_pt detach_data = {
>>           .argsz = sizeof(detach_data),
>> -        .flags = 0,
>> +        .flags = pasid == IOMMU_NO_PASID ? 0 : VFIO_DEVICE_DETACH_PASID,
>> +        .pasid = pasid,
>>       };
>>
>>       if (ioctl(vbasedev->fd, VFIO_DEVICE_DETACH_IOMMUFD_PT, &detach_data))
>{
>> -        error_setg_errno(errp, errno, "detach %s failed", vbasedev->name);
>> +        error_setg_errno(errp, errno, "detach %s pasid %d failed",
>> +                         vbasedev->name, pasid);
>>           return false;
>>       }
>>
>> -    trace_iommufd_cdev_detach_ioas_hwpt(iommufd, vbasedev->name);
>> +    trace_iommufd_cdev_pasid_detach_ioas_hwpt(iommufd, vbasedev->name,
>pasid);
>>       return true;
>>   }
>>
>> @@ -359,7 +365,8 @@ static bool
>iommufd_cdev_autodomains_get(VFIODevice *vbasedev,
>>       /* Try to find a domain */
>>       QLIST_FOREACH(hwpt, &container->hwpt_list, next) {
>>           if (!cpr_is_incoming()) {
>> -            ret = iommufd_cdev_attach_ioas_hwpt(vbasedev, hwpt->hwpt_id, errp);
>> +            ret = iommufd_cdev_pasid_attach_ioas_hwpt(vbasedev,
>IOMMU_NO_PASID,
>> +                                                      hwpt->hwpt_id, errp);
>>           } else if (vbasedev->cpr.hwpt_id == hwpt->hwpt_id) {
>>               ret = 0;
>>           } else {
>> @@ -432,7 +439,8 @@ static bool
>iommufd_cdev_autodomains_get(VFIODevice *vbasedev,
>>           return false;
>>       }
>>
>> -    ret = iommufd_cdev_attach_ioas_hwpt(vbasedev, hwpt_id, errp);
>> +    ret = iommufd_cdev_pasid_attach_ioas_hwpt(vbasedev, IOMMU_NO_PASID,
>hwpt_id,
>> +                                              errp);
>>       if (ret) {
>>           iommufd_backend_free_id(container->be, hwpt_id);
>>           return false;
>> @@ -485,7 +493,8 @@ static bool iommufd_cdev_attach_container(VFIODevice
>*vbasedev,
>>
>>       /* If CPR, we are already attached to ioas_id. */
>>       return cpr_is_incoming() ||
>> -           !iommufd_cdev_attach_ioas_hwpt(vbasedev, container->ioas_id, errp);
>> +           !iommufd_cdev_pasid_attach_ioas_hwpt(vbasedev, IOMMU_NO_PASID,
>> +                                                container->ioas_id, errp);
>>   }
>>
>>   static void iommufd_cdev_detach_container(VFIODevice *vbasedev,
>> @@ -493,7 +502,7 @@ static void
>iommufd_cdev_detach_container(VFIODevice *vbasedev,
>>   {
>>       Error *err = NULL;
>>
>> -    if (!iommufd_cdev_detach_ioas_hwpt(vbasedev, &err)) {
>> +    if (!iommufd_cdev_pasid_detach_ioas_hwpt(vbasedev, IOMMU_NO_PASID,
>&err)) {
>>           error_report_err(err);
>>       }
>>
>> @@ -919,7 +928,8 @@
>host_iommu_device_iommufd_vfio_attach_hwpt(HostIOMMUDeviceIOMMUFD
>*idev,
>>   {
>>       VFIODevice *vbasedev = HOST_IOMMU_DEVICE(idev)->agent;
>>
>> -    return !iommufd_cdev_attach_ioas_hwpt(vbasedev, hwpt_id, errp);
>> +    return !iommufd_cdev_pasid_attach_ioas_hwpt(vbasedev,
>IOMMU_NO_PASID,
>> +                                                hwpt_id, errp);
>>   }
>>
>>   static bool
>> @@ -928,7 +938,7 @@
>host_iommu_device_iommufd_vfio_detach_hwpt(HostIOMMUDeviceIOMMUFD
>*idev,
>>   {
>>       VFIODevice *vbasedev = HOST_IOMMU_DEVICE(idev)->agent;
>>
>> -    return iommufd_cdev_detach_ioas_hwpt(vbasedev, errp);
>> +    return iommufd_cdev_pasid_detach_ioas_hwpt(vbasedev,
>IOMMU_NO_PASID, errp);
>>   }
>>
>>   static bool hiod_iommufd_vfio_realize(HostIOMMUDevice *hiod, void *opaque,
>> diff --git a/hw/vfio/trace-events b/hw/vfio/trace-events
>> index 846e3625c5..764a3e4855 100644
>> --- a/hw/vfio/trace-events
>> +++ b/hw/vfio/trace-events
>> @@ -182,8 +182,8 @@ vfio_vmstate_change_prepare(const char *name, int
>running, const char *reason, c
>>
>>   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"
>>   iommufd_cdev_getfd(const char *dev, int devfd) " %s (fd=%d)"
>> -iommufd_cdev_attach_ioas_hwpt(int iommufd, const char *name, int devfd, int
>id) " [iommufd=%d] Successfully attached device %s (%d) to id=%d"
>> -iommufd_cdev_detach_ioas_hwpt(int iommufd, const char *name) "
>[iommufd=%d] Successfully detached %s"
>> +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 %d to id=%d"
>> +iommufd_cdev_pasid_detach_ioas_hwpt(int iommufd, const char *name,
>uint32_t pasid) " [iommufd=%d] Successfully detached %s pasid %d"
>>   iommufd_cdev_fail_attach_existing_container(const char *msg) " %s"
>>   iommufd_cdev_alloc_ioas(int iommufd, int ioas_id) " [iommufd=%d] new
>IOMMUFD container with ioasid=%d"
>>   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"