On 5/30/25 11:35 AM, Zhenzhong Duan wrote:
> Enhance HostIOMMUDeviceIOMMUFD object with 3 new members, specific
> to the iommufd BE + 2 new class functions.
>
> IOMMUFD BE includes IOMMUFD handle, devid and hwpt_id. IOMMUFD handle
> and devid are used to allocate/free ioas and hwpt. hwpt_id is used to
> re-attach IOMMUFD backed device to its default VFIO sub-system created
> hwpt, i.e., when vIOMMU is disabled by guest. These properties are
> initialized in hiod::realize() after attachment.
>
> 2 new class functions are [at|de]tach_hwpt(). They are used to
> attach/detach hwpt. VFIO and VDPA can have different implementions,
> so implementation will be in sub-class instead of HostIOMMUDeviceIOMMUFD,
> e.g., in HostIOMMUDeviceIOMMUFDVFIO.
>
> Add two wrappers host_iommu_device_iommufd_[at|de]tach_hwpt to wrap the
> two functions.
>
> Signed-off-by: Zhenzhong Duan <zhenzhong.d...@intel.com>
> Reviewed-by: Cédric Le Goater <c...@redhat.com>
Reviewed-by: Eric Auger <eric.au...@redhat.com>
Eric
> ---
> include/system/iommufd.h | 50 ++++++++++++++++++++++++++++++++++++++++
> backends/iommufd.c | 22 ++++++++++++++++++
> hw/vfio/iommufd.c | 6 +++++
> 3 files changed, 78 insertions(+)
>
> diff --git a/include/system/iommufd.h b/include/system/iommufd.h
> index 83ab8e1e4c..283861b924 100644
> --- a/include/system/iommufd.h
> +++ b/include/system/iommufd.h
> @@ -67,4 +67,54 @@ bool iommufd_backend_invalidate_cache(IOMMUFDBackend *be,
> uint32_t id,
> Error **errp);
>
> #define TYPE_HOST_IOMMU_DEVICE_IOMMUFD TYPE_HOST_IOMMU_DEVICE "-iommufd"
> +OBJECT_DECLARE_TYPE(HostIOMMUDeviceIOMMUFD, HostIOMMUDeviceIOMMUFDClass,
> + HOST_IOMMU_DEVICE_IOMMUFD)
> +
> +/* Overload of the host IOMMU device for the iommufd backend */
> +struct HostIOMMUDeviceIOMMUFD {
> + HostIOMMUDevice parent_obj;
> +
> + IOMMUFDBackend *iommufd;
> + uint32_t devid;
> + uint32_t hwpt_id;
> +};
> +
> +struct HostIOMMUDeviceIOMMUFDClass {
> + HostIOMMUDeviceClass parent_class;
> +
> + /**
> + * @attach_hwpt: attach host IOMMU device to IOMMUFD hardware page table.
> + * VFIO and VDPA device can have different implementation.
> + *
> + * Mandatory callback.
> + *
> + * @idev: host IOMMU device backed by IOMMUFD backend.
> + *
> + * @hwpt_id: ID of IOMMUFD hardware page table.
> + *
> + * @errp: pass an Error out when attachment fails.
> + *
> + * Returns: true on success, false on failure.
> + */
> + bool (*attach_hwpt)(HostIOMMUDeviceIOMMUFD *idev, uint32_t hwpt_id,
> + Error **errp);
> + /**
> + * @detach_hwpt: detach host IOMMU device from IOMMUFD hardware page
> table.
> + * VFIO and VDPA device can have different implementation.
> + *
> + * Mandatory callback.
> + *
> + * @idev: host IOMMU device backed by IOMMUFD backend.
> + *
> + * @errp: pass an Error out when attachment fails.
> + *
> + * Returns: true on success, false on failure.
> + */
> + bool (*detach_hwpt)(HostIOMMUDeviceIOMMUFD *idev, Error **errp);
> +};
> +
> +bool host_iommu_device_iommufd_attach_hwpt(HostIOMMUDeviceIOMMUFD *idev,
> + uint32_t hwpt_id, Error **errp);
> +bool host_iommu_device_iommufd_detach_hwpt(HostIOMMUDeviceIOMMUFD *idev,
> + Error **errp);
> #endif
> diff --git a/backends/iommufd.c b/backends/iommufd.c
> index 8bcdb60fe7..c2c47abf7e 100644
> --- a/backends/iommufd.c
> +++ b/backends/iommufd.c
> @@ -347,6 +347,26 @@ bool iommufd_backend_invalidate_cache(IOMMUFDBackend
> *be, uint32_t id,
> return !ret;
> }
>
> +bool host_iommu_device_iommufd_attach_hwpt(HostIOMMUDeviceIOMMUFD *idev,
> + uint32_t hwpt_id, Error **errp)
> +{
> + HostIOMMUDeviceIOMMUFDClass *idevc =
> + HOST_IOMMU_DEVICE_IOMMUFD_GET_CLASS(idev);
> +
> + g_assert(idevc->attach_hwpt);
> + return idevc->attach_hwpt(idev, hwpt_id, errp);
> +}
> +
> +bool host_iommu_device_iommufd_detach_hwpt(HostIOMMUDeviceIOMMUFD *idev,
> + Error **errp)
> +{
> + HostIOMMUDeviceIOMMUFDClass *idevc =
> + HOST_IOMMU_DEVICE_IOMMUFD_GET_CLASS(idev);
> +
> + g_assert(idevc->detach_hwpt);
> + return idevc->detach_hwpt(idev, errp);
> +}
> +
> static int hiod_iommufd_get_cap(HostIOMMUDevice *hiod, int cap, Error **errp)
> {
> HostIOMMUDeviceCaps *caps = &hiod->caps;
> @@ -385,6 +405,8 @@ static const TypeInfo types[] = {
> }, {
> .name = TYPE_HOST_IOMMU_DEVICE_IOMMUFD,
> .parent = TYPE_HOST_IOMMU_DEVICE,
> + .instance_size = sizeof(HostIOMMUDeviceIOMMUFD),
> + .class_size = sizeof(HostIOMMUDeviceIOMMUFDClass),
> .class_init = hiod_iommufd_class_init,
> .abstract = true,
> }
> diff --git a/hw/vfio/iommufd.c b/hw/vfio/iommufd.c
> index af1c7ab10a..5fde2b633a 100644
> --- a/hw/vfio/iommufd.c
> +++ b/hw/vfio/iommufd.c
> @@ -814,6 +814,7 @@ static bool hiod_iommufd_vfio_realize(HostIOMMUDevice
> *hiod, void *opaque,
> Error **errp)
> {
> VFIODevice *vdev = opaque;
> + HostIOMMUDeviceIOMMUFD *idev;
> HostIOMMUDeviceCaps *caps = &hiod->caps;
> enum iommu_hw_info_type type;
> union {
> @@ -833,6 +834,11 @@ static bool hiod_iommufd_vfio_realize(HostIOMMUDevice
> *hiod, void *opaque,
> caps->type = type;
> caps->hw_caps = hw_caps;
>
> + idev = HOST_IOMMU_DEVICE_IOMMUFD(hiod);
> + idev->iommufd = vdev->iommufd;
> + idev->devid = vdev->devid;
> + idev->hwpt_id = vdev->hwpt->hwpt_id;
> +
> return true;
> }
>