From patchwork Fri Sep 27 18:37:57 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adrian Moreno X-Patchwork-Id: 60057 X-Patchwork-Delegate: maxime.coquelin@redhat.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 2F51D1BEF7; Fri, 27 Sep 2019 20:38:23 +0200 (CEST) Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by dpdk.org (Postfix) with ESMTP id CE9101BEDA; Fri, 27 Sep 2019 20:38:19 +0200 (CEST) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 24CA0E8CDA; Fri, 27 Sep 2019 18:38:19 +0000 (UTC) Received: from amorenoz.users.ipa.redhat.com (ovpn-116-96.ams2.redhat.com [10.36.116.96]) by smtp.corp.redhat.com (Postfix) with ESMTP id 9983A5C21A; Fri, 27 Sep 2019 18:38:17 +0000 (UTC) From: Adrian Moreno To: dev@dpdk.org Cc: tiwei.bie@intel.com, zhihong.wang@intel.com, maxime.coquelin@redhat.com, Adrian Moreno , stable@dpdk.org Date: Fri, 27 Sep 2019 20:37:57 +0200 Message-Id: <20190927183759.18816-2-amorenoz@redhat.com> In-Reply-To: <20190927183759.18816-1-amorenoz@redhat.com> References: <20190927183759.18816-1-amorenoz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.38]); Fri, 27 Sep 2019 18:38:19 +0000 (UTC) Subject: [dpdk-dev] [PATCH v3 1/3] vhost: translate incoming log address to gpa X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" When IOMMU is enabled the incoming log address is in IOVA space. In that case, look in IOTLB table and translate the resulting HVA to GPA. If IOMMU is not enabled, the incoming log address is already a GPA so no transformation is needed. Fixes: 69c90e98f483 ("vhost: enable IOMMU support") Cc: maxime.coquelin@redhat.com Cc: stable@dpdk.org Signed-off-by: Adrian Moreno --- lib/librte_vhost/vhost.c | 1 + lib/librte_vhost/vhost.h | 20 ++++++++++++++++ lib/librte_vhost/vhost_user.c | 44 ++++++++++++++++++++++++++++++++++- 3 files changed, 64 insertions(+), 1 deletion(-) diff --git a/lib/librte_vhost/vhost.c b/lib/librte_vhost/vhost.c index 981837b5d..e57dda22f 100644 --- a/lib/librte_vhost/vhost.c +++ b/lib/librte_vhost/vhost.c @@ -383,6 +383,7 @@ vring_invalidate(struct virtio_net *dev, struct vhost_virtqueue *vq) vq->desc = NULL; vq->avail = NULL; vq->used = NULL; + vq->log_guest_addr = 0; if (dev->features & (1ULL << VIRTIO_F_IOMMU_PLATFORM)) vhost_user_iotlb_wr_unlock(vq); diff --git a/lib/librte_vhost/vhost.h b/lib/librte_vhost/vhost.h index 884befa85..9d3883385 100644 --- a/lib/librte_vhost/vhost.h +++ b/lib/librte_vhost/vhost.h @@ -447,6 +447,26 @@ gpa_to_hpa(struct virtio_net *dev, uint64_t gpa, uint64_t size) return 0; } +static __rte_always_inline uint64_t +hva_to_gpa(struct virtio_net *dev, uint64_t vva, uint64_t len) +{ + struct rte_vhost_mem_region *r; + uint32_t i; + + if (unlikely(!dev || !dev->mem)) + return 0; + + for (i = 0; i < dev->mem->nregions; i++) { + r = &dev->mem->regions[i]; + + if (vva >= r->host_user_addr && + vva + len < r->host_user_addr + r->size) { + return r->guest_phys_addr + vva - r->host_user_addr; + } + } + return 0; +} + static __rte_always_inline struct virtio_net * get_device(int vid) { diff --git a/lib/librte_vhost/vhost_user.c b/lib/librte_vhost/vhost_user.c index 0b72648a5..fec448ea2 100644 --- a/lib/librte_vhost/vhost_user.c +++ b/lib/librte_vhost/vhost_user.c @@ -570,6 +570,40 @@ ring_addr_to_vva(struct virtio_net *dev, struct vhost_virtqueue *vq, return qva_to_vva(dev, ra, size); } +/* + * Converts vring log address to GPA + * If IOMMU is enabled, the log address is IOVA + * If IOMMU not enabled, the log address is already GPA + */ +static uint64_t +translate_log_addr(struct virtio_net *dev, struct vhost_virtqueue *vq, + uint64_t log_addr) +{ + if (dev->features & (1ULL << VIRTIO_F_IOMMU_PLATFORM)) { + const uint64_t exp_size = sizeof(struct vring_used) + + sizeof(struct vring_used_elem) * vq->size; + uint64_t hva, gpa; + uint64_t size = exp_size; + + hva = vhost_iova_to_vva(dev, vq, log_addr, + &size, VHOST_ACCESS_RW); + if (size != exp_size) + return 0; + + gpa = hva_to_gpa(dev, hva, exp_size); + if (!gpa) { + RTE_LOG(ERR, VHOST_CONFIG, + "VQ: Failed to find GPA mapping for log_addr." + "log_addr: 0x%0lx hva: 0x%0lx\n", + log_addr, hva); + return 0; + } + return gpa; + + } else + return log_addr; +} + static struct virtio_net * translate_ring_addresses(struct virtio_net *dev, int vq_index) { @@ -676,7 +710,15 @@ translate_ring_addresses(struct virtio_net *dev, int vq_index) vq->last_avail_idx = vq->used->idx; } - vq->log_guest_addr = addr->log_guest_addr; + vq->log_guest_addr = + translate_log_addr(dev, vq, addr->log_guest_addr); + if (vq->log_guest_addr == 0) { + RTE_LOG(DEBUG, VHOST_CONFIG, + "(%d) failed to map log_guest_addr .\n", + dev->vid); + return dev; + } + VHOST_LOG_DEBUG(VHOST_CONFIG, "(%d) mapped address desc: %p\n", dev->vid, vq->desc);