All these errors are caused by a buggy guest: let's switch the device to the broken state instead of terminating QEMU. Also we detach the element from the virtqueue and free it.
Signed-off-by: Greg Kurz <gr...@kaod.org> Reviewed-by: Cornelia Huck <cornelia.h...@de.ibm.com> Reviewed-by: Stefan Hajnoczi <stefa...@redhat.com> --- v4: - added Stefan's R-b tag --- hw/net/virtio-net.c | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c index 2c02ba8a70a4..10a4c745f0bd 100644 --- a/hw/net/virtio-net.c +++ b/hw/net/virtio-net.c @@ -1125,21 +1125,24 @@ static ssize_t virtio_net_receive(NetClientState *nc, const uint8_t *buf, size_t elem = virtqueue_pop(q->rx_vq, sizeof(VirtQueueElement)); if (!elem) { - if (i == 0) - return -1; - error_report("virtio-net unexpected empty queue: " - "i %zd mergeable %d offset %zd, size %zd, " - "guest hdr len %zd, host hdr len %zd " - "guest features 0x%" PRIx64, - i, n->mergeable_rx_bufs, offset, size, - n->guest_hdr_len, n->host_hdr_len, - vdev->guest_features); - exit(1); + if (i) { + virtio_error(vdev, "virtio-net unexpected empty queue: " + "i %zd mergeable %d offset %zd, size %zd, " + "guest hdr len %zd, host hdr len %zd " + "guest features 0x%" PRIx64, + i, n->mergeable_rx_bufs, offset, size, + n->guest_hdr_len, n->host_hdr_len, + vdev->guest_features); + } + return -1; } if (elem->in_num < 1) { - error_report("virtio-net receive queue contains no in buffers"); - exit(1); + virtio_error(vdev, + "virtio-net receive queue contains no in buffers"); + virtqueue_detach_element(q->rx_vq, elem, 0); + g_free(elem); + return -1; } sg = elem->in_sg;