From patchwork Tue Jul 4 09:49:14 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxime Coquelin X-Patchwork-Id: 26349 X-Patchwork-Delegate: yuanhan.liu@linux.intel.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [IPv6:::1]) by dpdk.org (Postfix) with ESMTP id AA06E7CCD; Tue, 4 Jul 2017 11:50:23 +0200 (CEST) Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by dpdk.org (Postfix) with ESMTP id 0A5B07CCD for ; Tue, 4 Jul 2017 11:50:22 +0200 (CEST) Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 55EBE369C9; Tue, 4 Jul 2017 09:50:21 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 55EBE369C9 Authentication-Results: ext-mx06.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx06.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=maxime.coquelin@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com 55EBE369C9 Received: from localhost.localdomain (ovpn-112-47.ams2.redhat.com [10.36.112.47]) by smtp.corp.redhat.com (Postfix) with ESMTP id 47BCC63F69; Tue, 4 Jul 2017 09:50:19 +0000 (UTC) From: Maxime Coquelin To: dev@dpdk.org, Yuanhan Liu Cc: mst@redhat.com, vkaplans@redhat.com, jasowang@redhat.com, jfreiman@redhat.com, Maxime Coquelin Date: Tue, 4 Jul 2017 11:49:14 +0200 Message-Id: <20170704094922.11405-12-maxime.coquelin@redhat.com> In-Reply-To: <20170704094922.11405-1-maxime.coquelin@redhat.com> References: <20170704094922.11405-1-maxime.coquelin@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.30]); Tue, 04 Jul 2017 09:50:21 +0000 (UTC) Subject: [dpdk-dev] [RFC 11/19] vhost: introduce guest IOVA to backend VA helper 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" This patch introduces vhost_iova_to_vva() function to translate guest's IO virtual adresses to backend's virtual addresses. When IOMMU is enabled, the IOTLB cache is queried to get the translation. If missing from the IOTLB cache, an IOTLB_MISS request is sent to Qemu, and IOTLB cache is queried again on IOTLB event notification. When IOMMU is disabled, the passed address is a guest's physical address, so the legacy rte_vhost_gpa_to_vva() API is used. Signed-off-by: Maxime Coquelin --- lib/librte_vhost/vhost.c | 35 +++++++++++++++++++++++++++++++++++ lib/librte_vhost/vhost.h | 3 +++ 2 files changed, 38 insertions(+) diff --git a/lib/librte_vhost/vhost.c b/lib/librte_vhost/vhost.c index 3897f9c..7920216 100644 --- a/lib/librte_vhost/vhost.c +++ b/lib/librte_vhost/vhost.c @@ -47,9 +47,11 @@ #include #include #include +#include #include "iotlb.h" #include "vhost.h" +#include "vhost_user.h" struct vhost_device { struct virtio_net *dev; @@ -59,6 +61,39 @@ struct vhost_device { /* Declared as static so that .lock is initialized */ static struct vhost_device vhost_devices[MAX_VHOST_DEVICE]; +uint64_t vhost_iova_to_vva(struct virtio_net *dev, struct vhost_virtqueue *vq, + uint64_t iova, uint64_t size, uint8_t perm) +{ + uint64_t vva, tmp_size; + int ret; + + if (unlikely(!size)) + return 0; + + if (!(dev->features & (1ULL << VIRTIO_F_IOMMU_PLATFORM))) + return rte_vhost_gpa_to_vva(dev->mem, iova); + + do { + tmp_size = size; + + vva = vhost_user_iotlb_find(vq, iova, &tmp_size, perm); + if (tmp_size == size) + return vva; + + /* Not in IOTLB cache */ + ret = vhost_user_iotlb_miss(dev, iova + tmp_size, perm); + if (ret) + return 0; + + while (!rte_atomic16_cmpset((volatile uint16_t *) + &vq->iotlb_event.cnt, 1, 0)) + rte_pause(); + + } while (likely(dev->flags & VIRTIO_DEV_RUNNING)); + + return 0; +} + static inline struct virtio_net * __get_device(int vid) { diff --git a/lib/librte_vhost/vhost.h b/lib/librte_vhost/vhost.h index 3242658..5c39d88 100644 --- a/lib/librte_vhost/vhost.h +++ b/lib/librte_vhost/vhost.h @@ -353,4 +353,7 @@ struct vhost_device_ops const *vhost_driver_callback_get(const char *path); void vhost_backend_cleanup(struct virtio_net *dev); void notify_iotlb_event(struct virtio_net *dev); +uint64_t vhost_iova_to_vva(struct virtio_net *dev, struct vhost_virtqueue *vq, + uint64_t iova, uint64_t size, uint8_t perm); + #endif /* _VHOST_NET_CDEV_H_ */