From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mx1.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) by dpdk.org (Postfix) with ESMTP id 02F714F9A for ; Mon, 23 Apr 2018 17:59:45 +0200 (CEST) Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.rdu2.redhat.com [10.11.54.4]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 671BAE44B5 for ; Mon, 23 Apr 2018 15:59:44 +0000 (UTC) Received: from localhost.localdomain (ovpn-112-58.ams2.redhat.com [10.36.112.58]) by smtp.corp.redhat.com (Postfix) with ESMTP id B0C182026DFD; Mon, 23 Apr 2018 15:59:43 +0000 (UTC) From: Maxime Coquelin To: stable@dpdk.org Cc: Maxime Coquelin Date: Mon, 23 Apr 2018 17:59:14 +0200 Message-Id: <20180423155918.21350-3-maxime.coquelin@redhat.com> In-Reply-To: <20180423155918.21350-1-maxime.coquelin@redhat.com> References: <20180423155918.21350-1-maxime.coquelin@redhat.com> X-Scanned-By: MIMEDefang 2.78 on 10.11.54.4 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.1]); Mon, 23 Apr 2018 15:59:44 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.1]); Mon, 23 Apr 2018 15:59:44 +0000 (UTC) for IP:'10.11.54.4' DOMAIN:'int-mx04.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'maxime.coquelin@redhat.com' RCPT:'' Subject: [dpdk-stable] [PATCH v16.11 LTS 2/6] vhost: ensure all range is mapped when translating QVAs X-BeenThere: stable@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches for DPDK stable branches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 23 Apr 2018 15:59:45 -0000 This patch ensures that all the address range is mapped when translating addresses from master's addresses (e.g. QEMU host addressess) to process VAs. Signed-off-by: Maxime Coquelin --- lib/librte_vhost/vhost_user.c | 41 +++++++++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/lib/librte_vhost/vhost_user.c b/lib/librte_vhost/vhost_user.c index 94a48a4b0..550a1329d 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 (unlikely(*len > r->guest_user_addr + r->size - qva)) + *len = r->guest_user_addr + r->size - qva; - if (qva >= reg->guest_user_addr && - qva < reg->guest_user_addr + reg->size) { - return qva - reg->guest_user_addr + - reg->host_user_addr; + return qva - r->guest_user_addr + + r->host_user_addr; } } + *len = 0; return 0; } @@ -332,6 +337,7 @@ vhost_user_set_vring_addr(struct virtio_net **pdev, { struct vhost_virtqueue *vq; struct virtio_net *dev = *pdev; + uint64_t size, req_size; if (dev->mem == NULL) return -1; @@ -340,11 +346,13 @@ vhost_user_set_vring_addr(struct virtio_net **pdev, 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; } @@ -354,18 +362,23 @@ vhost_user_set_vring_addr(struct virtio_net **pdev, 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); -- 2.14.3