aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorCédric Le Goater <clg@redhat.com>2024-06-17 08:34:02 +0200
committerCédric Le Goater <clg@redhat.com>2024-06-24 23:15:31 +0200
commit9550fdfd29f52d548d99aed2b1a002308ad6175a (patch)
tree8a7be0e481333a6dae7eff85fca27920538af3e9 /hw
parent58f5c13260c2bf8fe158d0e176d1595858157946 (diff)
downloadqemu-9550fdfd29f52d548d99aed2b1a002308ad6175a.zip
qemu-9550fdfd29f52d548d99aed2b1a002308ad6175a.tar.gz
qemu-9550fdfd29f52d548d99aed2b1a002308ad6175a.tar.bz2
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')
-rw-r--r--hw/vfio/container.c47
1 files changed, 23 insertions, 24 deletions
diff --git a/hw/vfio/container.c b/hw/vfio/container.c
index a869194..31bdc46 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)) {