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.duan@intel.com>
Reviewed-by: Cédric Le Goater <clg@redhat.com>
---
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;
}
--
2.34.1
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.duan@intel.com>
> Reviewed-by: Cédric Le Goater <clg@redhat.com>
Reviewed-by: Eric Auger <eric.auger@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;
> }
>
On Fri, May 30, 2025 at 05:35:10PM +0800, 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. You mean HostIOMMUDeviceVFIO and HostIOMMUDeviceVDPA? I wonder what are the difference between their implementations. Main reason for asking this is that we have alloc_hwpt (and will have alloc_viommu soon) too, and should that/those be a part of the Class op(s) too? > @@ -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; Since it's the default hwpt that VFIO contain allocated, perhaps it's better to call it default_hwpt_id, indicating that won't be changed by further HWPT attachment. Thanks Nicolin
>-----Original Message----- >From: Nicolin Chen <nicolinc@nvidia.com> >Subject: Re: [PATCH v2 2/4] vfio/iommufd: Add properties and handlers to >TYPE_HOST_IOMMU_DEVICE_IOMMUFD > >On Fri, May 30, 2025 at 05:35:10PM +0800, 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. > >You mean HostIOMMUDeviceVFIO and HostIOMMUDeviceVDPA? HostIOMMUDeviceIOMMUFDVFIO and HostIOMMUDeviceIOMMUFDVDPA. > >I wonder what are the difference between their implementations. They have different way to transform HOST_IOMMU_DEVICE(idev)->agent. See host_iommu_device_iommufd_vfio_attach_hwpt() > >Main reason for asking this is that we have alloc_hwpt (and will >have alloc_viommu soon) too, and should that/those be a part of >the Class op(s) too? I think vIOMMU could call alloc_viommu and alloc_hwpt directly, they are common IOMMUFD interface no matter VFIO or VDPA backend device. > >> @@ -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; > >Since it's the default hwpt that VFIO contain allocated, perhaps >it's better to call it default_hwpt_id, indicating that won't be >changed by further HWPT attachment. hiod_iommufd_vfio_realize() is called only once, no one will change idev->hwpt_id. Thanks Zhenzhong
© 2016 - 2025 Red Hat, Inc.