qemu/vhost-enable-vrings-in-vhost_dev_start-for-vhost-use.patch
Jiabo Feng 946c69b887 QEMU update to version 6.2.0-84(master)
- hw/arm/fsl-imx: Do not ignore Error argument
- hw/net/cadence_gem.c: spelling fixes: Octects
- tests/qtest: check the return value
- libvhost-user: Fix VHOST_USER_GET_MAX_MEM_SLOTS  reply mainline inclusion commit 69a5daec06f423843ce1bb9be5fb049314996f78 category: bugfix
- io_uring: fix short read slow path mainline inclusion commit c06fc7ce147e57ab493bad9263f1601b8298484b category: bugfix
- libvhost-user: Fix VHOST_USER_ADD_MEM_REG reply mainline inclusion commit 7f27d20ded2f480f3e66d03f90ea71507b834276 category: bugfix
- qsd: Unlink absolute PID file path mainline inclusion commit 9d8f8233b9fa525a7e37350fbc18877051128c5d category: bugfix
- net: Fix a misleading error message
- vdpa: stop all svq on device deletion
- vhost: release virtqueue objects in error path
- vhost: fix the fd leak
- virtio: i2c: Check notifier helpers for VIRTIO_CONFIG_IRQ_IDX
- hw/virtio: fix typo in VIRTIO_CONFIG_IRQ_IDX comments
- virtio-net: clear guest_announce feature if no cvq backend
- vdpa: fix VHOST_BACKEND_F_IOTLB_ASID flag check
- vdpa: do not block migration if device has cvq and x-svq=on
- vdpa net: block migration if the device has CVQ
- vdpa: Return -EIO if device ack is VIRTIO_NET_ERR in _load_mq()
- vdpa: Return -EIO if device ack is VIRTIO_NET_ERR in _load_mac()
- vdpa: fix not using CVQ buffer in case of error
- vdpa: Fix possible use-after-free for VirtQueueElement
- hw/virtio: fix vhost_user_read tracepoint
- vhost: Fix false positive out-of-bounds
- vhost: fix possible wrap in SVQ descriptor ring
- vhost: move iova_tree set to vhost_svq_start
- vhost: Always store new kick fd on vhost_svq_set_svq_kick_fd
- virtio-crypto: verify src&dst buffer length for sym request
- vdpa: commit all host notifier MRs in a single MR transaction
- vdpa: harden the error path if get_iova_range failed
- vdpa-dev: get iova range explicitly
- virtio-pci: add support for configure interrupt
- virtio-mmio: add support for configure interrupt
- virtio-net: add support for configure interrupt
- vhost: add support for configure interrupt
- virtio: add support for configure interrupt
- vhost-vdpa: add support for config interrupt
- vhost: introduce new VhostOps vhost_set_config_call
- virtio-pci: decouple the single vector from the interrupt process
- virtio-pci: decouple notifier from interrupt process
- virtio: introduce macro VIRTIO_CONFIG_IRQ_IDX
- vdpa: do not handle VIRTIO_NET_F_GUEST_ANNOUNCE in vhost-vdpa
- vdpa: handle VIRTIO_NET_CTRL_ANNOUNCE in vhost_vdpa_net_handle_ctrl_avail
- vhost: fix vq dirty bitmap syncing when vIOMMU is enabled
- hw/virtio: gracefully handle unset vhost_dev vdev
- hw/virtio/vhost: Fix typo in comment.
- vdpa: always start CVQ in SVQ mode if possible
- vdpa: add shadow_data to vhost_vdpa
- vdpa: store x-svq parameter in VhostVDPAState
- vdpa: add asid parameter to vhost_vdpa_dma_map/unmap
- vdpa: allocate SVQ array unconditionally
- vdpa: move SVQ vring features check to net/
- vdpa: request iova_range only once
- vdpa: add vhost_vdpa_net_valid_svq_features
- vhost: allocate SVQ device file descriptors at device start
- vhost: set SVQ device call handler at SVQ start
- vdpa: use v->shadow_vqs_enabled in vhost_vdpa_svqs_start & stop
- vhost: enable vrings in vhost_dev_start() for vhost-user devices
- vhost-vdpa: fix assert !virtio_net_get_subqueue(nc)->async_tx.elem in virtio_net_reset
- net/vhost-vdpa.c: Fix clang compilation failure
- vhost-vdpa: allow passing opened vhostfd to vhost-vdpa
- vdpa: Remove shadow CVQ command check
- vdpa: Delete duplicated vdpa_feature_bits entry
- hw/virtio: add some vhost-user trace events
- vdpa: Allow MQ feature in SVQ
- virtio-net: Update virtio-net curr_queue_pairs in vdpa backends
- vdpa: validate MQ CVQ commands
- vdpa: Add vhost_vdpa_net_load_mq
- vdpa: extract vhost_vdpa_net_load_mac from vhost_vdpa_net_load
- vdpa: Make VhostVDPAState cvq_cmd_in_buffer control ack type
- vdpa: Delete CVQ migration blocker
- vdpa: Add virtio-net mac address via CVQ at start
- vhost_net: add NetClientState->load() callback
- vdpa: extract vhost_vdpa_net_cvq_add from vhost_vdpa_net_handle_ctrl_avail
- vdpa: Move command buffers map to start of net device
- vdpa: add net_vhost_vdpa_cvq_info NetClientInfo
- vhost_net: Add NetClientInfo stop callback
- vhost_net: Add NetClientInfo start callback
- vdpa: Use ring hwaddr at vhost_vdpa_svq_unmap_ring
- vdpa: Make SVQ vring unmapping return void
- vdpa: Remove SVQ vring from iova_tree at shutdown
- util: accept iova_tree_remove_parameter by value
- vdpa: do not save failed dma maps in SVQ iova tree
- vdpa: Skip the maps not in the iova tree
- vdpa: Fix file descriptor leak on get features error
- vdpa: Fix memory listener deletions of iova tree
- vhost: Get vring base from vq, not svq
- vdpa: Add x-svq to NetdevVhostVDPAOptions
- vdpa: Add device migration blocker
- vdpa: Extract get features part from vhost_vdpa_get_max_queue_pairs
- vdpa: Buffer CVQ support on shadow virtqueue
- vdpa: manual forward CVQ buffers
- vdpa: Export vhost_vdpa_dma_map and unmap calls
- vhost: Add svq avail_handler callback
- vhost: add vhost_svq_poll
- vhost: Expose vhost_svq_add
- vhost: add vhost_svq_push_elem
- vhost: Track number of descs in SVQDescState
- vhost: Add SVQDescState
- vhost: Decouple vhost_svq_add from VirtQueueElement
- vhost: Check for queue full at vhost_svq_add
- vhost: Move vhost_svq_kick call to vhost_svq_add
- vhost: Reorder vhost_svq_kick
- vdpa: Avoid compiler to squash reads to used idx
- virtio-net: Expose ctrl virtqueue logic
- virtio-net: Expose MAC_TABLE_ENTRIES
- vhost: move descriptor translation to vhost_svq_vring_write_descs
- util: Return void on iova_tree_remove
- virtio-net: don't handle mq request in userspace handler for vhost-vdpa
- vhost-vdpa: change name and polarity for vhost_vdpa_one_time_request()
- vhost-vdpa: backend feature should set only once
- vhost-vdpa: fix improper cleanup in net_init_vhost_vdpa
- virtio-net: align ctrl_vq index for non-mq guest for vhost_vdpa
- virtio: add vhost support for virtio devices
- include/hw: start documenting the vhost API
- hw/virtio: add vhost_user_[read|write] trace points
- vhost: Fix element in vhost_svq_add failure
- vdpa: Fix index calculus at vhost_vdpa_svqs_start
- vdpa: Fix bad index calculus at vhost_vdpa_get_vring_base
- vhost: Fix device's used descriptor dequeue
- vhost: Track descriptor chain in private at SVQ
- vdpa: Add missing tracing to batch mapping functions
- vhost-vdpa: fix typo in a comment
- virtio: fix --enable-vhost-user build on non-Linux
- vdpa: Expose VHOST_F_LOG_ALL on SVQ
- vdpa: Never set log_base addr if SVQ is enabled
- vdpa: Adapt vhost_vdpa_get_vring_base to SVQ
- vdpa: Add custom IOTLB translations to SVQ
- vhost: Add VhostIOVATree
- util: add iova_tree_find_iova
- util: Add iova_tree_alloc_map
- vhost: Shadow virtqueue buffers forwarding
- vdpa: adapt vhost_ops callbacks to svq
- virtio: Add vhost_svq_get_vring_addr
- vhost: Add vhost_svq_valid_features to shadow vq
- vhost: Add Shadow VirtQueue call forwarding capabilities
- vhost: Add Shadow VirtQueue kick forwarding capabilities
- vhost: Add VhostShadowVirtqueue
- vdpa: Make ncs autofree
- Revert "virtio: introduce macro IRTIO_CONFIG_IRQ_IDX"
- Revert "virtio-pci: decouple notifier from interrupt process"
- Revert "virtio-pci: decouple the single vector from the interrupt process"
- Revert "vhost-vdpa: add support for config interrupt"
- Revert "virtio: add support for configure interrupt"
- Revert "vhost: add support for configure interrupt"
- Revert "virtio-net: add support for configure interrupt"
- Revert "virtio-mmio: add support for configure interrupt"
- Revert "virtio-pci: add support for configure interrupt"
- Revert "vhost: introduce new VhostOps vhost_set_config_call"
- virtio: signal after wrapping packed used_idx
- target/i386: Adjust feature level according to FEAT_7_1_EDX
- target/i386: Add new CPU model GraniteRapids
- target/i386: Add support for PREFETCHIT0/1 in CPUID enumeration
- target/i386: Add support for AVX-NE-CONVERT in CPUID enumeration
- target/i386: Add support for AVX-VNNI-INT8 in CPUID enumeration
- target/i386: Add support for AVX-IFMA in CPUID enumeration
- target/i386: Add support for AMX-FP16 in CPUID enumeration
- target/i386: Add support for CMPCCXADD in CPUID enumeration
- tracetool: avoid invalid escape in Python string
- hw/pvrdma: Protect against buggy or malicious guest driver
- vga: avoid crash if no default vga card mainline inclusion commit 6985d8ede92494f3b791de01e8ee9306eb6d5e4a category: bugfix
- qom/object: Remove circular include dependency mainline inclusion commit 5bba9bcfbb42e7c016626420e148a1bf1b080835 category: bugfix
- artist: set memory region owners for buffers to the  artist device mainline inclusion commit 39fbaeca096a9bf6cbe2af88572c1cb2aa62aa8c category: bugfix
- virtio-iommu: Fix the partial copy of probe request mainline inclusion commit 45461aace83d961e933b27519b81d17b4c690514 category: bugfix
- e1000: set RX descriptor status in a separate  operation mainline inclusion commit 034d00d4858161e1d4cff82d8d230bce874a04d3 category: bugfix
- vhost: introduce new VhostOps vhost_set_config_call
- vhost: stick to -errno error return convention
- vhost-user: stick to -errno error return convention
- vhost-vdpa: stick to -errno error return convention
- virtio-pci: add support for configure interrupt
- virtio-mmio: add support for configure interrupt
- virtio-net: add support for configure interrupt
- vhost: add support for configure interrupt
- virtio: add support for configure interrupt
- vhost-vdpa: add support for config interrupt
- virtio-pci: decouple the single vector from the interrupt process
- virtio-pci: decouple notifier from interrupt process
- virtio: introduce macro IRTIO_CONFIG_IRQ_IDX
- pci: Fix the update of interrupt disable bit in PCI_COMMAND register
- hw/timer/npcm7xx_timer: Prevent timer from counting down past zero
- tpm_crb: mark command buffer as dirty on request  completion mainline inclusion commit e37a0ef4605e5d2041785ff3fc89ca6021faf7a0 category: bugfix
- pci: fix overflow in snprintf string formatting mainline inclusion commit 36f18c6989a3d1ff1d7a0e50b0868ef3958299b4 category: bugfix
- hw/usb/hcd-ehci: fix writeback order mainline inclusion commit f471e8b060798f26a7fc339c6152f82f22a7b33d category: bugfix
- qemu-timer: Skip empty timer lists before locking  in qemu_clock_deadline_ns_all mainline inclusion commit 3f42906c9ab2c777a895b48b87b8107167e4a275 category: bugfix
- semihosting/config: Merge --semihosting-config  option groups mainline inclusion commit 90c072e063737e9e8f431489bbd334452f89056e category: bugfix
- semihosting: fix memleak at semihosting_arg_fallback
- target/i386: Export GDS_NO bit to guests

