On stopping the vhost, a call to VHOST_GET_VRING_BASE is issued. The received value is stored as last_avail_idx, so the virtqueue can continue operating if the connection is resumed. Handle the failure of this call and use the current avail_idx. Some packets from the avail ring may be omitted but still we keep a sane value and can continue on reconnect.
Signed-off-by: Antonios Motakis <a.mota...@virtualopensystems.com> Signed-off-by: Nikolay Nikolaev <n.nikol...@virtualopensystems.com> --- hw/virtio/vhost.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c index 9e336ad..322e2c0 100644 --- a/hw/virtio/vhost.c +++ b/hw/virtio/vhost.c @@ -758,12 +758,13 @@ static void vhost_virtqueue_stop(struct vhost_dev *dev, assert(idx >= dev->vq_index && idx < dev->vq_index + dev->nvqs); r = ioctl(dev->control, VHOST_GET_VRING_BASE, &state); if (r < 0) { + state.num = virtio_queue_get_avail_idx(vdev, idx); fprintf(stderr, "vhost VQ %d ring restore failed: %d\n", idx, r); fflush(stderr); } virtio_queue_set_last_avail_idx(vdev, idx, state.num); virtio_queue_invalidate_signalled_used(vdev, idx); - assert (r >= 0); + cpu_physical_memory_unmap(vq->ring, virtio_queue_get_ring_size(vdev, idx), 0, virtio_queue_get_ring_size(vdev, idx)); cpu_physical_memory_unmap(vq->used, virtio_queue_get_used_size(vdev, idx), -- 1.8.3.2