Blame SOURCES/kvm-vhost_net-don-t-set-backend-for-the-uninitialized-vi.patch

7711c0
From 55e77ff717339c63b0408e0b9a1bcd313d6c0c48 Mon Sep 17 00:00:00 2001
7711c0
From: Xiao Wang <jasowang@redhat.com>
7711c0
Date: Fri, 24 May 2019 12:56:42 +0200
7711c0
Subject: [PATCH] vhost_net: don't set backend for the uninitialized virtqueue
7711c0
7711c0
RH-Author: Xiao Wang <jasowang@redhat.com>
7711c0
Message-id: <1558702602-3677-1-git-send-email-jasowang@redhat.com>
7711c0
Patchwork-id: 88204
7711c0
O-Subject: [RHEL-7.7 qemu-kvm PATCH] vhost_net: don't set backend for the uninitialized virtqueue
7711c0
Bugzilla: 1608226
7711c0
RH-Acked-by: Thomas Huth <thuth@redhat.com>
7711c0
RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
7711c0
RH-Acked-by: Jens Freimann <jfreimann@redhat.com>
7711c0
7711c0
We used to set backend unconditionally, this won't work for some
7711c0
guests (e.g windows driver) who may not initialize all virtqueues. For
7711c0
kernel backend, this will fail since it may try to validate the rings
7711c0
during setting backend.
7711c0
7711c0
Fixing this by simply skipping the backend set when we find desc is
7711c0
not ready.
7711c0
7711c0
Reviewed-by: Michael S. Tsirkin<mst@redhat.com>
7711c0
Signed-off-by: Jason Wang <jasowang@redhat.com>
7711c0
(cherry picked from commit 23bfaf77fa801ba30bb136de7cec47728eb02f4b)
7711c0
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
7711c0
---
7711c0
 hw/net/vhost_net.c         | 10 ++++++++++
7711c0
 hw/virtio/virtio.c         |  5 +++++
7711c0
 include/hw/virtio/virtio.h |  1 +
7711c0
 3 files changed, 16 insertions(+)
7711c0
7711c0
diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c
7711c0
index e037db6..ec22727 100644
7711c0
--- a/hw/net/vhost_net.c
7711c0
+++ b/hw/net/vhost_net.c
7711c0
@@ -246,6 +246,11 @@ static int vhost_net_start_one(struct vhost_net *net,
7711c0
         qemu_set_fd_handler(net->backend, NULL, NULL, NULL);
7711c0
         file.fd = net->backend;
7711c0
         for (file.index = 0; file.index < net->dev.nvqs; ++file.index) {
7711c0
+            if (!virtio_queue_enabled(dev, net->dev.vq_index +
7711c0
+                                      file.index)) {
7711c0
+                /* Queue might not be ready for start */
7711c0
+                continue;
7711c0
+            }
7711c0
             r = vhost_net_set_backend(&net->dev, &file;;
7711c0
             if (r < 0) {
7711c0
                 r = -errno;
7711c0
@@ -258,6 +263,11 @@ fail:
7711c0
     file.fd = -1;
7711c0
     if (net->nc->info->type == NET_CLIENT_DRIVER_TAP) {
7711c0
         while (file.index-- > 0) {
7711c0
+            if (!virtio_queue_enabled(dev, net->dev.vq_index +
7711c0
+                                      file.index)) {
7711c0
+                /* Queue might not be ready for start */
7711c0
+                continue;
7711c0
+            }
7711c0
             int r = vhost_net_set_backend(&net->dev, &file;;
7711c0
             assert(r >= 0);
7711c0
         }
7711c0
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
7711c0
index 1c936ad..3492b20 100644
7711c0
--- a/hw/virtio/virtio.c
7711c0
+++ b/hw/virtio/virtio.c
7711c0
@@ -2317,6 +2317,11 @@ hwaddr virtio_queue_get_desc_addr(VirtIODevice *vdev, int n)
7711c0
     return vdev->vq[n].vring.desc;
7711c0
 }
7711c0
 
7711c0
+bool virtio_queue_enabled(VirtIODevice *vdev, int n)
7711c0
+{
7711c0
+    return virtio_queue_get_desc_addr(vdev, n) != 0;
7711c0
+}
7711c0
+
7711c0
 hwaddr virtio_queue_get_avail_addr(VirtIODevice *vdev, int n)
7711c0
 {
7711c0
     return vdev->vq[n].vring.avail;
7711c0
diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
7711c0
index 96313e8..3029758 100644
7711c0
--- a/include/hw/virtio/virtio.h
7711c0
+++ b/include/hw/virtio/virtio.h
7711c0
@@ -268,6 +268,7 @@ typedef struct VirtIORNGConf VirtIORNGConf;
7711c0
                       VIRTIO_F_IOMMU_PLATFORM, false)
7711c0
 
7711c0
 hwaddr virtio_queue_get_desc_addr(VirtIODevice *vdev, int n);
7711c0
+bool virtio_queue_enabled(VirtIODevice *vdev, int n);
7711c0
 hwaddr virtio_queue_get_avail_addr(VirtIODevice *vdev, int n);
7711c0
 hwaddr virtio_queue_get_used_addr(VirtIODevice *vdev, int n);
7711c0
 hwaddr virtio_queue_get_desc_size(VirtIODevice *vdev, int n);
7711c0
-- 
7711c0
1.8.3.1
7711c0