aboutsummaryrefslogtreecommitdiff
path: root/hw/vfio/iommufd.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/vfio/iommufd.c')
-rw-r--r--hw/vfio/iommufd.c73
1 files changed, 65 insertions, 8 deletions
diff --git a/hw/vfio/iommufd.c b/hw/vfio/iommufd.c
index 554f9a6..7b5f87a 100644
--- a/hw/vfio/iommufd.c
+++ b/hw/vfio/iommufd.c
@@ -237,9 +237,8 @@ static void iommufd_cdev_container_destroy(VFIOIOMMUFDContainer *container)
return;
}
memory_listener_unregister(&bcontainer->listener);
- vfio_container_destroy(bcontainer);
iommufd_backend_free_id(container->be, container->ioas_id);
- g_free(container);
+ object_unref(container);
}
static int iommufd_cdev_ram_block_discard_disable(bool state)
@@ -324,7 +323,7 @@ static bool iommufd_cdev_attach(const char *name, VFIODevice *vbasedev,
/* try to attach to an existing container in this space */
QLIST_FOREACH(bcontainer, &space->containers, next) {
container = container_of(bcontainer, VFIOIOMMUFDContainer, bcontainer);
- if (bcontainer->ops != iommufd_vioc ||
+ if (VFIO_IOMMU_GET_CLASS(bcontainer) != iommufd_vioc ||
vbasedev->iommufd != container->be) {
continue;
}
@@ -352,13 +351,12 @@ static bool iommufd_cdev_attach(const char *name, VFIODevice *vbasedev,
trace_iommufd_cdev_alloc_ioas(vbasedev->iommufd->fd, ioas_id);
- container = g_malloc0(sizeof(*container));
+ container = VFIO_IOMMU_IOMMUFD(object_new(TYPE_VFIO_IOMMU_IOMMUFD));
container->be = vbasedev->iommufd;
container->ioas_id = ioas_id;
bcontainer = &container->bcontainer;
- vfio_container_init(bcontainer, space, iommufd_vioc);
- QLIST_INSERT_HEAD(&space->containers, bcontainer, next);
+ vfio_address_space_insert(space, bcontainer);
if (!iommufd_cdev_attach_container(vbasedev, container, errp)) {
goto err_attach_container;
@@ -465,7 +463,7 @@ static VFIODevice *iommufd_cdev_pci_find_by_devid(__u32 devid)
VFIO_IOMMU_CLASS(object_class_by_name(TYPE_VFIO_IOMMU_IOMMUFD));
QLIST_FOREACH(vbasedev_iter, &vfio_device_list, global_next) {
- if (vbasedev_iter->bcontainer->ops != iommufd_vioc) {
+ if (VFIO_IOMMU_GET_CLASS(vbasedev_iter->bcontainer) != iommufd_vioc) {
continue;
}
if (devid == vbasedev_iter->devid) {
@@ -612,6 +610,8 @@ static void vfio_iommu_iommufd_class_init(ObjectClass *klass, void *data)
{
VFIOIOMMUClass *vioc = VFIO_IOMMU_CLASS(klass);
+ vioc->hiod_typename = TYPE_HOST_IOMMU_DEVICE_IOMMUFD_VFIO;
+
vioc->dma_map = iommufd_cdev_map;
vioc->dma_unmap = iommufd_cdev_unmap;
vioc->attach_device = iommufd_cdev_attach;
@@ -619,12 +619,69 @@ static void vfio_iommu_iommufd_class_init(ObjectClass *klass, void *data)
vioc->pci_hot_reset = iommufd_cdev_pci_hot_reset;
};
+static bool hiod_iommufd_vfio_realize(HostIOMMUDevice *hiod, void *opaque,
+ Error **errp)
+{
+ VFIODevice *vdev = opaque;
+ HostIOMMUDeviceCaps *caps = &hiod->caps;
+ enum iommu_hw_info_type type;
+ union {
+ struct iommu_hw_info_vtd vtd;
+ } data;
+
+ hiod->agent = opaque;
+
+ if (!iommufd_backend_get_device_info(vdev->iommufd, vdev->devid,
+ &type, &data, sizeof(data), errp)) {
+ return false;
+ }
+
+ hiod->name = g_strdup(vdev->name);
+ caps->type = type;
+ caps->aw_bits = vfio_device_get_aw_bits(vdev);
+
+ return true;
+}
+
+static GList *
+hiod_iommufd_vfio_get_iova_ranges(HostIOMMUDevice *hiod)
+{
+ VFIODevice *vdev = hiod->agent;
+
+ g_assert(vdev);
+ return vfio_container_get_iova_ranges(vdev->bcontainer);
+}
+
+static uint64_t
+hiod_iommufd_vfio_get_page_size_mask(HostIOMMUDevice *hiod)
+{
+ VFIODevice *vdev = hiod->agent;
+
+ g_assert(vdev);
+ return vfio_container_get_page_size_mask(vdev->bcontainer);
+}
+
+
+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;
+ hiodc->get_page_size_mask = hiod_iommufd_vfio_get_page_size_mask;
+};
+
static const TypeInfo types[] = {
{
.name = TYPE_VFIO_IOMMU_IOMMUFD,
.parent = TYPE_VFIO_IOMMU,
+ .instance_size = sizeof(VFIOIOMMUFDContainer),
.class_init = vfio_iommu_iommufd_class_init,
- },
+ }, {
+ .name = TYPE_HOST_IOMMU_DEVICE_IOMMUFD_VFIO,
+ .parent = TYPE_HOST_IOMMU_DEVICE_IOMMUFD,
+ .class_init = hiod_iommufd_vfio_class_init,
+ }
};
DEFINE_TYPES(types)