From: Zhenzhong Duan <[email protected]> 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 <[email protected]> Suggested-by: Nicolin Chen <[email protected]> Signed-off-by: Zhenzhong Duan <[email protected]> Reviewed-by: Yi Liu <[email protected]> Reviewed-by: Nicolin Chen <[email protected]> Reviewed-by: Cédric Le Goater <[email protected]> Reviewed-by: Shameer Kolothum <[email protected]> Tested-by: Xudong Hao <[email protected]> Reviewed-by: Michael S. Tsirkin <[email protected]> Signed-off-by: Michael S. Tsirkin <[email protected]> Message-Id: <[email protected]> --- hw/vfio/iommufd.c | 44 +++++++++++++++++++++++++---------------- hw/vfio/trace-events | 4 ++-- include/hw/core/iommu.h | 3 +++ 3 files changed, 32 insertions(+), 19 deletions(-) diff --git a/hw/vfio/iommufd.c b/hw/vfio/iommufd.c index df148a49a7..f86f6f0d7b 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; } @@ -363,7 +369,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 { @@ -442,7 +449,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; @@ -495,7 +503,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, @@ -503,7 +512,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); } @@ -929,7 +938,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 @@ -938,7 +948,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 2049159015..8dbb477298 100644 --- a/hw/vfio/trace-events +++ b/hw/vfio/trace-events @@ -183,8 +183,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 %u to id=%d" +iommufd_cdev_pasid_detach_ioas_hwpt(int iommufd, const char *name, uint32_t pasid) " [iommufd=%d] Successfully detached %s pasid %u" 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" diff --git a/include/hw/core/iommu.h b/include/hw/core/iommu.h index cd59a367ce..7fb5c81c9f 100644 --- a/include/hw/core/iommu.h +++ b/include/hw/core/iommu.h @@ -30,4 +30,7 @@ enum host_iommu_quirks { HOST_IOMMU_QUIRK_NESTING_PARENT_BYPASS_RO = BIT_ULL(0), }; +/* ABI constant: IOMMU_NO_PASID must always be 0 (keep in sync with kernel) */ +#define IOMMU_NO_PASID 0 + #endif /* HW_IOMMU_H */ -- MST
