Skip to contentSkip to conversation

vhost: fix async address mapping

PATCH Superseded [email protected] 1 participant 3 messages Feb 15, 2022

v3 of 4 Superseded Latest is v4 →

lore
Share & tools
lore
#0 lore raw

v3 cover vhost: fix async address mapping

From: Xuan Ding <[email protected]>

This patchset fixes the issue of incorrect DMA mapping in PA mode. Due to the ambiguity of host_phys_addr naming in the guest page struct, rename it to host_iova.

v3:
* Fix some format issues.

v2:
* Change the order of patch.

Xuan Ding (2):
vhost: fix field naming in guest page struct
vhost: fix physical address mapping

 lib/vhost/vhost.h      |  11 ++--
 lib/vhost/vhost_user.c | 134 ++++++++++++++++++++---------------------
 lib/vhost/virtio_net.c |  11 ++--
 3 files changed, 77 insertions(+), 79 deletions(-)
Signature · 1 line
2.17.1
#1 lore raw

PATCH v3 1/2 vhost: fix field naming in guest page struct

From: Xuan Ding <[email protected]>

This patch renames the host_phys_addr to host_iova in guest_page struct. The host_phys_addr is iova, it depends on the DPDK IOVA mode.

Fixes e246896178e6 ("vhost: get guest/host physical address mappings")
---
 lib/vhost/vhost.h      | 10 +++++-----
 lib/vhost/vhost_user.c | 20 ++++++++++----------
 lib/vhost/virtio_net.c | 11 ++++++-----
 3 files changed, 21 insertions(+), 20 deletions(-)
lib/vhost/vhost.h +5 -5
index b3f0c1d07c..c5d8b84320 100644
@@ -354,7 +354,7 @@ struct vring_packed_desc_event {
 
 struct guest_page {
 	uint64_t guest_phys_addr;
-	uint64_t host_phys_addr;
+	uint64_t host_iova;
 	uint64_t size;
 };
 
@@ -618,13 +618,13 @@ gpa_to_first_hpa(struct virtio_net *dev, uint64_t gpa,
 			if (gpa + gpa_size <=
 					page->guest_phys_addr + page->size) {
 				return gpa - page->guest_phys_addr +
-					page->host_phys_addr;
+					page->host_iova;
 			} else if (gpa < page->guest_phys_addr +
 						page->size) {
 				*hpa_size = page->guest_phys_addr +
 					page->size - gpa;
 				return gpa - page->guest_phys_addr +
-					page->host_phys_addr;
+					page->host_iova;
 			}
 		}
 	} else {
@@ -635,13 +635,13 @@ gpa_to_first_hpa(struct virtio_net *dev, uint64_t gpa,
 				if (gpa + gpa_size <=
 					page->guest_phys_addr + page->size) {
 					return gpa - page->guest_phys_addr +
-						page->host_phys_addr;
+						page->host_iova;
 				} else if (gpa < page->guest_phys_addr +
 							page->size) {
 					*hpa_size = page->guest_phys_addr +
 						page->size - gpa;
 					return gpa - page->guest_phys_addr +
-						page->host_phys_addr;
+						page->host_iova;
 				}
 			}
 		}
