[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 04/33] dataplane: allow virtio-1 devices
From: |
Gerd Hoffmann |
Subject: |
[Qemu-devel] [PATCH 04/33] dataplane: allow virtio-1 devices |
Date: |
Thu, 4 Jun 2015 12:34:13 +0200 |
From: Cornelia Huck <address@hidden>
Handle endianness conversion for virtio-1 virtqueues correctly.
Note that dataplane now needs to be built per-target.
Signed-off-by: Cornelia Huck <address@hidden>
Reviewed-by: Michael S. Tsirkin <address@hidden>
Signed-off-by: Michael S. Tsirkin <address@hidden>
---
hw/virtio/dataplane/vring.c | 47 +++++++++++++++++++++++++--------------------
1 file changed, 26 insertions(+), 21 deletions(-)
diff --git a/hw/virtio/dataplane/vring.c b/hw/virtio/dataplane/vring.c
index 5c7b8c2..fabb810 100644
--- a/hw/virtio/dataplane/vring.c
+++ b/hw/virtio/dataplane/vring.c
@@ -157,15 +157,18 @@ bool vring_should_notify(VirtIODevice *vdev, Vring *vring)
}
-static int get_desc(Vring *vring, VirtQueueElement *elem,
+static int get_desc(VirtIODevice *vdev, Vring *vring, VirtQueueElement *elem,
struct vring_desc *desc)
{
unsigned *num;
struct iovec *iov;
hwaddr *addr;
MemoryRegion *mr;
+ int is_write = virtio_tswap16(vdev, desc->flags) & VRING_DESC_F_WRITE;
+ uint32_t len = virtio_tswap32(vdev, desc->len);
+ uint64_t desc_addr = virtio_tswap64(vdev, desc->addr);
- if (desc->flags & VRING_DESC_F_WRITE) {
+ if (is_write) {
num = &elem->in_num;
iov = &elem->in_sg[*num];
addr = &elem->in_addr[*num];
@@ -189,18 +192,17 @@ static int get_desc(Vring *vring, VirtQueueElement *elem,
}
/* TODO handle non-contiguous memory across region boundaries */
- iov->iov_base = vring_map(&mr, desc->addr, desc->len,
- desc->flags & VRING_DESC_F_WRITE);
+ iov->iov_base = vring_map(&mr, desc_addr, len, is_write);
if (!iov->iov_base) {
error_report("Failed to map descriptor addr %#" PRIx64 " len %u",
- (uint64_t)desc->addr, desc->len);
+ (uint64_t)desc_addr, len);
return -EFAULT;
}
/* The MemoryRegion is looked up again and unref'ed later, leave the
* ref in place. */
- iov->iov_len = desc->len;
- *addr = desc->addr;
+ iov->iov_len = len;
+ *addr = desc_addr;
*num += 1;
return 0;
}
@@ -222,21 +224,23 @@ static int get_indirect(VirtIODevice *vdev, Vring *vring,
struct vring_desc desc;
unsigned int i = 0, count, found = 0;
int ret;
+ uint32_t len = virtio_tswap32(vdev, indirect->len);
+ uint64_t addr = virtio_tswap64(vdev, indirect->addr);
/* Sanity check */
- if (unlikely(indirect->len % sizeof(desc))) {
+ if (unlikely(len % sizeof(desc))) {
error_report("Invalid length in indirect descriptor: "
"len %#x not multiple of %#zx",
- indirect->len, sizeof(desc));
+ len, sizeof(desc));
vring->broken = true;
return -EFAULT;
}
- count = indirect->len / sizeof(desc);
+ count = len / sizeof(desc);
/* Buffers are chained via a 16 bit next field, so
* we can have at most 2^16 of these. */
if (unlikely(count > USHRT_MAX + 1)) {
- error_report("Indirect buffer length too big: %d", indirect->len);
+ error_report("Indirect buffer length too big: %d", len);
vring->broken = true;
return -EFAULT;
}
@@ -247,12 +251,12 @@ static int get_indirect(VirtIODevice *vdev, Vring *vring,
/* Translate indirect descriptor */
desc_ptr = vring_map(&mr,
- indirect->addr + found * sizeof(desc),
+ addr + found * sizeof(desc),
sizeof(desc), false);
if (!desc_ptr) {
error_report("Failed to map indirect descriptor "
"addr %#" PRIx64 " len %zu",
- (uint64_t)indirect->addr + found * sizeof(desc),
+ (uint64_t)addr + found * sizeof(desc),
sizeof(desc));
vring->broken = true;
return -EFAULT;
@@ -270,19 +274,20 @@ static int get_indirect(VirtIODevice *vdev, Vring *vring,
return -EFAULT;
}
- if (unlikely(desc.flags & VRING_DESC_F_INDIRECT)) {
+ if (unlikely(virtio_tswap16(vdev, desc.flags)
+ & VRING_DESC_F_INDIRECT)) {
error_report("Nested indirect descriptor");
vring->broken = true;
return -EFAULT;
}
- ret = get_desc(vring, elem, &desc);
+ ret = get_desc(vdev, vring, elem, &desc);
if (ret < 0) {
vring->broken |= (ret == -EFAULT);
return ret;
}
- i = desc.next;
- } while (desc.flags & VRING_DESC_F_NEXT);
+ i = virtio_tswap16(vdev, desc.next);
+ } while (virtio_tswap16(vdev, desc.flags) & VRING_DESC_F_NEXT);
return 0;
}
@@ -383,7 +388,7 @@ int vring_pop(VirtIODevice *vdev, Vring *vring,
/* Ensure descriptor is loaded before accessing fields */
barrier();
- if (desc.flags & VRING_DESC_F_INDIRECT) {
+ if (virtio_tswap16(vdev, desc.flags) & VRING_DESC_F_INDIRECT) {
ret = get_indirect(vdev, vring, elem, &desc);
if (ret < 0) {
goto out;
@@ -391,13 +396,13 @@ int vring_pop(VirtIODevice *vdev, Vring *vring,
continue;
}
- ret = get_desc(vring, elem, &desc);
+ ret = get_desc(vdev, vring, elem, &desc);
if (ret < 0) {
goto out;
}
- i = desc.next;
- } while (desc.flags & VRING_DESC_F_NEXT);
+ i = virtio_tswap16(vdev, desc.next);
+ } while (virtio_tswap16(vdev, desc.flags) & VRING_DESC_F_NEXT);
/* On success, increment avail index. */
vring->last_avail_idx++;
--
1.8.3.1
- [Qemu-devel] [PATCH 12/33] linux-headers: add virtio_pci, (continued)
- [Qemu-devel] [PATCH 12/33] linux-headers: add virtio_pci, Gerd Hoffmann, 2015/06/04
- [Qemu-devel] [PATCH 13/33] virtio-pci: initial virtio 1.0 support, Gerd Hoffmann, 2015/06/04
- [Qemu-devel] [PATCH 18/33] virtio-pci: make QEMU_VIRTIO_PCI_QUEUE_MEM_MULT smaller, Gerd Hoffmann, 2015/06/04
- [Qemu-devel] [PATCH 28/33] virtio-pci: move cap type to VirtIOPCIRegion, Gerd Hoffmann, 2015/06/04
- [Qemu-devel] [PATCH 33/33] virtio-input: emulated devices [pci], Gerd Hoffmann, 2015/06/04
- [Qemu-devel] [PATCH 30/33] virtio-pci: fill VirtIOPCIRegions early., Gerd Hoffmann, 2015/06/04
- [Qemu-devel] [PATCH 32/33] virtio-input: core code & base class [pci], Gerd Hoffmann, 2015/06/04
- [Qemu-devel] [PATCH 31/33] pci: add PCI_CLASS_INPUT_*, Gerd Hoffmann, 2015/06/04
- [Qemu-devel] [PATCH 25/33] virtio-pci: add virtio_pci_modern_regions_init(), Gerd Hoffmann, 2015/06/04
- [Qemu-devel] [PATCH 24/33] virtio-pci: add struct VirtIOPCIRegion for virtio-1 regions, Gerd Hoffmann, 2015/06/04
- [Qemu-devel] [PATCH 04/33] dataplane: allow virtio-1 devices,
Gerd Hoffmann <=
- Re: [Qemu-devel] [PATCH 00/33] virtio 1.0 patch series rebased, Michael S. Tsirkin, 2015/06/04
- Re: [Qemu-devel] [PATCH 00/33] virtio 1.0 patch series rebased, Gerd Hoffmann, 2015/06/09
- Re: [Qemu-devel] [PATCH 00/33] virtio 1.0 patch series rebased, Michael S. Tsirkin, 2015/06/10