qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH RFC] virtio: add virtqueue_fill_partial


From: Michael S. Tsirkin
Subject: [Qemu-devel] [PATCH RFC] virtio: add virtqueue_fill_partial
Date: Mon, 27 Apr 2015 16:18:36 +0200

On error, virtio blk dirties guest memory but doesn't want to tell guest
about it. Add virtqueue_fill_partial to cover this use case.  This gets
two parameters: host_len is >= the amount of guest memory actually
written, guest_len is how much we guarantee to guest.

Cc: Paolo Bonzini <address@hidden>
Signed-off-by: Michael S. Tsirkin <address@hidden>
---
 include/hw/virtio/virtio.h |  3 +++
 hw/virtio/virtio.c         | 25 ++++++++++++++++++++-----
 2 files changed, 23 insertions(+), 5 deletions(-)

diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
index e3adb1d..9957aae 100644
--- a/include/hw/virtio/virtio.h
+++ b/include/hw/virtio/virtio.h
@@ -135,6 +135,9 @@ void virtio_del_queue(VirtIODevice *vdev, int n);
 void virtqueue_push(VirtQueue *vq, const VirtQueueElement *elem,
                     unsigned int len);
 void virtqueue_flush(VirtQueue *vq, unsigned int count);
+void virtqueue_fill_partial(VirtQueue *vq, const VirtQueueElement *elem,
+                            unsigned int host_len, unsigned int guest_len,
+                            unsigned int idx);
 void virtqueue_fill(VirtQueue *vq, const VirtQueueElement *elem,
                     unsigned int len, unsigned int idx);
 
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index 159e5c6..111b0db 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -241,17 +241,26 @@ int virtio_queue_empty(VirtQueue *vq)
     return vring_avail_idx(vq) == vq->last_avail_idx;
 }
 
-void virtqueue_fill(VirtQueue *vq, const VirtQueueElement *elem,
-                    unsigned int len, unsigned int idx)
+/*
+ * Some devices dirty guest memory but don't want to tell guest about it. In
+ * that case, use virtqueue_fill_partial: host_len is >= the amount of guest
+ * memory actually written, guest_len is how much we guarantee to guest.
+ * If you know exactly how much was written, use virtqueue_fill instead.
+ */
+void virtqueue_fill_partial(VirtQueue *vq, const VirtQueueElement *elem,
+                            unsigned int host_len, unsigned int guest_len,
+                            unsigned int idx)
 {
     unsigned int offset;
     int i;
 
-    trace_virtqueue_fill(vq, elem, len, idx);
+    assert(host_len >= guest_len);
+
+    trace_virtqueue_fill(vq, elem, guest_len, idx);
 
     offset = 0;
     for (i = 0; i < elem->in_num; i++) {
-        size_t size = MIN(len - offset, elem->in_sg[i].iov_len);
+        size_t size = MIN(host_len - offset, elem->in_sg[i].iov_len);
 
         cpu_physical_memory_unmap(elem->in_sg[i].iov_base,
                                   elem->in_sg[i].iov_len,
@@ -269,7 +278,13 @@ void virtqueue_fill(VirtQueue *vq, const VirtQueueElement 
*elem,
 
     /* Get a pointer to the next entry in the used ring. */
     vring_used_ring_id(vq, idx, elem->index);
-    vring_used_ring_len(vq, idx, len);
+    vring_used_ring_len(vq, idx, guest_len);
+}
+
+void virtqueue_fill(VirtQueue *vq, const VirtQueueElement *elem,
+                    unsigned int len, unsigned int idx)
+{
+    virtqueue_fill_partial(vq, elem, len, len, idx);
 }
 
 void virtqueue_flush(VirtQueue *vq, unsigned int count)
-- 
MST



reply via email to

[Prev in Thread] Current Thread [Next in Thread]