aboutsummaryrefslogtreecommitdiff
path: root/include/hw/virtio
diff options
context:
space:
mode:
authorMichael S. Tsirkin <mst@redhat.com>2015-10-27 10:01:44 +0200
committerMichael S. Tsirkin <mst@redhat.com>2015-10-29 11:05:24 +0200
commit8059feee004111534c4c0652e2f0715e9b4e0754 (patch)
tree2da88fa4471492aa2abdb8e83915c5a8cda29b1f /include/hw/virtio
parent9d4ec9370a36f8a564e1ba05519328c0bd60da13 (diff)
virtio: introduce virtio_map
virtio_map_sg currently fails if one of the entries it's mapping is contigious in GPA but not HVA address space. Introduce virtio_map which handles this by splitting sg entries. This new API generally turns out to be a good idea since it's harder to misuse: at least in one case the existing one was used incorrectly. This will still fail if there's no space left in the sg, but luckily max queue size in use is currently 256, while max sg size is 1024, so we should be OK even is all entries happen to cross a single DIMM boundary. Won't work well with very small DIMM sizes, unfortunately: e.g. this will fail with 4K DIMMs where a single request might span a large number of DIMMs. Let's hope these are uncommon - at least we are not breaking things. Note: virtio-scsi calls virtio_map_sg on data loaded from network, and validates input, asserting on failure. Copy the validating code here - it will be dropped from virtio-scsi in a follow-up patch. Reported-by: Igor Mammedov <imammedo@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com> Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> Reviewed-by: Igor Mammedov <imammedo@redhat.com>
Diffstat (limited to 'include/hw/virtio')
-rw-r--r--include/hw/virtio/virtio.h1
1 files changed, 1 insertions, 0 deletions
diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
index 9d09115fab..9d9abb4689 100644
--- a/include/hw/virtio/virtio.h
+++ b/include/hw/virtio/virtio.h
@@ -153,6 +153,7 @@ void virtqueue_fill(VirtQueue *vq, const VirtQueueElement *elem,
void virtqueue_map_sg(struct iovec *sg, hwaddr *addr,
size_t num_sg, int is_write);
+void virtqueue_map(VirtQueueElement *elem);
int virtqueue_pop(VirtQueue *vq, VirtQueueElement *elem);
int virtqueue_avail_bytes(VirtQueue *vq, unsigned int in_bytes,
unsigned int out_bytes);