Signed-off-by: Chen Fan <chen.fan.f...@cn.fujitsu.com> --- hw/vfio/common.c | 60 ++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 39 insertions(+), 21 deletions(-)
diff --git a/hw/vfio/common.c b/hw/vfio/common.c index 67881f7..df3171d 100644 --- a/hw/vfio/common.c +++ b/hw/vfio/common.c @@ -631,6 +631,38 @@ static void vfio_put_address_space(VFIOAddressSpace *space) } } +static int vfio_register_container_listener(VFIOContainer *container, + AddressSpace *as) +{ + int ret; + + if (!as) { + return 0; + } + + container->iommu_data.type1.listener = vfio_memory_listener; + container->iommu_data.release = vfio_listener_release; + + memory_listener_register(&container->iommu_data.type1.listener, + as); + + if (container->iommu_data.type1.error) { + ret = container->iommu_data.type1.error; + error_report("vfio: memory listener initialization failed for container"); + goto listener_release_exit; + } + + container->iommu_data.type1.initialized = true; + container->space->as = as; + + return 0; + +listener_release_exit: + vfio_listener_release(container); + + return ret; +} + static int vfio_connect_container(VFIOGroup *group, AddressSpace *as) { VFIOContainer *container; @@ -684,20 +716,10 @@ static int vfio_connect_container(VFIOGroup *group, AddressSpace *as) goto free_container_exit; } - container->iommu_data.type1.listener = vfio_memory_listener; - container->iommu_data.release = vfio_listener_release; - - memory_listener_register(&container->iommu_data.type1.listener, - container->space->as); - - if (container->iommu_data.type1.error) { - ret = container->iommu_data.type1.error; - error_report("vfio: memory listener initialization failed for container"); - goto listener_release_exit; + ret = vfio_register_container_listener(container, as); + if (ret) { + goto free_container_exit; } - - container->iommu_data.type1.initialized = true; - } else if (ioctl(fd, VFIO_CHECK_EXTENSION, VFIO_SPAPR_TCE_IOMMU)) { ret = ioctl(group->fd, VFIO_GROUP_SET_CONTAINER, &fd); if (ret) { @@ -724,12 +746,10 @@ static int vfio_connect_container(VFIOGroup *group, AddressSpace *as) goto free_container_exit; } - container->iommu_data.type1.listener = vfio_memory_listener; - container->iommu_data.release = vfio_listener_release; - - memory_listener_register(&container->iommu_data.type1.listener, - container->space->as); - + ret = vfio_register_container_listener(container, as); + if (ret) { + goto free_container_exit; + } } else { error_report("vfio: No available IOMMU models"); ret = -EINVAL; @@ -743,8 +763,6 @@ static int vfio_connect_container(VFIOGroup *group, AddressSpace *as) QLIST_INSERT_HEAD(&container->group_list, group, container_next); return 0; -listener_release_exit: - vfio_listener_release(container); free_container_exit: g_free(container); -- 1.9.3