619821
From 6b2d5dafa9847ce29e5cddeb369b35db5ce076b1 Mon Sep 17 00:00:00 2001
4f5da8
From: Ladi Prosek <lprosek@redhat.com>
4f5da8
Date: Thu, 10 Nov 2016 23:00:50 +0100
4f5da8
Subject: [PATCH 7/8] virtio: add virtqueue_rewind()
4f5da8
4f5da8
RH-Author: Ladi Prosek <lprosek@redhat.com>
4f5da8
Message-id: <1478797251-10302-1-git-send-email-lprosek@redhat.com>
4f5da8
Patchwork-id: 72818
4f5da8
O-Subject: [PATCH v2 7/6] virtio: add virtqueue_rewind()
619821
Bugzilla: 1377968
4f5da8
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
4f5da8
RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
4f5da8
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
4f5da8
4f5da8
From: Stefan Hajnoczi <stefanha@redhat.com>
4f5da8
4f5da8
virtqueue_discard() requires a VirtQueueElement but virtio-balloon does
4f5da8
not migrate its in-use element.  Introduce a new function that is
4f5da8
similar to virtqueue_discard() but doesn't require a VirtQueueElement.
4f5da8
4f5da8
This will allow virtio-balloon to access element again after migration
4f5da8
with the usual proviso that the guest may have modified the vring since
4f5da8
last time.
4f5da8
4f5da8
Cc: Michael S. Tsirkin <mst@redhat.com>
4f5da8
Cc: Roman Kagan <rkagan@virtuozzo.com>
4f5da8
Cc: Stefan Hajnoczi <stefanha@redhat.com>
4f5da8
Signed-off-by: Ladi Prosek <lprosek@redhat.com>
4f5da8
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
4f5da8
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
4f5da8
(cherry picked from commit 297a75e6c55d91db2704a3d6e4029d99c7df51fd)
4f5da8
Signed-off-by: Ladi Prosek <lprosek@redhat.com>
4f5da8
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
4f5da8
---
4f5da8
 hw/virtio/virtio.c         | 22 ++++++++++++++++++++++
4f5da8
 include/hw/virtio/virtio.h |  1 +
4f5da8
 2 files changed, 23 insertions(+)
4f5da8
4f5da8
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
4f5da8
index cdb21b1..fe6b032 100644
4f5da8
--- a/hw/virtio/virtio.c
4f5da8
+++ b/hw/virtio/virtio.c
4f5da8
@@ -259,6 +259,28 @@ void virtqueue_discard(VirtQueue *vq, const VirtQueueElement *elem,
4f5da8
     virtqueue_unmap_sg(vq, elem, len);
4f5da8
 }
4f5da8
 
4f5da8
+/* virtqueue_rewind:
4f5da8
+ * @vq: The #VirtQueue
4f5da8
+ * @num: Number of elements to push back
4f5da8
+ *
4f5da8
+ * Pretend that elements weren't popped from the virtqueue.  The next
4f5da8
+ * virtqueue_pop() will refetch the oldest element.
4f5da8
+ *
4f5da8
+ * Use virtqueue_discard() instead if you have a VirtQueueElement.
4f5da8
+ *
4f5da8
+ * Returns: true on success, false if @num is greater than the number of in use
4f5da8
+ * elements.
4f5da8
+ */
4f5da8
+bool virtqueue_rewind(VirtQueue *vq, unsigned int num)
4f5da8
+{
4f5da8
+    if (num > vq->inuse) {
4f5da8
+        return false;
4f5da8
+    }
4f5da8
+    vq->last_avail_idx -= num;
4f5da8
+    vq->inuse -= num;
4f5da8
+    return true;
4f5da8
+}
4f5da8
+
4f5da8
 void virtqueue_fill(VirtQueue *vq, const VirtQueueElement *elem,
4f5da8
                     unsigned int len, unsigned int idx)
4f5da8
 {
4f5da8
diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
4f5da8
index de32425..d9bfe4c 100644
4f5da8
--- a/include/hw/virtio/virtio.h
4f5da8
+++ b/include/hw/virtio/virtio.h
4f5da8
@@ -167,6 +167,7 @@ void virtqueue_push(VirtQueue *vq, const VirtQueueElement *elem,
4f5da8
 void virtqueue_flush(VirtQueue *vq, unsigned int count);
4f5da8
 void virtqueue_discard(VirtQueue *vq, const VirtQueueElement *elem,
4f5da8
                        unsigned int len);
4f5da8
+bool virtqueue_rewind(VirtQueue *vq, unsigned int num);
4f5da8
 void virtqueue_fill(VirtQueue *vq, const VirtQueueElement *elem,
4f5da8
                     unsigned int len, unsigned int idx);
4f5da8
 
4f5da8
-- 
4f5da8
1.8.3.1
4f5da8