aboutsummaryrefslogtreecommitdiff
path: root/hw/virtio/dataplane/vring.c
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2015-07-08 13:36:19 +0100
committerPeter Maydell <peter.maydell@linaro.org>2015-07-08 13:36:19 +0100
commitc8232b39bb18a91cde39b8e0b60e731a4ce782b1 (patch)
tree8cc13bdc7b677a07edeb762d216e366ca3e0b1eb /hw/virtio/dataplane/vring.c
parent62a3864eb09414d3cee94a2a592ecd414200912f (diff)
parentc4fc82bf1ad088a84ccedf779f6aa928e4fadb5f (diff)
Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into staging
pc,virtio,pci: fixes and updates Most notably, this includes the TCO support for ICH: the last feature for 2.4 as we are entering the hard freeze. Bugfixes only from now on. virtio pci also gained cfg access capability - arguably a bugfix since virtio spec makes it mandatory, but it's a big patch. Signed-off-by: Michael S. Tsirkin <mst@redhat.com> # gpg: Signature made Wed Jul 8 10:40:07 2015 BST using RSA key ID D28D5469 # gpg: Good signature from "Michael S. Tsirkin <mst@kernel.org>" # gpg: aka "Michael S. Tsirkin <mst@redhat.com>" * remotes/mst/tags/for_upstream: tco-test: fix up config accesses and re-enable virtio fix cfg endian-ness for BE targets virtio-pci: implement cfg capability virtio: define virtio_pci_cfg_cap in header. pcie: Set the "link active" in the link status register pci_regs.h: import from linux virtio_net: reuse constants from linux hw/i386/pc: don't carry FDC from pc_basic_device_init() to pc_cmos_init() hw/i386/pc: reflect any FDC @ ioport 0x3f0 in the CMOS hw/i386/pc: factor out pc_cmos_init_floppy() ich9: implement strap SPKR pin logic tests: add testcase for TCO watchdog emulation ich9: add TCO interface emulation acpi: split out ICH ACPI support Revert "dataplane: allow virtio-1 devices" dataplane: fix cross-endian issues Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw/virtio/dataplane/vring.c')
-rw-r--r--hw/virtio/dataplane/vring.c53
1 files changed, 25 insertions, 28 deletions
diff --git a/hw/virtio/dataplane/vring.c b/hw/virtio/dataplane/vring.c
index 35891856ee..07fd69c69e 100644
--- a/hw/virtio/dataplane/vring.c
+++ b/hw/virtio/dataplane/vring.c
@@ -153,22 +153,20 @@ bool vring_should_notify(VirtIODevice *vdev, Vring *vring)
return true;
}
- return vring_need_event(vring_used_event(&vring->vr), new, old);
+ return vring_need_event(virtio_tswap16(vdev, vring_used_event(&vring->vr)),
+ new, old);
}
-static int get_desc(VirtIODevice *vdev, Vring *vring, VirtQueueElement *elem,
+static int get_desc(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 (is_write) {
+ if (desc->flags & VRING_DESC_F_WRITE) {
num = &elem->in_num;
iov = &elem->in_sg[*num];
addr = &elem->in_addr[*num];
@@ -192,17 +190,18 @@ static int get_desc(VirtIODevice *vdev, Vring *vring, VirtQueueElement *elem,
}
/* TODO handle non-contiguous memory across region boundaries */
- iov->iov_base = vring_map(&mr, desc_addr, len, is_write);
+ iov->iov_base = vring_map(&mr, desc->addr, desc->len,
+ desc->flags & VRING_DESC_F_WRITE);
if (!iov->iov_base) {
error_report("Failed to map descriptor addr %#" PRIx64 " len %u",
- (uint64_t)desc_addr, len);
+ (uint64_t)desc->addr, desc->len);
return -EFAULT;
}
/* The MemoryRegion is looked up again and unref'ed later, leave the
* ref in place. */
- iov->iov_len = len;
- *addr = desc_addr;
+ iov->iov_len = desc->len;
+ *addr = desc->addr;
*num += 1;
return 0;
}
@@ -224,23 +223,21 @@ 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(len % sizeof(desc))) {
+ if (unlikely(indirect->len % sizeof(desc))) {
error_report("Invalid length in indirect descriptor: "
"len %#x not multiple of %#zx",
- len, sizeof(desc));
+ indirect->len, sizeof(desc));
vring->broken = true;
return -EFAULT;
}
- count = len / sizeof(desc);
+ count = indirect->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", len);
+ error_report("Indirect buffer length too big: %d", indirect->len);
vring->broken = true;
return -EFAULT;
}
@@ -251,12 +248,12 @@ static int get_indirect(VirtIODevice *vdev, Vring *vring,
/* Translate indirect descriptor */
desc_ptr = vring_map(&mr,
- addr + found * sizeof(desc),
+ indirect->addr + found * sizeof(desc),
sizeof(desc), false);
if (!desc_ptr) {
error_report("Failed to map indirect descriptor "
"addr %#" PRIx64 " len %zu",
- (uint64_t)addr + found * sizeof(desc),
+ (uint64_t)indirect->addr + found * sizeof(desc),
sizeof(desc));
vring->broken = true;
return -EFAULT;
@@ -274,20 +271,19 @@ static int get_indirect(VirtIODevice *vdev, Vring *vring,
return -EFAULT;
}
- if (unlikely(virtio_tswap16(vdev, desc.flags)
- & VRING_DESC_F_INDIRECT)) {
+ if (unlikely(desc.flags & VRING_DESC_F_INDIRECT)) {
error_report("Nested indirect descriptor");
vring->broken = true;
return -EFAULT;
}
- ret = get_desc(vdev, vring, elem, &desc);
+ ret = get_desc(vring, elem, &desc);
if (ret < 0) {
vring->broken |= (ret == -EFAULT);
return ret;
}
- i = virtio_tswap16(vdev, desc.next);
- } while (virtio_tswap16(vdev, desc.flags) & VRING_DESC_F_NEXT);
+ i = desc.next;
+ } while (desc.flags & VRING_DESC_F_NEXT);
return 0;
}
@@ -388,7 +384,7 @@ int vring_pop(VirtIODevice *vdev, Vring *vring,
/* Ensure descriptor is loaded before accessing fields */
barrier();
- if (virtio_tswap16(vdev, desc.flags) & VRING_DESC_F_INDIRECT) {
+ if (desc.flags & VRING_DESC_F_INDIRECT) {
ret = get_indirect(vdev, vring, elem, &desc);
if (ret < 0) {
goto out;
@@ -396,18 +392,19 @@ int vring_pop(VirtIODevice *vdev, Vring *vring,
continue;
}
- ret = get_desc(vdev, vring, elem, &desc);
+ ret = get_desc(vring, elem, &desc);
if (ret < 0) {
goto out;
}
- i = virtio_tswap16(vdev, desc.next);
- } while (virtio_tswap16(vdev, desc.flags) & VRING_DESC_F_NEXT);
+ i = desc.next;
+ } while (desc.flags & VRING_DESC_F_NEXT);
/* On success, increment avail index. */
vring->last_avail_idx++;
if (virtio_has_feature(vdev, VIRTIO_RING_F_EVENT_IDX)) {
- vring_avail_event(&vring->vr) = vring->last_avail_idx;
+ vring_avail_event(&vring->vr) =
+ virtio_tswap16(vdev, vring->last_avail_idx);
}
return head;