vhost: create worker at end of vhost_dev_set_owner
vsock can start queueing work after VHOST_VSOCK_SET_GUEST_CID, so after we have called vhost_worker_create it can be calling vhost_work_queue and trying to access the vhost worker/task. If vhost_dev_alloc_iovecs fails, then vhost_worker_free could free the worker/task from under vsock. This moves vhost_worker_create to the end of vhost_dev_set_owner where we know we can no longer fail in that path. If it fails after the VHOST_SET_OWNER and userspace closes the device, then the normal vsock release handling will do the right thing. Signed-off-by: Mike Christie <michael.christie@oracle.com> Message-Id: <20230626232307.97930-2-michael.christie@oracle.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
This commit is contained in:
Родитель
3845308fc8
Коммит
3e11c6eb6a
|
@ -572,20 +572,27 @@ long vhost_dev_set_owner(struct vhost_dev *dev)
|
||||||
|
|
||||||
vhost_attach_mm(dev);
|
vhost_attach_mm(dev);
|
||||||
|
|
||||||
|
err = vhost_dev_alloc_iovecs(dev);
|
||||||
|
if (err)
|
||||||
|
goto err_iovecs;
|
||||||
|
|
||||||
if (dev->use_worker) {
|
if (dev->use_worker) {
|
||||||
|
/*
|
||||||
|
* This should be done last, because vsock can queue work
|
||||||
|
* before VHOST_SET_OWNER so it simplifies the failure path
|
||||||
|
* below since we don't have to worry about vsock queueing
|
||||||
|
* while we free the worker.
|
||||||
|
*/
|
||||||
err = vhost_worker_create(dev);
|
err = vhost_worker_create(dev);
|
||||||
if (err)
|
if (err)
|
||||||
goto err_worker;
|
goto err_worker;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = vhost_dev_alloc_iovecs(dev);
|
|
||||||
if (err)
|
|
||||||
goto err_iovecs;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
err_iovecs:
|
|
||||||
vhost_worker_free(dev);
|
|
||||||
err_worker:
|
err_worker:
|
||||||
|
vhost_dev_free_iovecs(dev);
|
||||||
|
err_iovecs:
|
||||||
vhost_detach_mm(dev);
|
vhost_detach_mm(dev);
|
||||||
err_mm:
|
err_mm:
|
||||||
return err;
|
return err;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче