]> git.proxmox.com Git - pve-qemu.git/commitdiff
fix #1107: merge: virtio: fix descriptor counting in virtqueue_pop
authorWolfgang Bumiller <w.bumiller@proxmox.com>
Fri, 22 Sep 2017 11:14:53 +0000 (13:14 +0200)
committerWolfgang Bumiller <w.bumiller@proxmox.com>
Tue, 17 Oct 2017 09:36:40 +0000 (11:36 +0200)
debian/patches/extra/0014-virtio-fix-descriptor-counting-in-virtqueue_pop.patch [new file with mode: 0644]
debian/patches/series

diff --git a/debian/patches/extra/0014-virtio-fix-descriptor-counting-in-virtqueue_pop.patch b/debian/patches/extra/0014-virtio-fix-descriptor-counting-in-virtqueue_pop.patch
new file mode 100644 (file)
index 0000000..15c5afe
--- /dev/null
@@ -0,0 +1,55 @@
+From 3474ad551f5ff8c550d388251c9555882d9beb5d Mon Sep 17 00:00:00 2001
+From: Wolfgang Bumiller <w.bumiller@proxmox.com>
+Date: Tue, 19 Sep 2017 14:20:28 +0200
+Subject: [PATCH 14/14] virtio: fix descriptor counting in virtqueue_pop
+
+While changing the s/g list allocation, commit 3b3b0628
+also changed the descriptor counting to count iovec entries
+as split by cpu_physical_memory_map(). Previously only the
+actual descriptor entries were counted and the split into
+the iovec happened afterwards in virtqueue_map().
+Count the entries again instead to avoid erroneous
+"Looped descriptor" errors.
+
+Reported-by: Hans Middelhoek <h.middelhoek@ospito.nl>
+Link: https://forum.proxmox.com/threads/vm-crash-with-memory-hotplug.35904/
+Fixes: 3b3b0628217e ("virtio: slim down allocation of VirtQueueElements")
+Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
+---
+ hw/virtio/virtio.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
+index 890b4d7eb7..33bb770177 100644
+--- a/hw/virtio/virtio.c
++++ b/hw/virtio/virtio.c
+@@ -834,7 +834,7 @@ void *virtqueue_pop(VirtQueue *vq, size_t sz)
+     int64_t len;
+     VirtIODevice *vdev = vq->vdev;
+     VirtQueueElement *elem = NULL;
+-    unsigned out_num, in_num;
++    unsigned out_num, in_num, elem_entries;
+     hwaddr addr[VIRTQUEUE_MAX_SIZE];
+     struct iovec iov[VIRTQUEUE_MAX_SIZE];
+     VRingDesc desc;
+@@ -852,7 +852,7 @@ void *virtqueue_pop(VirtQueue *vq, size_t sz)
+     smp_rmb();
+     /* When we start there are none of either input nor output. */
+-    out_num = in_num = 0;
++    out_num = in_num = elem_entries = 0;
+     max = vq->vring.num;
+@@ -922,7 +922,7 @@ void *virtqueue_pop(VirtQueue *vq, size_t sz)
+         }
+         /* If we've got too many, that implies a descriptor loop. */
+-        if ((in_num + out_num) > max) {
++        if (++elem_entries > max) {
+             virtio_error(vdev, "Looped descriptor");
+             goto err_undo_map;
+         }
+-- 
+2.11.0
+
index 6de3a9321dec62fd3b15475a2f0ceb5c19164b89..b4c21c8a3bc91c5ab11d91fd5ca23078d83cf6c7 100644 (file)
@@ -39,3 +39,4 @@ extra/0010-vga-fix-display-update-region-calculation.patch
 extra/0011-vga-fix-display-update-region-calculation-split-scre.patch
 extra/0012-vga-stop-passing-pointers-to-vga_draw_line-functions.patch
 extra/0013-multiboot-validate-multiboot-header-address-values.patch
+extra/0014-virtio-fix-descriptor-counting-in-virtqueue_pop.patch