mirror of https://github.com/xqemu/xqemu.git
vhost: fix cleanup on not fully initialized device
If vhost_dev_init() failed, caller may still call vhost_dev_cleanup() later. However, vhost_dev_cleanup() tries to remove the device from the list even if it wasn't yet added, which may lead to crashes. Similarly for the memory listener. Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
This commit is contained in:
parent
7b527247f0
commit
5be5f9be72
|
@ -1033,7 +1033,6 @@ int vhost_dev_init(struct vhost_dev *hdev, void *opaque,
|
||||||
r = -1;
|
r = -1;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
QLIST_INSERT_HEAD(&vhost_devices, hdev, entry);
|
|
||||||
|
|
||||||
r = hdev->vhost_ops->vhost_set_owner(hdev);
|
r = hdev->vhost_ops->vhost_set_owner(hdev);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
|
@ -1103,6 +1102,7 @@ int vhost_dev_init(struct vhost_dev *hdev, void *opaque,
|
||||||
hdev->started = false;
|
hdev->started = false;
|
||||||
hdev->memory_changed = false;
|
hdev->memory_changed = false;
|
||||||
memory_listener_register(&hdev->memory_listener, &address_space_memory);
|
memory_listener_register(&hdev->memory_listener, &address_space_memory);
|
||||||
|
QLIST_INSERT_HEAD(&vhost_devices, hdev, entry);
|
||||||
return 0;
|
return 0;
|
||||||
fail_busyloop:
|
fail_busyloop:
|
||||||
while (--i >= 0) {
|
while (--i >= 0) {
|
||||||
|
@ -1126,7 +1126,11 @@ void vhost_dev_cleanup(struct vhost_dev *hdev)
|
||||||
for (i = 0; i < hdev->nvqs; ++i) {
|
for (i = 0; i < hdev->nvqs; ++i) {
|
||||||
vhost_virtqueue_cleanup(hdev->vqs + i);
|
vhost_virtqueue_cleanup(hdev->vqs + i);
|
||||||
}
|
}
|
||||||
|
if (hdev->mem) {
|
||||||
|
/* those are only safe after successful init */
|
||||||
memory_listener_unregister(&hdev->memory_listener);
|
memory_listener_unregister(&hdev->memory_listener);
|
||||||
|
QLIST_REMOVE(hdev, entry);
|
||||||
|
}
|
||||||
if (hdev->migration_blocker) {
|
if (hdev->migration_blocker) {
|
||||||
migrate_del_blocker(hdev->migration_blocker);
|
migrate_del_blocker(hdev->migration_blocker);
|
||||||
error_free(hdev->migration_blocker);
|
error_free(hdev->migration_blocker);
|
||||||
|
@ -1135,7 +1139,6 @@ void vhost_dev_cleanup(struct vhost_dev *hdev)
|
||||||
g_free(hdev->mem_sections);
|
g_free(hdev->mem_sections);
|
||||||
hdev->vhost_ops->vhost_backend_cleanup(hdev);
|
hdev->vhost_ops->vhost_backend_cleanup(hdev);
|
||||||
assert(!hdev->log);
|
assert(!hdev->log);
|
||||||
QLIST_REMOVE(hdev, entry);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Stop processing guest IO notifications in qemu.
|
/* Stop processing guest IO notifications in qemu.
|
||||||
|
|
Loading…
Reference in New Issue