diff options
author | Cédric Le Goater <clg@redhat.com> | 2024-06-17 08:34:02 +0200 |
---|---|---|
committer | Cédric Le Goater <clg@redhat.com> | 2024-06-24 23:15:31 +0200 |
commit | 9550fdfd29f52d548d99aed2b1a002308ad6175a (patch) | |
tree | 8a7be0e481333a6dae7eff85fca27920538af3e9 /hw/vfio | |
parent | 58f5c13260c2bf8fe158d0e176d1595858157946 (diff) |
vfio/container: Discover IOMMU type before creating the container
Since the QEMU struct type representing the VFIO container is deduced
from the IOMMU type exposed by the host, this type should be well
defined *before* creating the container struct. This will be necessary
to instantiate a QOM object of the correct type in future changes.
Rework vfio_set_iommu() to extract the part doing the container
initialization and move it under vfio_create_container().
Reviewed-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
Reviewed-by: Eric Auger <eric.auger@redhat.com>
Tested-by: Eric Auger <eric.auger@redhat.com>
Signed-off-by: Cédric Le Goater <clg@redhat.com>
Diffstat (limited to 'hw/vfio')
-rw-r--r-- | hw/vfio/container.c | 47 |
1 files changed, 23 insertions, 24 deletions
diff --git a/hw/vfio/container.c b/hw/vfio/container.c index a869194279..31bdc46a96 100644 --- a/hw/vfio/container.c +++ b/hw/vfio/container.c @@ -389,54 +389,56 @@ static const char *vfio_get_iommu_class_name(int iommu_type) }; } -static bool vfio_set_iommu(VFIOContainer *container, int group_fd, - Error **errp) +static bool vfio_set_iommu(int container_fd, int group_fd, + int *iommu_type, Error **errp) { - int iommu_type; - const VFIOIOMMUClass *vioc; - const char *vioc_name; - - iommu_type = vfio_get_iommu_type(container->fd, errp); - if (iommu_type < 0) { - return false; - } - - if (ioctl(group_fd, VFIO_GROUP_SET_CONTAINER, &container->fd)) { + if (ioctl(group_fd, VFIO_GROUP_SET_CONTAINER, &container_fd)) { error_setg_errno(errp, errno, "Failed to set group container"); return false; } - while (ioctl(container->fd, VFIO_SET_IOMMU, iommu_type)) { - if (iommu_type == VFIO_SPAPR_TCE_v2_IOMMU) { + while (ioctl(container_fd, VFIO_SET_IOMMU, *iommu_type)) { + if (*iommu_type == VFIO_SPAPR_TCE_v2_IOMMU) { /* * On sPAPR, despite the IOMMU subdriver always advertises v1 and * v2, the running platform may not support v2 and there is no * way to guess it until an IOMMU group gets added to the container. * So in case it fails with v2, try v1 as a fallback. */ - iommu_type = VFIO_SPAPR_TCE_IOMMU; + *iommu_type = VFIO_SPAPR_TCE_IOMMU; continue; } error_setg_errno(errp, errno, "Failed to set iommu for container"); return false; } - container->iommu_type = iommu_type; - - vioc_name = vfio_get_iommu_class_name(iommu_type); - vioc = VFIO_IOMMU_CLASS(object_class_by_name(vioc_name)); - - vfio_container_init(&container->bcontainer, vioc); return true; } static VFIOContainer *vfio_create_container(int fd, VFIOGroup *group, Error **errp) { + int iommu_type; + const VFIOIOMMUClass *vioc; + const char *vioc_name; VFIOContainer *container; + iommu_type = vfio_get_iommu_type(fd, errp); + if (iommu_type < 0) { + return NULL; + } + + if (!vfio_set_iommu(fd, group->fd, &iommu_type, errp)) { + return NULL; + } + + vioc_name = vfio_get_iommu_class_name(iommu_type); + vioc = VFIO_IOMMU_CLASS(object_class_by_name(vioc_name)); + container = g_malloc0(sizeof(*container)); container->fd = fd; + container->iommu_type = iommu_type; + vfio_container_init(&container->bcontainer, vioc); return container; } @@ -618,9 +620,6 @@ static bool vfio_connect_container(VFIOGroup *group, AddressSpace *as, if (!container) { goto close_fd_exit; } - if (!vfio_set_iommu(container, group->fd, errp)) { - goto free_container_exit; - } bcontainer = &container->bcontainer; if (!vfio_cpr_register_container(bcontainer, errp)) { |