diff mbox series

[PULL,07/15] vhost: check queue state in the vhost_dev_set_log routine

Message ID 20200918150506.286890-8-mst@redhat.com
State New
Headers show
Series virtio,pc,acpi: fixes, tests | expand

Commit Message

Michael S. Tsirkin Sept. 18, 2020, 3:06 p.m. UTC
From: Dima Stepanov <dimastep@yandex-team.ru>

If the vhost-user-blk daemon provides only one virtqueue, but device was
added with several queues, then QEMU will send more VHOST-USER command
than expected by daemon side. The vhost_virtqueue_start() routine
handles such case by checking the return value from the
virtio_queue_get_desc_addr() function call. Add the same check to the
vhost_dev_set_log() routine.

Signed-off-by: Dima Stepanov <dimastep@yandex-team.ru>
Message-Id: <2da64fc45789094b6bd6f1c283cac9e47eeeb786.1598865610.git.dimastep@yandex-team.ru>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
 hw/virtio/vhost.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

Comments

Raphael Norwitz Sept. 18, 2020, 3:30 p.m. UTC | #1
Hi MST - I think you picked an earlier version of the change with a
bug. See my comment bellow:

On Fri, Sep 18, 2020 at 11:11 AM Michael S. Tsirkin <mst@redhat.com> wrote:
>

> From: Dima Stepanov <dimastep@yandex-team.ru>

>

> If the vhost-user-blk daemon provides only one virtqueue, but device was

> added with several queues, then QEMU will send more VHOST-USER command

> than expected by daemon side. The vhost_virtqueue_start() routine

> handles such case by checking the return value from the

> virtio_queue_get_desc_addr() function call. Add the same check to the

> vhost_dev_set_log() routine.

>

> Signed-off-by: Dima Stepanov <dimastep@yandex-team.ru>

> Message-Id: <2da64fc45789094b6bd6f1c283cac9e47eeeb786.1598865610.git.dimastep@yandex-team.ru>

> Reviewed-by: Michael S. Tsirkin <mst@redhat.com>

> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>

> ---

>  hw/virtio/vhost.c | 12 ++++++++++++

>  1 file changed, 12 insertions(+)

>

> diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c

> index 1b2d735b54..abe0fe3e67 100644

> --- a/hw/virtio/vhost.c

> +++ b/hw/virtio/vhost.c

> @@ -835,12 +835,24 @@ out:

>  static int vhost_dev_set_log(struct vhost_dev *dev, bool enable_log)

>  {

>      int r, i, idx;

> +    hwaddr addr;

> +

>      r = vhost_dev_set_features(dev, enable_log);

>      if (r < 0) {

>          goto err_features;

>      }

>      for (i = 0; i < dev->nvqs; ++i) {

>          idx = dev->vhost_ops->vhost_get_vq_index(dev, dev->vq_index + i);

> +        addr = virtio_queue_get_desc_addr(dev->vdev, idx);

> +        if (!addr) {

> +            /*

> +             * The queue might not be ready for start. If this

> +             * is the case there is no reason to continue the process.

> +             * The similar logic is used by the vhost_virtqueue_start()

> +             * routine.

> +             */


This should be "continue" not "break" right?

ref: https://lore.kernel.org/qemu-devel/20200901083616.GA18268@dimastep-nix/

> +            break;

> +        }

>          r = vhost_virtqueue_set_addr(dev, dev->vqs + i, idx,

>                                       enable_log);

>          if (r < 0) {

> --

> MST

>

>
diff mbox series

Patch

diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index 1b2d735b54..abe0fe3e67 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -835,12 +835,24 @@  out:
 static int vhost_dev_set_log(struct vhost_dev *dev, bool enable_log)
 {
     int r, i, idx;
+    hwaddr addr;
+
     r = vhost_dev_set_features(dev, enable_log);
     if (r < 0) {
         goto err_features;
     }
     for (i = 0; i < dev->nvqs; ++i) {
         idx = dev->vhost_ops->vhost_get_vq_index(dev, dev->vq_index + i);
+        addr = virtio_queue_get_desc_addr(dev->vdev, idx);
+        if (!addr) {
+            /*
+             * The queue might not be ready for start. If this
+             * is the case there is no reason to continue the process.
+             * The similar logic is used by the vhost_virtqueue_start()
+             * routine.
+             */
+            break;
+        }
         r = vhost_virtqueue_set_addr(dev, dev->vqs + i, idx,
                                      enable_log);
         if (r < 0) {