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