|
|
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 |
|