From: Andrey Drobyshev <[email protected]> Split the first part of vhost_dev_init(): selecting the backend, calling its .vhost_init() and reading the supported features - into a new vhost_dev_init_backend() helper, and call it from vhost_dev_init().
This is in preparation for CPR restore of vhost-vsock, which needs to learn the backend's features at realize time to negotiate them when loading the incoming virtio state, but also must defer taking ownership of the device to post_load. vhost_dev_init_backend() does exactly the pre-ownership part. As a result VHOST_SET_OWNER now follows the feature query rather than precedes it. This should be safe, as no backend requires ownership before VHOST_GET_FEATURES - the kernel and vdpa backends do not check ownership for it, and vhost-user already does query features from its .vhost_init() before set_owner(). Signed-off-by: Andrey Drobyshev <[email protected]> Reviewed-by: Michael S. Tsirkin <[email protected]> Signed-off-by: Michael S. Tsirkin <[email protected]> Message-ID: <[email protected]> --- include/hw/virtio/vhost.h | 22 ++++++++++++++++++++++ hw/virtio/vhost.c | 33 +++++++++++++++++++++++---------- 2 files changed, 45 insertions(+), 10 deletions(-) diff --git a/include/hw/virtio/vhost.h b/include/hw/virtio/vhost.h index 684bafcaad..9b98d34dd0 100644 --- a/include/hw/virtio/vhost.h +++ b/include/hw/virtio/vhost.h @@ -156,6 +156,28 @@ int vhost_dev_init(struct vhost_dev *hdev, void *opaque, VhostBackendType backend_type, uint32_t busyloop_timeout, Error **errp); +/** + * vhost_dev_init_backend() - set up the backend and query its features + * @hdev: the common vhost_dev structure + * @opaque: opaque ptr passed to backend (vhost/vhost-user/vdpa) + * @backend_type: type of backend + * @errp: error handle + * + * Select the backend, initialise the backend instance and read its supported + * features into @hdev, without issuing VHOST_SET_OWNER, setting up the + * virtqueues or registering the memory listener. This is the part of + * vhost_dev_init() that precedes taking ownership; it can be used on its own + * so feature negotiation can happen before ownership is acquired (e.g. by CPR + * restore). + * + * On failure the backend may be left partially initialised; the caller must + * still call vhost_dev_cleanup() to release it. + * + * Return: 0 on success, non-zero on error while setting errp. + */ +int vhost_dev_init_backend(struct vhost_dev *hdev, void *opaque, + VhostBackendType backend_type, Error **errp); + /** * vhost_dev_cleanup() - tear down and cleanup vhost interface * @hdev: the common vhost_dev structure diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c index 371dca17dd..f9b54c46f9 100644 --- a/hw/virtio/vhost.c +++ b/hw/virtio/vhost.c @@ -1668,6 +1668,28 @@ static int vhost_dev_init_features(struct vhost_dev *hdev) return r; } +int vhost_dev_init_backend(struct vhost_dev *hdev, void *opaque, + VhostBackendType backend_type, Error **errp) +{ + int r; + + r = vhost_set_backend_type(hdev, backend_type); + assert(r >= 0); + + r = hdev->vhost_ops->vhost_init(hdev, opaque, errp); + if (r < 0) { + return r; + } + + r = vhost_dev_init_features(hdev); + if (r < 0) { + error_setg_errno(errp, -r, "vhost_init_features failed"); + return r; + } + + return 0; +} + int vhost_dev_init(struct vhost_dev *hdev, void *opaque, VhostBackendType backend_type, uint32_t busyloop_timeout, Error **errp) @@ -1680,10 +1702,7 @@ int vhost_dev_init(struct vhost_dev *hdev, void *opaque, hdev->vdev = NULL; hdev->migration_blocker = NULL; - r = vhost_set_backend_type(hdev, backend_type); - assert(r >= 0); - - r = hdev->vhost_ops->vhost_init(hdev, opaque, errp); + r = vhost_dev_init_backend(hdev, opaque, backend_type, errp); if (r < 0) { goto fail; } @@ -1694,12 +1713,6 @@ int vhost_dev_init(struct vhost_dev *hdev, void *opaque, goto fail; } - r = vhost_dev_init_features(hdev); - if (r < 0) { - error_setg_errno(errp, -r, "vhost_init_features failed"); - goto fail; - } - limit = hdev->vhost_ops->vhost_memslots_limit(hdev); if (limit < MEMORY_DEVICES_SAFE_MAX_MEMSLOTS && memory_devices_memslot_auto_decision_active()) { -- MST
