Message ID | 20240614095402.904691-4-eric.auger@redhat.com |
---|---|
State | New |
Headers | show |
Series | VIRTIO-IOMMU/VFIO: Fix host iommu geometry handling for hotplugged devices | expand |
On 6/14/24 11:52 AM, Eric Auger wrote: > Introduce a new HostIOMMUDevice callback that allows to > retrieve the usable IOVA ranges. > > Implement this callback in the legacy VFIO and IOMMUFD VFIO > host iommu devices. This relies on the VFIODevice agent's > base container iova_ranges resource. > > Signed-off-by: Eric Auger <eric.auger@redhat.com> > Reviewed-by: Zhenzhong Duan <zhenzhong.duan@intel.com> > > --- > > v2 -> v3: > - add g_assert(vdev) > --- > include/sysemu/host_iommu_device.h | 8 ++++++++ > hw/vfio/container.c | 16 ++++++++++++++++ > hw/vfio/iommufd.c | 16 ++++++++++++++++ > 3 files changed, 40 insertions(+) > > diff --git a/include/sysemu/host_iommu_device.h b/include/sysemu/host_iommu_device.h > index 3e5f058e7b..40e0fa13ef 100644 > --- a/include/sysemu/host_iommu_device.h > +++ b/include/sysemu/host_iommu_device.h > @@ -80,6 +80,14 @@ struct HostIOMMUDeviceClass { > * i.e., HOST_IOMMU_DEVICE_CAP_AW_BITS. > */ > int (*get_cap)(HostIOMMUDevice *hiod, int cap, Error **errp); > + /** > + * @get_iova_ranges: Return the list of usable iova_ranges along with > + * @hiod Host IOMMU device > + * > + * @hiod: handle to the host IOMMU device > + * @errp: error handle > + */ > + GList* (*get_iova_ranges)(HostIOMMUDevice *hiod, Error **errp); > }; > > /* > diff --git a/hw/vfio/container.c b/hw/vfio/container.c > index b728b978a2..c48749c089 100644 > --- a/hw/vfio/container.c > +++ b/hw/vfio/container.c > @@ -1164,12 +1164,28 @@ static int hiod_legacy_vfio_get_cap(HostIOMMUDevice *hiod, int cap, > } > } > > +static GList * > +hiod_legacy_vfio_get_iova_ranges(HostIOMMUDevice *hiod, Error **errp) > +{ > + VFIODevice *vdev = hiod->agent; > + GList *l = NULL; > + > + g_assert(vdev); > + > + if (vdev->bcontainer) { > + l = g_list_copy(vdev->bcontainer->iova_ranges); > + } > + > + return l; > +} > + > static void hiod_legacy_vfio_class_init(ObjectClass *oc, void *data) > { > HostIOMMUDeviceClass *hioc = HOST_IOMMU_DEVICE_CLASS(oc); > > hioc->realize = hiod_legacy_vfio_realize; > hioc->get_cap = hiod_legacy_vfio_get_cap; > + hioc->get_iova_ranges = hiod_legacy_vfio_get_iova_ranges; > }; > > static const TypeInfo types[] = { > diff --git a/hw/vfio/iommufd.c b/hw/vfio/iommufd.c > index dbdae1adbb..e502081c2a 100644 > --- a/hw/vfio/iommufd.c > +++ b/hw/vfio/iommufd.c > @@ -645,11 +645,27 @@ static bool hiod_iommufd_vfio_realize(HostIOMMUDevice *hiod, void *opaque, > return true; > } > > +static GList * > +hiod_iommufd_vfio_get_iova_ranges(HostIOMMUDevice *hiod, Error **errp) > +{ > + VFIODevice *vdev = hiod->agent; > + GList *l = NULL; > + > + g_assert(vdev); > + > + if (vdev->bcontainer) { > + l = g_list_copy(vdev->bcontainer->iova_ranges); > + } > + > + return l; > +} May be introduce a common vfio_container_get_iova_ranges() to be called from the get_iova_ranges() handlers ? Thanks, C. > static void hiod_iommufd_vfio_class_init(ObjectClass *oc, void *data) > { > HostIOMMUDeviceClass *hiodc = HOST_IOMMU_DEVICE_CLASS(oc); > > hiodc->realize = hiod_iommufd_vfio_realize; > + hiodc->get_iova_ranges = hiod_iommufd_vfio_get_iova_ranges; > }; > > static const TypeInfo types[] = {
diff --git a/include/sysemu/host_iommu_device.h b/include/sysemu/host_iommu_device.h index 3e5f058e7b..40e0fa13ef 100644 --- a/include/sysemu/host_iommu_device.h +++ b/include/sysemu/host_iommu_device.h @@ -80,6 +80,14 @@ struct HostIOMMUDeviceClass { * i.e., HOST_IOMMU_DEVICE_CAP_AW_BITS. */ int (*get_cap)(HostIOMMUDevice *hiod, int cap, Error **errp); + /** + * @get_iova_ranges: Return the list of usable iova_ranges along with + * @hiod Host IOMMU device + * + * @hiod: handle to the host IOMMU device + * @errp: error handle + */ + GList* (*get_iova_ranges)(HostIOMMUDevice *hiod, Error **errp); }; /* diff --git a/hw/vfio/container.c b/hw/vfio/container.c index b728b978a2..c48749c089 100644 --- a/hw/vfio/container.c +++ b/hw/vfio/container.c @@ -1164,12 +1164,28 @@ static int hiod_legacy_vfio_get_cap(HostIOMMUDevice *hiod, int cap, } } +static GList * +hiod_legacy_vfio_get_iova_ranges(HostIOMMUDevice *hiod, Error **errp) +{ + VFIODevice *vdev = hiod->agent; + GList *l = NULL; + + g_assert(vdev); + + if (vdev->bcontainer) { + l = g_list_copy(vdev->bcontainer->iova_ranges); + } + + return l; +} + static void hiod_legacy_vfio_class_init(ObjectClass *oc, void *data) { HostIOMMUDeviceClass *hioc = HOST_IOMMU_DEVICE_CLASS(oc); hioc->realize = hiod_legacy_vfio_realize; hioc->get_cap = hiod_legacy_vfio_get_cap; + hioc->get_iova_ranges = hiod_legacy_vfio_get_iova_ranges; }; static const TypeInfo types[] = { diff --git a/hw/vfio/iommufd.c b/hw/vfio/iommufd.c index dbdae1adbb..e502081c2a 100644 --- a/hw/vfio/iommufd.c +++ b/hw/vfio/iommufd.c @@ -645,11 +645,27 @@ static bool hiod_iommufd_vfio_realize(HostIOMMUDevice *hiod, void *opaque, return true; } +static GList * +hiod_iommufd_vfio_get_iova_ranges(HostIOMMUDevice *hiod, Error **errp) +{ + VFIODevice *vdev = hiod->agent; + GList *l = NULL; + + g_assert(vdev); + + if (vdev->bcontainer) { + l = g_list_copy(vdev->bcontainer->iova_ranges); + } + + return l; +} + static void hiod_iommufd_vfio_class_init(ObjectClass *oc, void *data) { HostIOMMUDeviceClass *hiodc = HOST_IOMMU_DEVICE_CLASS(oc); hiodc->realize = hiod_iommufd_vfio_realize; + hiodc->get_iova_ranges = hiod_iommufd_vfio_get_iova_ranges; }; static const TypeInfo types[] = {