aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHalil Pasic <pasic@linux.vnet.ibm.com>2016-12-19 16:44:44 +0100
committerMichael S. Tsirkin <mst@redhat.com>2017-01-10 07:02:52 +0200
commite66bcc408146730958d1a840bda85d7ad51e0cd7 (patch)
tree9e56c94da535bddfc600bd5e8b3cbadd9a6bc040
parentf18c697b55d1374af67b84c581abaece8ab2aca3 (diff)
virtio: fix vq->inuse recalc after migr
Correct recalculation of vq->inuse after migration for the corner case where the avail_idx has already wrapped but used_idx not yet. Also change the type of the VirtQueue.inuse to unsigned int. This is done to be consistent with other members representing sizes (VRing.num), and because C99 guarantees max ring size < UINT_MAX but does not guarantee max ring size < INT_MAX. Signed-off-by: Halil Pasic <pasic@linux.vnet.ibm.com> Fixes: bccdef6b ("virtio: recalculate vq->inuse after migration") CC: qemu-stable@nongnu.org Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com> Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
-rw-r--r--hw/virtio/virtio.c8
1 files changed, 5 insertions, 3 deletions
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index 933a3d749a..8357218ae6 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -93,7 +93,7 @@ struct VirtQueue
uint16_t queue_index;
- int inuse;
+ unsigned int inuse;
uint16_t vector;
VirtIOHandleOutput handle_output;
@@ -1878,9 +1878,11 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id)
/*
* Some devices migrate VirtQueueElements that have been popped
* from the avail ring but not yet returned to the used ring.
+ * Since max ring size < UINT16_MAX it's safe to use modulo
+ * UINT16_MAX + 1 subtraction.
*/
- vdev->vq[i].inuse = vdev->vq[i].last_avail_idx -
- vdev->vq[i].used_idx;
+ vdev->vq[i].inuse = (uint16_t)(vdev->vq[i].last_avail_idx -
+ vdev->vq[i].used_idx);
if (vdev->vq[i].inuse > vdev->vq[i].vring.num) {
error_report("VQ %d size 0x%x < last_avail_idx 0x%x - "
"used_idx 0x%x",