diff options
author | Luca Boccassi <luca.boccassi@gmail.com> | 2018-04-23 14:17:55 +0100 |
---|---|---|
committer | Luca Boccassi <luca.boccassi@gmail.com> | 2018-04-23 14:18:31 +0100 |
commit | 18af4227fa5eee002b1a79207935620f6112803e (patch) | |
tree | 2478ed36888eb88a9bcd49fd025f86ee9cab2bef /lib/librte_vhost/vhost_user.c | |
parent | 39157ec04095ab012d11db23c462844634bfbb8f (diff) |
New upstream version 16.11.6upstream/16.11.6
Change-Id: I7c0e5e32dc051256867f1db5600e269b4b917106
Signed-off-by: Luca Boccassi <luca.boccassi@gmail.com>
Diffstat (limited to 'lib/librte_vhost/vhost_user.c')
-rw-r--r-- | lib/librte_vhost/vhost_user.c | 49 |
1 files changed, 33 insertions, 16 deletions
diff --git a/lib/librte_vhost/vhost_user.c b/lib/librte_vhost/vhost_user.c index 80348dbf..550a1329 100644 --- a/lib/librte_vhost/vhost_user.c +++ b/lib/librte_vhost/vhost_user.c @@ -303,21 +303,26 @@ numa_realloc(struct virtio_net *dev, int index __rte_unused) * used to convert the ring addresses to our address space. */ static uint64_t -qva_to_vva(struct virtio_net *dev, uint64_t qva) +qva_to_vva(struct virtio_net *dev, uint64_t qva, uint64_t *len) { - struct virtio_memory_region *reg; + struct virtio_memory_region *r; uint32_t i; /* Find the region where the address lives. */ for (i = 0; i < dev->mem->nregions; i++) { - reg = &dev->mem->regions[i]; + r = &dev->mem->regions[i]; + + if (qva >= r->guest_user_addr && + qva < r->guest_user_addr + r->size) { - if (qva >= reg->guest_user_addr && - qva < reg->guest_user_addr + reg->size) { - return qva - reg->guest_user_addr + - reg->host_user_addr; + if (unlikely(*len > r->guest_user_addr + r->size - qva)) + *len = r->guest_user_addr + r->size - qva; + + return qva - r->guest_user_addr + + r->host_user_addr; } } + *len = 0; return 0; } @@ -327,9 +332,12 @@ qva_to_vva(struct virtio_net *dev, uint64_t qva) * This function then converts these to our address space. */ static int -vhost_user_set_vring_addr(struct virtio_net *dev, struct vhost_vring_addr *addr) +vhost_user_set_vring_addr(struct virtio_net **pdev, + struct vhost_vring_addr *addr) { struct vhost_virtqueue *vq; + struct virtio_net *dev = *pdev; + uint64_t size, req_size; if (dev->mem == NULL) return -1; @@ -338,30 +346,39 @@ vhost_user_set_vring_addr(struct virtio_net *dev, struct vhost_vring_addr *addr) vq = dev->virtqueue[addr->index]; /* The addresses are converted from QEMU virtual to Vhost virtual. */ + req_size = sizeof(struct vring_desc) * vq->size; + size = req_size; vq->desc = (struct vring_desc *)(uintptr_t)qva_to_vva(dev, - addr->desc_user_addr); - if (vq->desc == 0) { + addr->desc_user_addr, &size); + if (vq->desc == 0 || size != req_size) { RTE_LOG(ERR, VHOST_CONFIG, - "(%d) failed to find desc ring address.\n", + "(%d) failed to map desc ring address.\n", dev->vid); return -1; } dev = numa_realloc(dev, addr->index); + *pdev = dev; + vq = dev->virtqueue[addr->index]; + req_size = sizeof(struct vring_avail) + sizeof(uint16_t) * vq->size; + size = req_size; vq->avail = (struct vring_avail *)(uintptr_t)qva_to_vva(dev, - addr->avail_user_addr); - if (vq->avail == 0) { + addr->avail_user_addr, &size); + if (vq->avail == 0 || size != req_size) { RTE_LOG(ERR, VHOST_CONFIG, "(%d) failed to find avail ring address.\n", dev->vid); return -1; } + req_size = sizeof(struct vring_used); + req_size += sizeof(struct vring_used_elem) * vq->size; + size = req_size; vq->used = (struct vring_used *)(uintptr_t)qva_to_vva(dev, - addr->used_user_addr); - if (vq->used == 0) { + addr->used_user_addr, &size); + if (vq->used == 0 || size != req_size) { RTE_LOG(ERR, VHOST_CONFIG, "(%d) failed to find used ring address.\n", dev->vid); @@ -1092,7 +1109,7 @@ vhost_user_msg_handler(int vid, int fd) vhost_user_set_vring_num(dev, &msg.payload.state); break; case VHOST_USER_SET_VRING_ADDR: - vhost_user_set_vring_addr(dev, &msg.payload.addr); + vhost_user_set_vring_addr(&dev, &msg.payload.addr); break; case VHOST_USER_SET_VRING_BASE: vhost_user_set_vring_base(dev, &msg.payload.state); |