Skip to content

Commit 0c9753e

Browse files
viviermstsirkin
authored andcommitted
virtio-pci: fix virtio_pci_queue_enabled()
In legacy mode, virtio_pci_queue_enabled() falls back to virtio_queue_enabled() to know if the queue is enabled. But virtio_queue_enabled() calls again virtio_pci_queue_enabled() if k->queue_enabled is set. This ends in a crash after a stack overflow. The problem can be reproduced with "-device virtio-net-pci,disable-legacy=off,disable-modern=true -net tap,vhost=on" And a look to the backtrace is very explicit: ... #4 0x000000010029a438 in virtio_queue_enabled () #5 0x0000000100497a9c in virtio_pci_queue_enabled () ... #130902 0x000000010029a460 in virtio_queue_enabled () #130903 0x0000000100497a9c in virtio_pci_queue_enabled () #130904 0x000000010029a460 in virtio_queue_enabled () #130905 0x0000000100454a20 in vhost_net_start () ... This patch fixes the problem by introducing a new function for the legacy case and calls it from virtio_pci_queue_enabled(). It also calls it from virtio_queue_enabled() to avoid code duplication. Fixes: f19bcdf ("virtio-pci: implement queue_enabled method") Cc: Jason Wang <[email protected]> Cc: Cindy Lu <[email protected]> CC: Michael S. Tsirkin <[email protected]> Signed-off-by: Laurent Vivier <[email protected]> Message-Id: <[email protected]> Reviewed-by: Michael S. Tsirkin <[email protected]> Signed-off-by: Michael S. Tsirkin <[email protected]>
1 parent d0d8952 commit 0c9753e

File tree

3 files changed

+8
-2
lines changed

3 files changed

+8
-2
lines changed

hw/virtio/virtio-pci.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -1116,7 +1116,7 @@ static bool virtio_pci_queue_enabled(DeviceState *d, int n)
11161116
return proxy->vqs[vdev->queue_sel].enabled;
11171117
}
11181118

1119-
return virtio_queue_enabled(vdev, n);
1119+
return virtio_queue_enabled_legacy(vdev, n);
11201120
}
11211121

11221122
static int virtio_pci_add_mem_cap(VirtIOPCIProxy *proxy,

hw/virtio/virtio.c

+6-1
Original file line numberDiff line numberDiff line change
@@ -3309,6 +3309,11 @@ hwaddr virtio_queue_get_desc_addr(VirtIODevice *vdev, int n)
33093309
return vdev->vq[n].vring.desc;
33103310
}
33113311

3312+
bool virtio_queue_enabled_legacy(VirtIODevice *vdev, int n)
3313+
{
3314+
return virtio_queue_get_desc_addr(vdev, n) != 0;
3315+
}
3316+
33123317
bool virtio_queue_enabled(VirtIODevice *vdev, int n)
33133318
{
33143319
BusState *qbus = qdev_get_parent_bus(DEVICE(vdev));
@@ -3317,7 +3322,7 @@ bool virtio_queue_enabled(VirtIODevice *vdev, int n)
33173322
if (k->queue_enabled) {
33183323
return k->queue_enabled(qbus->parent, n);
33193324
}
3320-
return virtio_queue_get_desc_addr(vdev, n) != 0;
3325+
return virtio_queue_enabled_legacy(vdev, n);
33213326
}
33223327

33233328
hwaddr virtio_queue_get_avail_addr(VirtIODevice *vdev, int n)

include/hw/virtio/virtio.h

+1
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,7 @@ typedef struct VirtIORNGConf VirtIORNGConf;
295295
VIRTIO_F_RING_PACKED, false)
296296

297297
hwaddr virtio_queue_get_desc_addr(VirtIODevice *vdev, int n);
298+
bool virtio_queue_enabled_legacy(VirtIODevice *vdev, int n);
298299
bool virtio_queue_enabled(VirtIODevice *vdev, int n);
299300
hwaddr virtio_queue_get_avail_addr(VirtIODevice *vdev, int n);
300301
hwaddr virtio_queue_get_used_addr(VirtIODevice *vdev, int n);

0 commit comments

Comments
 (0)