lib/vhost/vhost_user.c +10 -10
index 3b810c112c..cd066d8af0 100644
@@ -985,7 +985,7 @@ vhost_user_set_vring_base(struct virtio_net **pdev,
 
 static int
 add_one_guest_page(struct virtio_net *dev, uint64_t guest_phys_addr,
-		   uint64_t host_phys_addr, uint64_t size)
+		   uint64_t host_iova, uint64_t size)
 {
 	struct guest_page *page, *last_page;
 	struct guest_page *old_pages;
@@ -1006,7 +1006,7 @@ add_one_guest_page(struct virtio_net *dev, uint64_t guest_phys_addr,
 	if (dev->nr_guest_pages > 0) {
 		last_page = &dev->guest_pages[dev->nr_guest_pages - 1];
 		/* merge if the two pages are continuous */
-		if (host_phys_addr == last_page->host_phys_addr +
+		if (host_iova == last_page->host_iova +
 				      last_page->size) {
 			last_page->size += size;
 			return 0;
@@ -1015,7 +1015,7 @@ add_one_guest_page(struct virtio_net *dev, uint64_t guest_phys_addr,
 
 	page = &dev->guest_pages[dev->nr_guest_pages++];
 	page->guest_phys_addr = guest_phys_addr;
-	page->host_phys_addr  = host_phys_addr;
+	page->host_iova  = host_iova;
 	page->size = size;
 
 	return 0;
@@ -1028,14 +1028,14 @@ add_guest_pages(struct virtio_net *dev, struct rte_vhost_mem_region *reg,
 	uint64_t reg_size = reg->size;
 	uint64_t host_user_addr  = reg->host_user_addr;
 	uint64_t guest_phys_addr = reg->guest_phys_addr;
-	uint64_t host_phys_addr;
+	uint64_t host_iova;
 	uint64_t size;
 
-	host_phys_addr = rte_mem_virt2iova((void *)(uintptr_t)host_user_addr);
+	host_iova = rte_mem_virt2iova((void *)(uintptr_t)host_user_addr);
 	size = page_size - (guest_phys_addr & (page_size - 1));
 	size = RTE_MIN(size, reg_size);
 
-	if (add_one_guest_page(dev, guest_phys_addr, host_phys_addr, size) < 0)
+	if (add_one_guest_page(dev, guest_phys_addr, host_iova, size) < 0)
 		return -1;
 
 	host_user_addr  += size;
@@ -1044,9 +1044,9 @@ add_guest_pages(struct virtio_net *dev, struct rte_vhost_mem_region *reg,
 
 	while (reg_size > 0) {
 		size = RTE_MIN(reg_size, page_size);
-		host_phys_addr = rte_mem_virt2iova((void *)(uintptr_t)
+		host_iova = rte_mem_virt2iova((void *)(uintptr_t)
 						  host_user_addr);
-		if (add_one_guest_page(dev, guest_phys_addr, host_phys_addr,
+		if (add_one_guest_page(dev, guest_phys_addr, host_iova,
 				size) < 0)
 			return -1;
 
@@ -1079,8 +1079,8 @@ dump_guest_pages(struct virtio_net *dev)
 				dev->ifname, i);
 		VHOST_LOG_CONFIG(INFO, "(%s)\tguest_phys_addr: %" PRIx64 "\n",
 				dev->ifname, page->guest_phys_addr);
-		VHOST_LOG_CONFIG(INFO, "(%s)\thost_phys_addr : %" PRIx64 "\n",
-				dev->ifname, page->host_phys_addr);
+		VHOST_LOG_CONFIG(INFO, "(%s)\thost_iova : %" PRIx64 "\n",
+				dev->ifname, page->host_iova);
 		VHOST_LOG_CONFIG(INFO, "(%s)\tsize           : %" PRIx64 "\n",
 				dev->ifname, page->size);
 	}
lib/vhost/virtio_net.c +6 -5
index f19713137c..00c6c41292 100644
@@ -871,20 +871,21 @@ async_mbuf_to_desc_seg(struct virtio_net *dev, struct vhost_virtqueue *vq,
 	struct vhost_async *async = vq->async;
 	uint64_t mapped_len;
 	uint32_t buf_offset = 0;
-	void *hpa;
+	void *host_iova;
 
 	while (cpy_len) {
-		hpa = (void *)(uintptr_t)gpa_to_first_hpa(dev,
+		host_iova = (void *)(uintptr_t)gpa_to_first_hpa(dev,
 				buf_iova + buf_offset, cpy_len, &mapped_len);
-		if (unlikely(!hpa)) {
-			VHOST_LOG_DATA(ERR, "(%s) %s: failed to get hpa.\n", dev->ifname, __func__);
+		if (unlikely(!host_iova)) {
+			VHOST_LOG_DATA(ERR, "(%s) %s: failed to get host iova.\n",
+				       dev->ifname, __func__);
 			return -1;
 		}
 
 		if (unlikely(async_iter_add_iovec(dev, async,
 						(void *)(uintptr_t)rte_pktmbuf_iova_offset(m,
 							mbuf_offset),
-						hpa, (size_t)mapped_len)))
+						host_iova, (size_t)mapped_len)))
 			return -1;
 
 		cpy_len -= (uint32_t)mapped_len;
Signature · 1 line
2.17.1
#2 lore raw

PATCH v3 2/2 vhost: fix physical address mapping

In reply to [email protected]

From: Xuan Ding <[email protected]>

When choosing IOVA as PA mode, IOVA is likely to be discontinuous, which requires page by page mapping for DMA devices. To be consistent, this patch implements page by page mapping instead of mapping at the region granularity for both IOVA as VA and PA mode.

Fixes 7c61fa08b716 ("vhost: enable IOMMU for async vhost")
---
 lib/vhost/vhost.h      |   1 +
 lib/vhost/vhost_user.c | 119 ++++++++++++++++++++---------------------
 2 files changed, 58 insertions(+), 62 deletions(-)
lib/vhost/vhost.h +1 -0
index c5d8b84320..d4586f3341 100644
@@ -355,6 +355,7 @@ struct vring_packed_desc_event {
 struct guest_page {
 	uint64_t guest_phys_addr;
 	uint64_t host_iova;
+	uint64_t host_user_addr;
 	uint64_t size;
 };
 
lib/vhost/vhost_user.c +57 -62

197 lines not on this page · raw message

Signature · 1 line
2.17.1