[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
- [Qemu-devel] [PATCH RFC] virtio: add virtqueue_fill_partial,
Michael S. Tsirkin <=