vhost: fix async address mapping
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
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.
--- 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
@@ -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
@@ -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
@@ -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
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.
--- lib/vhost/vhost.h | 1 + lib/vhost/vhost_user.c | 119 ++++++++++++++++++++--------------------- 2 files changed, 58 insertions(+), 62 deletions(-)
lib/vhost/vhost.h +1 -0
@@ -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