]> git.ipfire.org Git - thirdparty/qemu.git/commit
hw/virtio: Fix packed virtqueue flush used_idx
authorWafer <wafer@jaguarmicro.com>
Sun, 7 Apr 2024 01:54:51 +0000 (09:54 +0800)
committerMichael Tokarev <mjt@tls.msk.ru>
Tue, 9 Apr 2024 17:39:50 +0000 (20:39 +0300)
commitfd01f5a847b4ffbe1b606f7efe0137b25c106a23
tree0fbe8d723e90e1304de2efae9ba15f83e20d712d
parent227d9450b557bc5c0487fd365c44de89c5d54fc6
hw/virtio: Fix packed virtqueue flush used_idx

In the event of writing many chains of descriptors, the device must
write just the id of the last buffer in the descriptor chain, skip
forward the number of descriptors in the chain, and then repeat the
operations for the rest of chains.

Current QEMU code writes all the buffer ids consecutively, and then
skips all the buffers altogether. This is a bug, and can be reproduced
with a VirtIONet device with _F_MRG_RXBUB and without
_F_INDIRECT_DESC:

If a virtio-net device has the VIRTIO_NET_F_MRG_RXBUF feature
but not the VIRTIO_RING_F_INDIRECT_DESC feature,
'VirtIONetQueue->rx_vq' will use the merge feature
to store data in multiple 'elems'.
The 'num_buffers' in the virtio header indicates how many elements are merged.
If the value of 'num_buffers' is greater than 1,
all the merged elements will be filled into the descriptor ring.
The 'idx' of the elements should be the value of 'vq->used_idx' plus 'ndescs'.

Fixes: 86044b24e8 ("virtio: basic packed virtqueue support")
Acked-by: Eugenio Pérez <eperezma@redhat.com>
Signed-off-by: Wafer <wafer@jaguarmicro.com>
Message-Id: <20240407015451.5228-2-wafer@jaguarmicro.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit 2d9a31b3c27311eca1682cb2c076d7a300441960)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
hw/virtio/virtio.c