[dpdk-stable] patch 'vhost: protect log address translation in IOTLB update' has been queued to LTS release 18.11.7

Kevin Traynor ktraynor at redhat.com
Wed Feb 19 16:56:02 CET 2020


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 rebasing
(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/413c05126b5948bc1b14bdb3bcbfcd3fdd3583c3

Thanks.

Kevin.

---
>From 413c05126b5948bc1b14bdb3bcbfcd3fdd3583c3 Mon Sep 17 00:00:00 2001
From: Adrian Moreno <amorenoz at redhat.com>
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 <amorenoz at redhat.com>
Reviewed-by: Maxime Coquelin <maxime.coquelin at redhat.com>
---
 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)
 }
 
+static __rte_always_inline int
+log_translate(struct virtio_net *dev, struct vhost_virtqueue *vq)
+{
+	if (likely(!(vq->ring_addrs.flags & (1 << VHOST_VRING_F_LOG))))
+		return 0;
+
+	vq->log_guest_addr = translate_log_addr(dev, vq,
+						vq->ring_addrs.log_guest_addr);
+	if (vq->log_guest_addr == 0)
+		return -1;
+
+	return 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,
+		uint64_t log_addr)
+{
+	if (dev->features & (1ULL << VIRTIO_F_IOMMU_PLATFORM)) {
+		const uint64_t exp_size = sizeof(uint64_t);
+		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 for log_addr: 0x%"
+				PRIx64 " hva: 0x%" PRIx64 "\n",
+				log_addr, hva);
+			return 0;
+		}
+		return gpa;
+
+	} else
+		return 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 vhost_virtqueue *vq)
 }
 
