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>
Tested-by: Xudong Hao <xudong.hao@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 399b36aa75..f020b56208 100644
--- a/hw/vfio/iommufd.c
+++ b/hw/vfio/iommufd.c
@@ -20,6 +20,7 @@
#include "trace.h"
#include "qapi/error.h"
#include "system/iommufd.h"
+#include "hw/core/iommu.h"
#include "hw/core/qdev.h"
#include "hw/vfio/vfio-cpr.h"
#include "system/reset.h"
@@ -305,43 +306,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;
}
@@ -362,7 +368,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 {
@@ -435,7 +442,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;
@@ -488,7 +496,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,
@@ -496,7 +505,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);
}
@@ -922,7 +931,8 @@ host_iommu_device_iommufd_vfio_attach_hwpt(HostIOMMUDeviceIOMMUFD *hiodi,
{
VFIODevice *vbasedev = HOST_IOMMU_DEVICE(hiodi)->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
@@ -931,7 +941,7 @@ host_iommu_device_iommufd_vfio_detach_hwpt(HostIOMMUDeviceIOMMUFD *hiodi,
{
VFIODevice *vbasedev = HOST_IOMMU_DEVICE(hiodi)->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
On 4/3/26 05:55, 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>
> Reviewed-by: Yi Liu <yi.l.liu@intel.com>
> Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
> Tested-by: Xudong Hao <xudong.hao@intel.com>
Reviewed-by: Cédric Le Goater <clg@redhat.com>
Thanks,
C.
> ---
> 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 399b36aa75..f020b56208 100644
> --- a/hw/vfio/iommufd.c
> +++ b/hw/vfio/iommufd.c
> @@ -20,6 +20,7 @@
> #include "trace.h"
> #include "qapi/error.h"
> #include "system/iommufd.h"
> +#include "hw/core/iommu.h"
> #include "hw/core/qdev.h"
> #include "hw/vfio/vfio-cpr.h"
> #include "system/reset.h"
> @@ -305,43 +306,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;
> }
>
> @@ -362,7 +368,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 {
> @@ -435,7 +442,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;
> @@ -488,7 +496,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,
> @@ -496,7 +505,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);
> }
>
> @@ -922,7 +931,8 @@ host_iommu_device_iommufd_vfio_attach_hwpt(HostIOMMUDeviceIOMMUFD *hiodi,
> {
> VFIODevice *vbasedev = HOST_IOMMU_DEVICE(hiodi)->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
> @@ -931,7 +941,7 @@ host_iommu_device_iommufd_vfio_detach_hwpt(HostIOMMUDeviceIOMMUFD *hiodi,
> {
> VFIODevice *vbasedev = HOST_IOMMU_DEVICE(hiodi)->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"
© 2016 - 2026 Red Hat, Inc.