From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 5F7C4A0555 for ; Wed, 19 Feb 2020 16:57:49 +0100 (CET) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 598511BF91; Wed, 19 Feb 2020 16:57:49 +0100 (CET) Received: from us-smtp-delivery-1.mimecast.com (us-smtp-1.mimecast.com [207.211.31.81]) by dpdk.org (Postfix) with ESMTP id 60141B62 for ; Wed, 19 Feb 2020 16:57:47 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1582127866; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=mkjauo79EQeebrpIzKYzqfRd+sDYv7r1PlPsw+LzyN0=; b=cEQURsf4Y55ISchmKQncz8aU/Yq01+tNCUGCliV5TCD0t3b1MSAWctAwUoPJ3nzR+Hjk6Q FgBrcv7k6R+6oQ99+oVKEWK4TBCBUE0YCpv77W9STvH+Bw8gNlYBvl5k6ndGqj5PODuzn7 vCyrAVkAw7IdD5u49M+DgnfUVG6sK50= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-195-CN9YaTTOPNyDWyjHfPqUxA-1; Wed, 19 Feb 2020 10:57:44 -0500 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 mimecast-mx01.redhat.com (Postfix) with ESMTPS id 84E1D100550E for ; Wed, 19 Feb 2020 15:57:43 +0000 (UTC) Received: from rh.redhat.com (unknown [10.33.36.109]) by smtp.corp.redhat.com (Postfix) with ESMTP id 9491B811F8; Wed, 19 Feb 2020 15:57:42 +0000 (UTC) From: Kevin Traynor To: Adrian Moreno Cc: Maxime Coquelin , dpdk stable Date: Wed, 19 Feb 2020 15:56:02 +0000 Message-Id: <20200219155607.20495-17-ktraynor@redhat.com> In-Reply-To: <20200219155607.20495-1-ktraynor@redhat.com> References: <20200219155607.20495-1-ktraynor@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-MC-Unique: CN9YaTTOPNyDWyjHfPqUxA-1 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: quoted-printable Subject: [dpdk-stable] patch 'vhost: protect log address translation in IOTLB update' has been queued to LTS release 18.11.7 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: , Errors-To: stable-bounces@dpdk.org Sender: "stable" Hi, FYI, your patch has been queued to LTS release 18.11.7 Note it hasn't been pushed to http://dpdk.org/browse/dpdk-stable yet. It will be pushed if I get no objections before 02/25/20. So please shout if anyone has objections. Also note that after the patch there's a diff of the upstream commit vs the patch applied to the branch. This will indicate if there was any rebasing needed to apply to the stable branch. If there were code changes for rebasi= ng (ie: not only metadata diffs), please double check that the rebase was correctly done. Queued patches are on a temporary branch at: https://github.com/kevintraynor/dpdk-stable-queue This queued commit can be viewed at: https://github.com/kevintraynor/dpdk-stable-queue/commit/413c05126b5948bc1b= 14bdb3bcbfcd3fdd3583c3 Thanks. Kevin. --- >From 413c05126b5948bc1b14bdb3bcbfcd3fdd3583c3 Mon Sep 17 00:00:00 2001 From: Adrian Moreno Date: Thu, 13 Feb 2020 11:04:58 +0100 Subject: [PATCH] vhost: protect log address translation in IOTLB update [ upstream commit 4f37df14c405b754b5e971c75f4f67f4bb5bfdde ] Currently, the log address translation only happens in the vhost-user's translate_ring_addresses(). However, the IOTLB update handler is not checking if it was mapped to re-trigger that translation. Since the log address mapping could fail, check it on iotlb updates. Also, check it on vring_translate() so we do not dirty pages if the logging address is not yet ready. Additionally, properly protect the accesses to the iotlb structures. Fixes: fbda9f145927 ("vhost: translate incoming log address to GPA") Signed-off-by: Adrian Moreno Reviewed-by: Maxime Coquelin --- lib/librte_vhost/vhost.c | 56 ++++++++++++++++++++++++++++++++++ lib/librte_vhost/vhost.h | 15 +++++++-- lib/librte_vhost/vhost_user.c | 57 +++++++++++++++-------------------- 3 files changed, 93 insertions(+), 35 deletions(-) diff --git a/lib/librte_vhost/vhost.c b/lib/librte_vhost/vhost.c index f00efb382c..0432b26638 100644 --- a/lib/librte_vhost/vhost.c +++ b/lib/librte_vhost/vhost.c @@ -324,4 +324,55 @@ free_device(struct virtio_net *dev) } =20 +static __rte_always_inline int +log_translate(struct virtio_net *dev, struct vhost_virtqueue *vq) +{ +=09if (likely(!(vq->ring_addrs.flags & (1 << VHOST_VRING_F_LOG)))) +=09=09return 0; + +=09vq->log_guest_addr =3D translate_log_addr(dev, vq, +=09=09=09=09=09=09vq->ring_addrs.log_guest_addr); +=09if (vq->log_guest_addr =3D=3D 0) +=09=09return -1; + +=09return 0; +} + +/* + * 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 + * + * Caller should have iotlb_lock read-locked + */ +uint64_t +translate_log_addr(struct virtio_net *dev, struct vhost_virtqueue *vq, +=09=09uint64_t log_addr) +{ +=09if (dev->features & (1ULL << VIRTIO_F_IOMMU_PLATFORM)) { +=09=09const uint64_t exp_size =3D sizeof(uint64_t); +=09=09uint64_t hva, gpa; +=09=09uint64_t size =3D exp_size; + +=09=09hva =3D vhost_iova_to_vva(dev, vq, log_addr, +=09=09=09=09=09&size, VHOST_ACCESS_RW); + +=09=09if (size !=3D exp_size) +=09=09=09return 0; + +=09=09gpa =3D hva_to_gpa(dev, hva, exp_size); +=09=09if (!gpa) { +=09=09=09RTE_LOG(ERR, VHOST_CONFIG, +=09=09=09=09"VQ: Failed to find GPA for log_addr: 0x%" +=09=09=09=09PRIx64 " hva: 0x%" PRIx64 "\n", +=09=09=09=09log_addr, hva); +=09=09=09return 0; +=09=09} +=09=09return gpa; + +=09} else +=09=09return log_addr; +} + +/* Caller should have iotlb_lock read-locked */ static int vring_translate_split(struct virtio_net *dev, struct vhost_virtqueue *vq) @@ -362,4 +413,5 @@ vring_translate_split(struct virtio_net *dev, struct vh= ost_virtqueue *vq) } =20 +/* Caller should have iotlb_lock read-locked */ static int vring_translate_packed(struct virtio_net *dev, struct vhost_virtqueue *vq) @@ -408,4 +460,8 @@ vring_translate(struct virtio_net *dev, struct vhost_vi= rtqueue *vq) =09=09=09return -1; =09} + +=09if (log_translate(dev, vq) < 0) +=09=09return -1; + =09vq->access_ok =3D 1; =20 diff --git a/lib/librte_vhost/vhost.h b/lib/librte_vhost/vhost.h index 4279db95a2..535591927f 100644 --- a/lib/librte_vhost/vhost.h +++ b/lib/librte_vhost/vhost.h @@ -438,5 +438,10 @@ vhost_log_cache_used_vring(struct virtio_net *dev, str= uct vhost_virtqueue *vq, =09=09=09uint64_t offset, uint64_t len) { -=09vhost_log_cache_write(dev, vq, vq->log_guest_addr + offset, len); +=09if (unlikely(dev->features & (1ULL << VHOST_F_LOG_ALL))) { +=09=09if (unlikely(vq->log_guest_addr =3D=3D 0)) +=09=09=09return; +=09=09__vhost_log_cache_write(dev, vq, vq->log_guest_addr + offset, +=09=09=09=09=09len); +=09} } =20 @@ -445,5 +450,9 @@ vhost_log_used_vring(struct virtio_net *dev, struct vho= st_virtqueue *vq, =09=09 uint64_t offset, uint64_t len) { -=09vhost_log_write(dev, vq->log_guest_addr + offset, len); +=09if (unlikely(dev->features & (1ULL << VHOST_F_LOG_ALL))) { +=09=09if (unlikely(vq->log_guest_addr =3D=3D 0)) +=09=09=09return; +=09=09__vhost_log_write(dev, vq->log_guest_addr + offset, len); +=09} } =20 @@ -594,4 +603,6 @@ void *vhost_alloc_copy_ind_table(struct virtio_net *dev= , =09=09=09uint64_t desc_addr, uint64_t desc_len); int vring_translate(struct virtio_net *dev, struct vhost_virtqueue *vq); +uint64_t translate_log_addr(struct virtio_net *dev, struct vhost_virtqueue= *vq, +=09=09uint64_t log_addr); void vring_invalidate(struct virtio_net *dev, struct vhost_virtqueue *vq); =20 diff --git a/lib/librte_vhost/vhost_user.c b/lib/librte_vhost/vhost_user.c index 13606cea44..2f4bbb342d 100644 --- a/lib/librte_vhost/vhost_user.c +++ b/lib/librte_vhost/vhost_user.c @@ -629,11 +629,9 @@ ring_addr_to_vva(struct virtio_net *dev, struct vhost_= virtqueue *vq, =09if (dev->features & (1ULL << VIRTIO_F_IOMMU_PLATFORM)) { =09=09uint64_t vva; -=09=09uint64_t req_size =3D *size; =20 -=09=09vva =3D vhost_user_iotlb_cache_find(vq, ra, +=09=09vhost_user_iotlb_rd_lock(vq); +=09=09vva =3D vhost_iova_to_vva(dev, vq, ra, =09=09=09=09=09size, VHOST_ACCESS_RW); -=09=09if (req_size !=3D *size) -=09=09=09vhost_user_iotlb_miss(dev, (ra + *size), -=09=09=09=09=09 VHOST_ACCESS_RW); +=09=09vhost_user_iotlb_rd_unlock(vq); =20 =09=09return vva; @@ -643,35 +641,14 @@ ring_addr_to_vva(struct virtio_net *dev, struct vhost= _virtqueue *vq, } =20 -/* - * 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, -=09=09uint64_t log_addr) +log_addr_to_gpa(struct virtio_net *dev, struct vhost_virtqueue *vq) { -=09if (dev->features & (1ULL << VIRTIO_F_IOMMU_PLATFORM)) { -=09=09const uint64_t exp_size =3D sizeof(struct vring_used) + -=09=09=09sizeof(struct vring_used_elem) * vq->size; -=09=09uint64_t hva, gpa; -=09=09uint64_t size =3D exp_size; +=09uint64_t log_gpa; =20 -=09=09hva =3D vhost_iova_to_vva(dev, vq, log_addr, -=09=09=09=09=09&size, VHOST_ACCESS_RW); -=09=09if (size !=3D exp_size) -=09=09=09return 0; +=09vhost_user_iotlb_rd_lock(vq); +=09log_gpa =3D translate_log_addr(dev, vq, vq->ring_addrs.log_guest_addr); +=09vhost_user_iotlb_rd_unlock(vq); =20 -=09=09gpa =3D hva_to_gpa(dev, hva, exp_size); -=09=09if (!gpa) { -=09=09=09RTE_LOG(ERR, VHOST_CONFIG, -=09=09=09=09"VQ: Failed to find GPA for log_addr: 0x%" PRIx64 " hva: 0x%" = PRIx64 "\n", -=09=09=09=09log_addr, hva); -=09=09=09return 0; -=09=09} -=09=09return gpa; - -=09} else -=09=09return log_addr; +=09return log_gpa; } =20 @@ -685,5 +662,5 @@ translate_ring_addresses(struct virtio_net *dev, int vq= _index) =09if (addr->flags & (1 << VHOST_VRING_F_LOG)) { =09=09vq->log_guest_addr =3D -=09=09=09translate_log_addr(dev, vq, addr->log_guest_addr); +=09=09=09log_addr_to_gpa(dev, vq); =09=09if (vq->log_guest_addr =3D=3D 0) { =09=09=09RTE_LOG(DEBUG, VHOST_CONFIG, @@ -1788,4 +1765,11 @@ is_vring_iotlb_split(struct vhost_virtqueue *vq, str= uct vhost_iotlb_msg *imsg) =09=09return 1; =20 +=09if (ra->flags & (1 << VHOST_VRING_F_LOG)) { +=09=09len =3D sizeof(uint64_t); +=09=09if (ra->log_guest_addr < end && +=09=09 (ra->log_guest_addr + len) > start) +=09=09=09return 1; +=09} + =09return 0; } @@ -1813,4 +1797,11 @@ is_vring_iotlb_packed(struct vhost_virtqueue *vq, st= ruct vhost_iotlb_msg *imsg) =09=09return 1; =20 +=09if (ra->flags & (1 << VHOST_VRING_F_LOG)) { +=09=09len =3D sizeof(uint64_t); +=09=09if (ra->log_guest_addr < end && +=09=09 (ra->log_guest_addr + len) > start) +=09=09=09return 1; +=09} + =09return 0; } --=20 2.21.1 --- Diff of the applied patch vs upstream commit (please double-check if non-= empty: --- --- -=092020-02-19 15:43:50.613352658 +0000 +++ 0017-vhost-protect-log-address-translation-in-IOTLB-updat.patch=092020-= 02-19 15:43:49.758141445 +0000 @@ -1 +1 @@ -From 4f37df14c405b754b5e971c75f4f67f4bb5bfdde Mon Sep 17 00:00:00 2001 +From 413c05126b5948bc1b14bdb3bcbfcd3fdd3583c3 Mon Sep 17 00:00:00 2001 @@ -5,0 +6,2 @@ +[ upstream commit 4f37df14c405b754b5e971c75f4f67f4bb5bfdde ] + @@ -17 +18,0 @@ -Cc: stable@dpdk.org @@ -28 +29 @@ -index c819a84774..0266318440 100644 +index f00efb382c..0432b26638 100644 @@ -31 +32 @@ -@@ -354,4 +354,55 @@ free_device(struct virtio_net *dev) +@@ -324,4 +324,55 @@ free_device(struct virtio_net *dev) @@ -72 +73 @@ -+=09=09=09VHOST_LOG_CONFIG(ERR, ++=09=09=09RTE_LOG(ERR, VHOST_CONFIG, @@ -87 +88 @@ -@@ -392,4 +443,5 @@ vring_translate_split(struct virtio_net *dev, struct v= host_virtqueue *vq) +@@ -362,4 +413,5 @@ vring_translate_split(struct virtio_net *dev, struct v= host_virtqueue *vq) @@ -93 +94 @@ -@@ -438,4 +490,8 @@ vring_translate(struct virtio_net *dev, struct vhost_v= irtqueue *vq) +@@ -408,4 +460,8 @@ vring_translate(struct virtio_net *dev, struct vhost_v= irtqueue *vq) @@ -103 +104 @@ -index 686ce42a20..2087d1400e 100644 +index 4279db95a2..535591927f 100644 @@ -106 +107 @@ -@@ -463,5 +463,10 @@ vhost_log_cache_used_vring(struct virtio_net *dev, st= ruct vhost_virtqueue *vq, +@@ -438,5 +438,10 @@ vhost_log_cache_used_vring(struct virtio_net *dev, st= ruct vhost_virtqueue *vq, @@ -118 +119 @@ -@@ -470,5 +475,9 @@ vhost_log_used_vring(struct virtio_net *dev, struct vh= ost_virtqueue *vq, +@@ -445,5 +450,9 @@ vhost_log_used_vring(struct virtio_net *dev, struct vh= ost_virtqueue *vq, @@ -129 +130 @@ -@@ -627,4 +636,6 @@ void *vhost_alloc_copy_ind_table(struct virtio_net *de= v, +@@ -594,4 +603,6 @@ void *vhost_alloc_copy_ind_table(struct virtio_net *de= v, @@ -137 +138 @@ -index 9a7b8b3088..bd1be01040 100644 +index 13606cea44..2f4bbb342d 100644 @@ -140 +141 @@ -@@ -657,11 +657,9 @@ ring_addr_to_vva(struct virtio_net *dev, struct vhost= _virtqueue *vq, +@@ -629,11 +629,9 @@ ring_addr_to_vva(struct virtio_net *dev, struct vhost= _virtqueue *vq, @@ -155 +156 @@ -@@ -671,35 +669,14 @@ ring_addr_to_vva(struct virtio_net *dev, struct vhos= t_virtqueue *vq, +@@ -643,35 +641,14 @@ ring_addr_to_vva(struct virtio_net *dev, struct vhos= t_virtqueue *vq, @@ -185 +186 @@ --=09=09=09VHOST_LOG_CONFIG(ERR, +-=09=09=09RTE_LOG(ERR, VHOST_CONFIG, @@ -197 +198 @@ -@@ -713,5 +690,5 @@ translate_ring_addresses(struct virtio_net *dev, int v= q_index) +@@ -685,5 +662,5 @@ translate_ring_addresses(struct virtio_net *dev, int v= q_index) @@ -203,2 +204,2 @@ - =09=09=09VHOST_LOG_CONFIG(DEBUG, -@@ -2252,4 +2229,11 @@ is_vring_iotlb_split(struct vhost_virtqueue *vq, st= ruct vhost_iotlb_msg *imsg) + =09=09=09RTE_LOG(DEBUG, VHOST_CONFIG, +@@ -1788,4 +1765,11 @@ is_vring_iotlb_split(struct vhost_virtqueue *vq, st= ruct vhost_iotlb_msg *imsg) @@ -216 +217 @@ -@@ -2277,4 +2261,11 @@ is_vring_iotlb_packed(struct vhost_virtqueue *vq, s= truct vhost_iotlb_msg *imsg) +@@ -1813,4 +1797,11 @@ is_vring_iotlb_packed(struct vhost_virtqueue *vq, s= truct vhost_iotlb_msg *imsg)