Commit 37ef70be authored by Wolfgang Bumiller's avatar Wolfgang Bumiller Committed by Michael S. Tsirkin
Browse files

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: default avatarHans Middelhoek <h.middelhoek@ospito.nl>
Link: https://forum.proxmox.com/threads/vm-crash-with-memory-hotplug.35904/


Fixes: 3b3b0628 ("virtio: slim down allocation of VirtQueueElements")
Signed-off-by: default avatarWolfgang Bumiller <w.bumiller@proxmox.com>
Reviewed-by: default avatarMichael S. Tsirkin <mst@redhat.com>
Signed-off-by: default avatarMichael S. Tsirkin <mst@redhat.com>
parent 8e36c336
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -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;
        }