aboutsummaryrefslogtreecommitdiff
path: root/hw/vfio
diff options
context:
space:
mode:
authorEric Auger <eric.auger@redhat.com>2019-09-24 10:25:17 +0200
committerPaolo Bonzini <pbonzini@redhat.com>2019-10-04 18:49:18 +0200
commit549d4005874f602e957b07459949ae514ea96f20 (patch)
treea3d987bddb558edc3787a626a8fb28f867072153 /hw/vfio
parentd7d8783647841a4c18349fe60d0d99e0de865ce5 (diff)
downloadqemu-549d4005874f602e957b07459949ae514ea96f20.zip
qemu-549d4005874f602e957b07459949ae514ea96f20.tar.gz
qemu-549d4005874f602e957b07459949ae514ea96f20.tar.bz2
memory: allow memory_region_register_iommu_notifier() to fail
Currently, when a notifier is attempted to be registered and its flags are not supported (especially the MAP one) by the IOMMU MR, we generally abruptly exit in the IOMMU code. The failure could be handled more nicely in the caller and especially in the VFIO code. So let's allow memory_region_register_iommu_notifier() to fail as well as notify_flag_changed() callback. All sites implementing the callback are updated. This patch does not yet remove the exit(1) in the amd_iommu code. in SMMUv3 we turn the warning message into an error message saying that the assigned device would not work properly. Signed-off-by: Eric Auger <eric.auger@redhat.com> Reviewed-by: Peter Xu <peterx@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'hw/vfio')
-rw-r--r--hw/vfio/common.c9
1 files changed, 7 insertions, 2 deletions
diff --git a/hw/vfio/common.c b/hw/vfio/common.c
index cebbb1c..5ca1148 100644
--- a/hw/vfio/common.c
+++ b/hw/vfio/common.c
@@ -636,9 +636,14 @@ static void vfio_listener_region_add(MemoryListener *listener,
section->offset_within_region,
int128_get64(llend),
iommu_idx);
- QLIST_INSERT_HEAD(&container->giommu_list, giommu, giommu_next);
- memory_region_register_iommu_notifier(section->mr, &giommu->n);
+ ret = memory_region_register_iommu_notifier(section->mr, &giommu->n,
+ &err);
+ if (ret) {
+ g_free(giommu);
+ goto fail;
+ }
+ QLIST_INSERT_HEAD(&container->giommu_list, giommu, giommu_next);
memory_region_iommu_replay(giommu->iommu, &giommu->n);
return;