Signed-off-by: Jiabo Feng <fengjiabo1@huawei.com>
2023-11-28 16:41:25 +08:00

454 lines
16 KiB
Diff

From f0586baaa57c4042135b6d8f4d940da8a99e3737 Mon Sep 17 00:00:00 2001
From: Stefano Garzarella <sgarzare@redhat.com>
Date: Wed, 30 Nov 2022 11:24:36 +0000
Subject: [PATCH] vhost: enable vrings in vhost_dev_start() for vhost-user
devices
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Commit 02b61f38d3 ("hw/virtio: incorporate backend features in features")
properly negotiates VHOST_USER_F_PROTOCOL_FEATURES with the vhost-user
backend, but we forgot to enable vrings as specified in
docs/interop/vhost-user.rst:
If ``VHOST_USER_F_PROTOCOL_FEATURES`` has not been negotiated, the
ring starts directly in the enabled state.
If ``VHOST_USER_F_PROTOCOL_FEATURES`` has been negotiated, the ring is
initialized in a disabled state and is enabled by
``VHOST_USER_SET_VRING_ENABLE`` with parameter 1.
Some vhost-user front-ends already did this by calling
vhost_ops.vhost_set_vring_enable() directly:
- backends/cryptodev-vhost.c
- hw/net/virtio-net.c
- hw/virtio/vhost-user-gpio.c
But most didn't do that, so we would leave the vrings disabled and some
backends would not work. We observed this issue with the rust version of
virtiofsd [1], which uses the event loop [2] provided by the
vhost-user-backend crate where requests are not processed if vring is
not enabled.
Let's fix this issue by enabling the vrings in vhost_dev_start() for
vhost-user front-ends that don't already do this directly. Same thing
also in vhost_dev_stop() where we disable vrings.
[1] https://gitlab.com/virtio-fs/virtiofsd
[2] https://github.com/rust-vmm/vhost/blob/240fc2966/crates/vhost-user-backend/src/event_loop.rs#L217
Fixes: 02b61f38d3 ("hw/virtio: incorporate backend features in features")
Reported-by: German Maglione <gmaglione@redhat.com>
Tested-by: German Maglione <gmaglione@redhat.com>
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
Acked-by: Raphael Norwitz <raphael.norwitz@nutanix.com>
Message-Id: <20221123131630.52020-1-sgarzare@redhat.com>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Message-Id: <20221130112439.2527228-3-alex.bennee@linaro.org>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: fangyi <eric.fangyi@huawei.com>
---
backends/cryptodev-vhost.c | 4 ++--
backends/vhost-user.c | 4 ++--
hw/block/vhost-user-blk.c | 4 ++--
hw/net/vhost_net.c | 6 ++---
hw/scsi/vhost-scsi-common.c | 4 ++--
hw/virtio/trace-events | 4 ++--
hw/virtio/vdpa-dev.c | 4 ++--
hw/virtio/vhost-user-fs.c | 4 ++--
hw/virtio/vhost-user-i2c.c | 4 ++--
hw/virtio/vhost-user-rng.c | 4 ++--
hw/virtio/vhost-vsock-common.c | 4 ++--
hw/virtio/vhost.c | 44 ++++++++++++++++++++++++++++++----
include/hw/virtio/vhost.h | 9 +++++--
13 files changed, 69 insertions(+), 30 deletions(-)
diff --git a/backends/cryptodev-vhost.c b/backends/cryptodev-vhost.c
index bc13e466b4..572f87b3be 100644
--- a/backends/cryptodev-vhost.c
+++ b/backends/cryptodev-vhost.c
@@ -94,7 +94,7 @@ cryptodev_vhost_start_one(CryptoDevBackendVhost *crypto,
goto fail_notifiers;
}
- r = vhost_dev_start(&crypto->dev, dev);
+ r = vhost_dev_start(&crypto->dev, dev, false);
if (r < 0) {
goto fail_start;
}
@@ -111,7 +111,7 @@ static void
cryptodev_vhost_stop_one(CryptoDevBackendVhost *crypto,
VirtIODevice *dev)
{
- vhost_dev_stop(&crypto->dev, dev);
+ vhost_dev_stop(&crypto->dev, dev, false);
vhost_dev_disable_notifiers(&crypto->dev, dev);
}
diff --git a/backends/vhost-user.c b/backends/vhost-user.c
index 10b39992d2..6632e2fe6f 100644
--- a/backends/vhost-user.c
+++ b/backends/vhost-user.c
@@ -85,7 +85,7 @@ vhost_user_backend_start(VhostUserBackend *b)
}
b->dev.acked_features = b->vdev->guest_features;
- ret = vhost_dev_start(&b->dev, b->vdev);
+ ret = vhost_dev_start(&b->dev, b->vdev, true);
if (ret < 0) {
error_report("Error start vhost dev");
goto err_guest_notifiers;
@@ -120,7 +120,7 @@ vhost_user_backend_stop(VhostUserBackend *b)
return;
}
- vhost_dev_stop(&b->dev, b->vdev);
+ vhost_dev_stop(&b->dev, b->vdev, true);
if (k->set_guest_notifiers) {
ret = k->set_guest_notifiers(qbus->parent,
diff --git a/hw/block/vhost-user-blk.c b/hw/block/vhost-user-blk.c
index 9bf18434c2..eddc5588fa 100644
--- a/hw/block/vhost-user-blk.c
+++ b/hw/block/vhost-user-blk.c
@@ -167,7 +167,7 @@ static int vhost_user_blk_start(VirtIODevice *vdev, Error **errp)
goto err_guest_notifiers;
}
- ret = vhost_dev_start(&s->dev, vdev);
+ ret = vhost_dev_start(&s->dev, vdev, true);
if (ret < 0) {
error_setg_errno(errp, -ret, "Error starting vhost");
goto err_guest_notifiers;
@@ -207,7 +207,7 @@ static void vhost_user_blk_stop(VirtIODevice *vdev)
return;
}
- vhost_dev_stop(&s->dev, vdev);
+ vhost_dev_stop(&s->dev, vdev, true);
ret = k->set_guest_notifiers(qbus->parent, s->dev.nvqs, false);
if (ret < 0) {
diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c
index f709c060b6..c950d7e2e8 100644
--- a/hw/net/vhost_net.c
+++ b/hw/net/vhost_net.c
@@ -319,7 +319,7 @@ static int vhost_net_start_one(struct vhost_net *net,
goto fail_notifiers;
}
- r = vhost_dev_start(&net->dev, dev);
+ r = vhost_dev_start(&net->dev, dev, false);
if (r < 0) {
goto fail_start;
}
@@ -368,7 +368,7 @@ fail:
if (net->nc->info->poll) {
net->nc->info->poll(net->nc, true);
}
- vhost_dev_stop(&net->dev, dev);
+ vhost_dev_stop(&net->dev, dev, false);
fail_start:
vhost_dev_disable_notifiers(&net->dev, dev);
fail_notifiers:
@@ -389,7 +389,7 @@ static void vhost_net_stop_one(struct vhost_net *net,
if (net->nc->info->poll) {
net->nc->info->poll(net->nc, true);
}
- vhost_dev_stop(&net->dev, dev);
+ vhost_dev_stop(&net->dev, dev, false);
if (net->nc->info->stop) {
net->nc->info->stop(net->nc);
}
diff --git a/hw/scsi/vhost-scsi-common.c b/hw/scsi/vhost-scsi-common.c
index 767f827e55..18ea5dcfa1 100644
--- a/hw/scsi/vhost-scsi-common.c
+++ b/hw/scsi/vhost-scsi-common.c
@@ -68,7 +68,7 @@ int vhost_scsi_common_start(VHostSCSICommon *vsc)
goto err_guest_notifiers;
}
- ret = vhost_dev_start(&vsc->dev, vdev);
+ ret = vhost_dev_start(&vsc->dev, vdev, true);
if (ret < 0) {
error_report("Error start vhost dev");
goto err_guest_notifiers;
@@ -101,7 +101,7 @@ void vhost_scsi_common_stop(VHostSCSICommon *vsc)
VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
int ret = 0;
- vhost_dev_stop(&vsc->dev, vdev);
+ vhost_dev_stop(&vsc->dev, vdev, true);
if (k->set_guest_notifiers) {
ret = k->set_guest_notifiers(qbus->parent, vsc->dev.nvqs, false);
diff --git a/hw/virtio/trace-events b/hw/virtio/trace-events
index b8a33b2a83..35d4c00e59 100644
--- a/hw/virtio/trace-events
+++ b/hw/virtio/trace-events
@@ -9,8 +9,8 @@ vhost_section(const char *name) "%s"
vhost_reject_section(const char *name, int d) "%s:%d"
vhost_iotlb_miss(void *dev, int step) "%p step %d"
vhost_dev_cleanup(void *dev) "%p"
-vhost_dev_start(void *dev, const char *name) "%p:%s"
-vhost_dev_stop(void *dev, const char *name) "%p:%s"
+vhost_dev_start(void *dev, const char *name, bool vrings) "%p:%s vrings:%d"
+vhost_dev_stop(void *dev, const char *name, bool vrings) "%p:%s vrings:%d"
# vhost-user.c
diff --git a/hw/virtio/vdpa-dev.c b/hw/virtio/vdpa-dev.c
index 1840f0e450..465b08c0e3 100644
--- a/hw/virtio/vdpa-dev.c
+++ b/hw/virtio/vdpa-dev.c
@@ -242,7 +242,7 @@ static int vhost_vdpa_device_start(VirtIODevice *vdev, Error **errp)
s->dev.acked_features = vdev->guest_features;
- ret = vhost_dev_start(&s->dev, vdev);
+ ret = vhost_dev_start(&s->dev, vdev, false);
if (ret < 0) {
error_setg_errno(errp, -ret, "Error starting vhost");
goto err_guest_notifiers;
@@ -283,7 +283,7 @@ static void vhost_vdpa_device_stop(VirtIODevice *vdev)
return;
}
- vhost_dev_stop(&s->dev, vdev);
+ vhost_dev_stop(&s->dev, vdev, false);
ret = k->set_guest_notifiers(qbus->parent, s->dev.nvqs, false);
if (ret < 0) {
diff --git a/hw/virtio/vhost-user-fs.c b/hw/virtio/vhost-user-fs.c
index 392b7d3aa1..c2739557f2 100644
--- a/hw/virtio/vhost-user-fs.c
+++ b/hw/virtio/vhost-user-fs.c
@@ -74,7 +74,7 @@ static void vuf_start(VirtIODevice *vdev)
}
fs->vhost_dev.acked_features = vdev->guest_features;
- ret = vhost_dev_start(&fs->vhost_dev, vdev);
+ ret = vhost_dev_start(&fs->vhost_dev, vdev, true);
if (ret < 0) {
error_report("Error starting vhost: %d", -ret);
goto err_guest_notifiers;
@@ -108,7 +108,7 @@ static void vuf_stop(VirtIODevice *vdev)
return;
}
- vhost_dev_stop(&fs->vhost_dev, vdev);
+ vhost_dev_stop(&fs->vhost_dev, vdev, true);
ret = k->set_guest_notifiers(qbus->parent, fs->vhost_dev.nvqs, false);
if (ret < 0) {
diff --git a/hw/virtio/vhost-user-i2c.c b/hw/virtio/vhost-user-i2c.c
index d172632bb0..dcaf471115 100644
--- a/hw/virtio/vhost-user-i2c.c
+++ b/hw/virtio/vhost-user-i2c.c
@@ -45,7 +45,7 @@ static void vu_i2c_start(VirtIODevice *vdev)
i2c->vhost_dev.acked_features = vdev->guest_features;
- ret = vhost_dev_start(&i2c->vhost_dev, vdev);
+ ret = vhost_dev_start(&i2c->vhost_dev, vdev, true);
if (ret < 0) {
error_report("Error starting vhost-user-i2c: %d", -ret);
goto err_guest_notifiers;
@@ -79,7 +79,7 @@ static void vu_i2c_stop(VirtIODevice *vdev)
return;
}
- vhost_dev_stop(&i2c->vhost_dev, vdev);
+ vhost_dev_stop(&i2c->vhost_dev, vdev, true);
ret = k->set_guest_notifiers(qbus->parent, i2c->vhost_dev.nvqs, false);
if (ret < 0) {
diff --git a/hw/virtio/vhost-user-rng.c b/hw/virtio/vhost-user-rng.c
index 543f3e3cef..f25b7cf624 100644
--- a/hw/virtio/vhost-user-rng.c
+++ b/hw/virtio/vhost-user-rng.c
@@ -42,7 +42,7 @@ static void vu_rng_start(VirtIODevice *vdev)
}
rng->vhost_dev.acked_features = vdev->guest_features;
- ret = vhost_dev_start(&rng->vhost_dev, vdev);
+ ret = vhost_dev_start(&rng->vhost_dev, vdev, true);
if (ret < 0) {
error_report("Error starting vhost-user-rng: %d", -ret);
goto err_guest_notifiers;
@@ -76,7 +76,7 @@ static void vu_rng_stop(VirtIODevice *vdev)
return;
}
- vhost_dev_stop(&rng->vhost_dev, vdev);
+ vhost_dev_stop(&rng->vhost_dev, vdev, true);
ret = k->set_guest_notifiers(qbus->parent, rng->vhost_dev.nvqs, false);
if (ret < 0) {
diff --git a/hw/virtio/vhost-vsock-common.c b/hw/virtio/vhost-vsock-common.c
index cd45aaf28e..42e4db4712 100644
--- a/hw/virtio/vhost-vsock-common.c
+++ b/hw/virtio/vhost-vsock-common.c
@@ -68,7 +68,7 @@ int vhost_vsock_common_start(VirtIODevice *vdev)
}
vvc->vhost_dev.acked_features = vdev->guest_features;
- ret = vhost_dev_start(&vvc->vhost_dev, vdev);
+ ret = vhost_dev_start(&vvc->vhost_dev, vdev, true);
if (ret < 0) {
error_report("Error starting vhost: %d", -ret);
goto err_guest_notifiers;
@@ -103,7 +103,7 @@ void vhost_vsock_common_stop(VirtIODevice *vdev)
return;
}
- vhost_dev_stop(&vvc->vhost_dev, vdev);
+ vhost_dev_stop(&vvc->vhost_dev, vdev, true);
ret = k->set_guest_notifiers(qbus->parent, vvc->vhost_dev.nvqs, false);
if (ret < 0) {
diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index 86c727d2ab..22ec9e1ef7 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -1760,15 +1760,36 @@ int vhost_dev_get_inflight(struct vhost_dev *dev, uint16_t queue_size,
return 0;
}
+static int vhost_dev_set_vring_enable(struct vhost_dev *hdev, int enable)
+{
+ if (!hdev->vhost_ops->vhost_set_vring_enable) {
+ return 0;
+ }
+
+ /*
+ * For vhost-user devices, if VHOST_USER_F_PROTOCOL_FEATURES has not
+ * been negotiated, the rings start directly in the enabled state, and
+ * .vhost_set_vring_enable callback will fail since
+ * VHOST_USER_SET_VRING_ENABLE is not supported.
+ */
+ if (hdev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_USER &&
+ !virtio_has_feature(hdev->backend_features,
+ VHOST_USER_F_PROTOCOL_FEATURES)) {
+ return 0;
+ }
+
+ return hdev->vhost_ops->vhost_set_vring_enable(hdev, enable);
+}
+
/* Host notifiers must be enabled at this point. */
-int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev)
+int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev, bool vrings)
{
int i, r;
/* should only be called after backend is connected */
assert(hdev->vhost_ops);
- trace_vhost_dev_start(hdev, vdev->name);
+ trace_vhost_dev_start(hdev, vdev->name, vrings);
vdev->vhost_started = true;
hdev->started = true;
@@ -1813,10 +1834,16 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev)
goto fail_log;
}
}
+ if (vrings) {
+ r = vhost_dev_set_vring_enable(hdev, true);
+ if (r) {
+ goto fail_log;
+ }
+ }
if (hdev->vhost_ops->vhost_dev_start) {
r = hdev->vhost_ops->vhost_dev_start(hdev, true);
if (r) {
- goto fail_log;
+ goto fail_start;
}
}
if (vhost_dev_has_iommu(hdev) &&
@@ -1831,6 +1858,10 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev)
}
}
return 0;
+fail_start:
+ if (vrings) {
+ vhost_dev_set_vring_enable(hdev, false);
+ }
fail_log:
vhost_log_put(hdev, false);
fail_vq:
@@ -1849,18 +1880,21 @@ fail_features:
}
/* Host notifiers must be enabled at this point. */
-void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev)
+void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev, bool vrings)
{
int i;
/* should only be called after backend is connected */
assert(hdev->vhost_ops);
- trace_vhost_dev_stop(hdev, vdev->name);
+ trace_vhost_dev_stop(hdev, vdev->name, vrings);
if (hdev->vhost_ops->vhost_dev_start) {
hdev->vhost_ops->vhost_dev_start(hdev, false);
}
+ if (vrings) {
+ vhost_dev_set_vring_enable(hdev, false);
+ }
for (i = 0; i < hdev->nvqs; ++i) {
vhost_virtqueue_stop(hdev,
vdev,
diff --git a/include/hw/virtio/vhost.h b/include/hw/virtio/vhost.h
index d7ab2579ff..662e0f4370 100644
--- a/include/hw/virtio/vhost.h
+++ b/include/hw/virtio/vhost.h
@@ -5,6 +5,9 @@
#include "hw/virtio/virtio.h"
#include "exec/memory.h"
+#define VHOST_F_DEVICE_IOTLB 63
+#define VHOST_USER_F_PROTOCOL_FEATURES 30
+
/* Generic structures common for any vhost based device. */
struct vhost_inflight {
@@ -165,24 +168,26 @@ void vhost_dev_disable_notifiers(struct vhost_dev *hdev, VirtIODevice *vdev);
* vhost_dev_start() - start the vhost device
* @hdev: common vhost_dev structure
* @vdev: the VirtIODevice structure
+ * @vrings: true to have vrings enabled in this call
*
* Starts the vhost device. From this point VirtIO feature negotiation
* can start and the device can start processing VirtIO transactions.
*
* Return: 0 on success, < 0 on error.
*/
-int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev);
+int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev, bool vrings);
/**
* vhost_dev_stop() - stop the vhost device
* @hdev: common vhost_dev structure
* @vdev: the VirtIODevice structure
+ * @vrings: true to have vrings disabled in this call
*
* Stop the vhost device. After the device is stopped the notifiers
* can be disabled (@vhost_dev_disable_notifiers) and the device can
* be torn down (@vhost_dev_cleanup).
*/
-void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev);
+void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev, bool vrings);
/**
* DOC: vhost device configuration handling
--
2.27.0