patches for DPDK stable branches
 help / color / mirror / Atom feed
From: Kevin Traynor <ktraynor@redhat.com>
To: Adrian Moreno <amorenoz@redhat.com>
Cc: Maxime Coquelin <maxime.coquelin@redhat.com>,
	dpdk stable <stable@dpdk.org>
Subject: [dpdk-stable] patch 'vhost: protect log address translation in IOTLB update' has been queued to LTS release 18.11.7
Date: Wed, 19 Feb 2020 15:56:02 +0000	[thread overview]
Message-ID: <20200219155607.20495-17-ktraynor@redhat.com> (raw)
In-Reply-To: <20200219155607.20495-1-ktraynor@redhat.com>

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@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@redhat.com>
Reviewed-by: Maxime Coquelin <maxime.coquelin@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@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)


  parent reply	other threads:[~2020-02-19 15:57 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-02-19 15:55 [dpdk-stable] patch 'acl: fix 32-bit match for range field' " Kevin Traynor
2020-02-19 15:55 ` [dpdk-stable] patch 'examples/ethtool: fix unchecked return value' " Kevin Traynor
2020-02-19 15:55 ` [dpdk-stable] patch 'kni: fix build with Linux 5.6' " Kevin Traynor
2020-02-19 15:55 ` [dpdk-stable] patch 'fix Mellanox copyright and SPDX tag' " Kevin Traynor
2020-02-19 15:55 ` [dpdk-stable] patch 'kni: fix not contiguous FIFO' " Kevin Traynor
2020-02-19 15:55 ` [dpdk-stable] patch 'examples/l3fwd-power: fix a typo' " Kevin Traynor
2020-02-19 15:55 ` [dpdk-stable] patch 'examples/l3fwd-power: fix interrupt disable' " Kevin Traynor
2020-02-19 15:55 ` [dpdk-stable] patch 'lib: fix unnecessary double negation' " Kevin Traynor
2020-02-19 15:55 ` [dpdk-stable] patch 'crypto/ccp: fix queue alignment' " Kevin Traynor
2020-02-19 15:55 ` [dpdk-stable] patch 'test/compress: replace test vector' " Kevin Traynor
2020-02-19 15:55 ` [dpdk-stable] patch 'drivers/crypto: fix session-less mode' " Kevin Traynor
2020-02-19 15:55 ` [dpdk-stable] patch 'net/bnxt: fix buffer allocation reattempt' " Kevin Traynor
2020-02-19 15:55 ` [dpdk-stable] patch 'net/netvsc: initialize link state' " Kevin Traynor
2020-02-19 15:55 ` [dpdk-stable] patch 'net/ixgbe: remove dead code' " Kevin Traynor
2020-02-19 15:56 ` [dpdk-stable] patch 'net/mlx5: fix VLAN match for DV mode' " Kevin Traynor
2020-02-19 15:56 ` [dpdk-stable] patch 'vhost: check message header size read' " Kevin Traynor
2020-02-19 15:56 ` Kevin Traynor [this message]
2020-02-19 15:56 ` [dpdk-stable] patch 'app/testpmd: fix hot-unplug detaching' " Kevin Traynor
2020-02-19 15:56 ` [dpdk-stable] patch 'net/i40e: fix unchecked Tx cleanup error' " Kevin Traynor
2020-02-19 15:56 ` [dpdk-stable] patch 'app/eventdev: fix pipeline test with meson build' " Kevin Traynor
2020-02-19 15:56 ` [dpdk-stable] patch 'usertools: fix syntax warning in python 3.8' " Kevin Traynor
2020-02-19 15:56 ` [dpdk-stable] patch 'usertools: fix telemetry client with python 3' " Kevin Traynor

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200219155607.20495-17-ktraynor@redhat.com \
    --to=ktraynor@redhat.com \
    --cc=amorenoz@redhat.com \
    --cc=maxime.coquelin@redhat.com \
    --cc=stable@dpdk.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).