@@ -95,6 +95,7 @@ void vfio_container_destroy(VFIOContainerBase *bcontainer);
#define TYPE_VFIO_IOMMU "vfio-iommu"
#define TYPE_VFIO_IOMMU_LEGACY TYPE_VFIO_IOMMU "-legacy"
+#define TYPE_VFIO_IOMMU_SPAPR TYPE_VFIO_IOMMU "-spapr"
/*
* VFIOContainerBase is not an abstract QOM object because it felt
@@ -381,6 +381,10 @@ static const VFIOIOMMUClass *vfio_get_iommu_class(int iommu_type, Error **errp)
case VFIO_TYPE1_IOMMU:
klass = object_class_by_name(TYPE_VFIO_IOMMU_LEGACY);
break;
+ case VFIO_SPAPR_TCE_v2_IOMMU:
+ case VFIO_SPAPR_TCE_IOMMU:
+ klass = object_class_by_name(TYPE_VFIO_IOMMU_SPAPR);
+ break;
default:
g_assert_not_reached();
};
@@ -623,19 +627,9 @@ static int vfio_connect_container(VFIOGroup *group, AddressSpace *as,
goto free_container_exit;
}
- switch (container->iommu_type) {
- case VFIO_TYPE1v2_IOMMU:
- case VFIO_TYPE1_IOMMU:
- ret = vfio_legacy_setup(bcontainer, errp);
- break;
- case VFIO_SPAPR_TCE_v2_IOMMU:
- case VFIO_SPAPR_TCE_IOMMU:
- ret = vfio_spapr_container_init(container, errp);
- break;
- default:
- g_assert_not_reached();
- }
+ assert(bcontainer->ops->setup);
+ ret = bcontainer->ops->setup(bcontainer, errp);
if (ret) {
goto enable_discards_exit;
}
@@ -458,20 +458,11 @@ static void vfio_spapr_container_release(VFIOContainerBase *bcontainer)
}
}
-static VFIOIOMMUOps vfio_iommu_spapr_ops;
-
-static void setup_spapr_ops(VFIOContainerBase *bcontainer)
-{
- vfio_iommu_spapr_ops = *bcontainer->ops;
- vfio_iommu_spapr_ops.add_window = vfio_spapr_container_add_section_window;
- vfio_iommu_spapr_ops.del_window = vfio_spapr_container_del_section_window;
- vfio_iommu_spapr_ops.release = vfio_spapr_container_release;
- bcontainer->ops = &vfio_iommu_spapr_ops;
-}
-
-int vfio_spapr_container_init(VFIOContainer *container, Error **errp)
+static int vfio_spapr_container_setup(VFIOContainerBase *bcontainer,
+ Error **errp)
{
- VFIOContainerBase *bcontainer = &container->bcontainer;
+ VFIOContainer *container = container_of(bcontainer, VFIOContainer,
+ bcontainer);
VFIOSpaprContainer *scontainer = container_of(container, VFIOSpaprContainer,
container);
struct vfio_iommu_spapr_tce_info info;
@@ -536,8 +527,6 @@ int vfio_spapr_container_init(VFIOContainer *container, Error **errp)
0x1000);
}
- setup_spapr_ops(bcontainer);
-
return 0;
listener_unregister_exit:
@@ -546,3 +535,23 @@ listener_unregister_exit:
}
return ret;
}
+
+static void vfio_iommu_spapr_class_init(ObjectClass *klass, void *data)
+{
+ VFIOIOMMUClass *vioc = VFIO_IOMMU_CLASS(klass);
+
+ vioc->add_window = vfio_spapr_container_add_section_window;
+ vioc->del_window = vfio_spapr_container_del_section_window;
+ vioc->release = vfio_spapr_container_release;
+ vioc->setup = vfio_spapr_container_setup;
+};
+
+static const TypeInfo types[] = {
+ {
+ .name = TYPE_VFIO_IOMMU_SPAPR,
+ .parent = TYPE_VFIO_IOMMU_LEGACY,
+ .class_init = vfio_iommu_spapr_class_init,
+ },
+};
+
+DEFINE_TYPES(types)