+/* 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_virtqueue *vq)
 			return -1;
 	}
+
+	if (log_translate(dev, vq) < 0)
+		return -1;
+
 	vq->access_ok = 1;
 
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, struct vhost_virtqueue *vq,
 			uint64_t offset, uint64_t len)
 {
-	vhost_log_cache_write(dev, vq, vq->log_guest_addr + offset, len);
+	if (unlikely(dev->features & (1ULL << VHOST_F_LOG_ALL))) {
+		if (unlikely(vq->log_guest_addr == 0))
+			return;
+		__vhost_log_cache_write(dev, vq, vq->log_guest_addr + offset,
+					len);
+	}
 }
 
@@ -445,5 +450,9 @@ vhost_log_used_vring(struct virtio_net *dev, struct vhost_virtqueue *vq,
 		     uint64_t offset, uint64_t len)
 {
-	vhost_log_write(dev, vq->log_guest_addr + offset, len);
+	if (unlikely(dev->features & (1ULL << VHOST_F_LOG_ALL))) {
+		if (unlikely(vq->log_guest_addr == 0))
+			return;
+		__vhost_log_write(dev, vq->log_guest_addr + offset, len);
+	}
 }
 
@@ -594,4 +603,6 @@ void *vhost_alloc_copy_ind_table(struct virtio_net *dev,
 			uint64_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,
+		uint64_t log_addr);
 void vring_invalidate(struct virtio_net *dev, struct vhost_virtqueue *vq);
 
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,
 	if (dev->features & (1ULL << VIRTIO_F_IOMMU_PLATFORM)) {
 		uint64_t vva;
-		uint64_t req_size = *size;
 
-		vva = vhost_user_iotlb_cache_find(vq, ra,
+		vhost_user_iotlb_rd_lock(vq);
+		vva = vhost_iova_to_vva(dev, vq, ra,
 					size, VHOST_ACCESS_RW);
-		if (req_size != *size)
-			vhost_user_iotlb_miss(dev, (ra + *size),
-					      VHOST_ACCESS_RW);
+		vhost_user_iotlb_rd_unlock(vq);
 
 		return vva;
@@ -643,35 +641,14 @@ ring_addr_to_vva(struct virtio_net *dev, struct vhost_virtqueue *vq,
 }
 
-/*
- * 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)
+log_addr_to_gpa(struct virtio_net *dev, struct vhost_virtqueue *vq)
 {
-	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;
+	uint64_t log_gpa;
 
-		hva = vhost_iova_to_vva(dev, vq, log_addr,
-					&size, VHOST_ACCESS_RW);
-		if (size != exp_size)
-			return 0;
+	vhost_user_iotlb_rd_lock(vq);
+	log_gpa = translate_log_addr(dev, vq, vq->ring_addrs.log_guest_addr);
+	vhost_user_iotlb_rd_unlock(vq);
 
-		gpa = hva_to_gpa(dev, hva, exp_size);
-		if (!gpa) {
-			RTE_LOG(ERR, VHOST_CONFIG,
-				"VQ: Failed to find GPA for log_addr: 0x%" PRIx64 " hva: 0x%" PRIx64 "\n",
-				log_addr, hva);
-			return 0;
-		}
-		return gpa;
-
-	} else
-		return log_addr;
+	return log_gpa;
 }
 
@@ -685,5 +662,5 @@ translate_ring_addresses(struct virtio_net *dev, int vq_index)
 	if (addr->flags & (1 << VHOST_VRING_F_LOG)) {
 		vq->log_guest_addr =
-			translate_log_addr(dev, vq, addr->log_guest_addr);
+			log_addr_to_gpa(dev, vq);
 		if (vq->log_guest_addr == 0) {
 			RTE_LOG(DEBUG, VHOST_CONFIG,
@@ -1788,4 +1765,11 @@ is_vring_iotlb_split(struct vhost_virtqueue *vq, struct vhost_iotlb_msg *imsg)
 		return 1;
 
+	if (ra->flags & (1 << VHOST_VRING_F_LOG)) {
+		len = sizeof(uint64_t);
+		if (ra->log_guest_addr < end &&
+		    (ra->log_guest_addr + len) > start)
+			return 1;
+	}
+
 	return 0;
 }
@@ -1813,4 +1797,11 @@ is_vring_iotlb_packed(struct vhost_virtqueue *vq, struct vhost_iotlb_msg *imsg)
 		return 1;
 
+	if (ra->flags & (1 << VHOST_VRING_F_LOG)) {
+		len = sizeof(uint64_t);
+		if (ra->log_guest_addr < end &&
+		    (ra->log_guest_addr + len) > start)
+			return 1;
+	}
+
 	return 0;
 }
-- 
2.21.1

---
  Diff of the applied patch vs upstream commit (please double-check if non-empty:
---
--- -	2020-02-19 15:43:50.613352658 +0000
+++ 0017-vhost-protect-log-address-translation-in-IOTLB-updat.patch	2020-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 at 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 @@
-+			VHOST_LOG_CONFIG(ERR,
++			RTE_LOG(ERR, VHOST_CONFIG,
@@ -87 +88 @@
-@@ -392,4 +443,5 @@ vring_translate_split(struct virtio_net *dev, struct vhost_virtqueue *vq)
+@@ -362,4 +413,5 @@ vring_translate_split(struct virtio_net *dev, struct vhost_virtqueue *vq)
@@ -93 +94 @@
-@@ -438,4 +490,8 @@ vring_translate(struct virtio_net *dev, struct vhost_virtqueue *vq)
+@@ -408,4 +460,8 @@ vring_translate(struct virtio_net *dev, struct vhost_virtqueue *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, struct vhost_virtqueue *vq,
+@@ -438,5 +438,10 @@ vhost_log_cache_used_vring(struct virtio_net *dev, struct vhost_virtqueue *vq,
@@ -118 +119 @@
-@@ -470,5 +475,9 @@ vhost_log_used_vring(struct virtio_net *dev, struct vhost_virtqueue *vq,
+@@ -445,5 +450,9 @@ vhost_log_used_vring(struct virtio_net *dev, struct vhost_virtqueue *vq,
@@ -129 +130 @@
-@@ -627,4 +636,6 @@ void *vhost_alloc_copy_ind_table(struct virtio_net *dev,
+@@ -594,4 +603,6 @@ void *vhost_alloc_copy_ind_table(struct virtio_net *dev,
@@ -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 vhost_virtqueue *vq,
+@@ -643,35 +641,14 @@ ring_addr_to_vva(struct virtio_net *dev, struct vhost_virtqueue *vq,
@@ -185 +186 @@
--			VHOST_LOG_CONFIG(ERR,
+-			RTE_LOG(ERR, VHOST_CONFIG,
@@ -197 +198 @@
-@@ -713,5 +690,5 @@ translate_ring_addresses(struct virtio_net *dev, int vq_index)
+@@ -685,5 +662,5 @@ translate_ring_addresses(struct virtio_net *dev, int vq_index)
@@ -203,2 +204,2 @@
- 			VHOST_LOG_CONFIG(DEBUG,
-@@ -2252,4 +2229,11 @@ is_vring_iotlb_split(struct vhost_virtqueue *vq, struct vhost_iotlb_msg *imsg)
+ 			RTE_LOG(DEBUG, VHOST_CONFIG,
+@@ -1788,4 +1765,11 @@ is_vring_iotlb_split(struct vhost_virtqueue *vq, struct vhost_iotlb_msg *imsg)
@@ -216 +217 @@
-@@ -2277,4 +2261,11 @@ is_vring_iotlb_packed(struct vhost_virtqueue *vq, struct vhost_iotlb_msg *imsg)
+@@ -1813,4 +1797,11 @@ is_vring_iotlb_packed(struct vhost_virtqueue *vq, struct vhost_iotlb_msg *imsg)



More information about the stable mailing list