virtio-pci: fix virtio_pci_queue_enabled()
authorLaurent Vivier <lvivier@redhat.com>
Mon, 27 Jul 2020 15:33:19 +0000 (17:33 +0200)
committerMichael S. Tsirkin <mst@redhat.com>
Mon, 27 Jul 2020 15:34:50 +0000 (11:34 -0400)
commit0c9753ebda274b0e618d7b4032bb2d83d27483ed
treee289473b00bdbc7c56e248e640c09fdbfb2927e2
parentd0d89526f70ded5ac41a4c6bb071c0d919b772db
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: f19bcdfedd53 ("virtio-pci: implement queue_enabled method")
Cc: Jason Wang <jasowang@redhat.com>
Cc: Cindy Lu <lulu@redhat.com>
CC: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Laurent Vivier <lvivier@redhat.com>
Message-Id: <20200727153319.43716-1-lvivier@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
hw/virtio/virtio-pci.c
hw/virtio/virtio.c
include/hw/virtio/virtio.h