]>
Commit | Line | Data |
---|---|---|
3dcc8d3b | 1 | From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
fb8b489c | 2 | From: Wolfgang Bumiller <w.bumiller@proxmox.com> |
c53dfb57 | 3 | Date: Wed, 20 Sep 2017 08:09:33 +0200 |
3dcc8d3b | 4 | Subject: [PATCH] virtio: fix descriptor counting in virtqueue_pop |
fb8b489c WB |
5 | |
6 | While changing the s/g list allocation, commit 3b3b0628 | |
7 | also changed the descriptor counting to count iovec entries | |
8 | as split by cpu_physical_memory_map(). Previously only the | |
9 | actual descriptor entries were counted and the split into | |
10 | the iovec happened afterwards in virtqueue_map(). | |
11 | Count the entries again instead to avoid erroneous | |
12 | "Looped descriptor" errors. | |
13 | ||
14 | Reported-by: Hans Middelhoek <h.middelhoek@ospito.nl> | |
15 | Link: https://forum.proxmox.com/threads/vm-crash-with-memory-hotplug.35904/ | |
16 | Fixes: 3b3b0628217e ("virtio: slim down allocation of VirtQueueElements") | |
17 | Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com> | |
c53dfb57 WB |
18 | Reviewed-by: Michael S. Tsirkin <mst@redhat.com> |
19 | Signed-off-by: Michael S. Tsirkin <mst@redhat.com> | |
fb8b489c WB |
20 | --- |
21 | hw/virtio/virtio.c | 6 +++--- | |
22 | 1 file changed, 3 insertions(+), 3 deletions(-) | |
23 | ||
24 | diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c | |
25 | index 890b4d7eb7..33bb770177 100644 | |
26 | --- a/hw/virtio/virtio.c | |
27 | +++ b/hw/virtio/virtio.c | |
28 | @@ -834,7 +834,7 @@ void *virtqueue_pop(VirtQueue *vq, size_t sz) | |
29 | int64_t len; | |
30 | VirtIODevice *vdev = vq->vdev; | |
31 | VirtQueueElement *elem = NULL; | |
32 | - unsigned out_num, in_num; | |
33 | + unsigned out_num, in_num, elem_entries; | |
34 | hwaddr addr[VIRTQUEUE_MAX_SIZE]; | |
35 | struct iovec iov[VIRTQUEUE_MAX_SIZE]; | |
36 | VRingDesc desc; | |
37 | @@ -852,7 +852,7 @@ void *virtqueue_pop(VirtQueue *vq, size_t sz) | |
38 | smp_rmb(); | |
39 | ||
40 | /* When we start there are none of either input nor output. */ | |
41 | - out_num = in_num = 0; | |
42 | + out_num = in_num = elem_entries = 0; | |
43 | ||
44 | max = vq->vring.num; | |
45 | ||
46 | @@ -922,7 +922,7 @@ void *virtqueue_pop(VirtQueue *vq, size_t sz) | |
47 | } | |
48 | ||
49 | /* If we've got too many, that implies a descriptor loop. */ | |
50 | - if ((in_num + out_num) > max) { | |
51 | + if (++elem_entries > max) { | |
52 | virtio_error(vdev, "Looped descriptor"); | |
53 | goto err_undo_map; | |
54 | } | |
55 | -- | |
56 | 2.11.0 | |
57 |