vhost: convert buffer addresses to GPA for logging
authorAdrian Moreno <amorenoz@redhat.com>
Wed, 9 Oct 2019 11:54:31 +0000 (13:54 +0200)
committerFerruh Yigit <ferruh.yigit@intel.com>
Wed, 23 Oct 2019 14:43:09 +0000 (16:43 +0200)
Add IOVA versions of dirty page logging functions.

Note that the API facing rte_vhost_log_write is not modified.
So, make explicit that it expects the address in GPA space.

Fixes: 69c90e98f483 ("vhost: enable IOMMU support")
Cc: stable@dpdk.org
Signed-off-by: Adrian Moreno <amorenoz@redhat.com>
Reviewed-by: Maxime Coquelin <maxime.coquelin@redhat.com>
lib/librte_vhost/rte_vhost.h
lib/librte_vhost/vdpa.c
lib/librte_vhost/vhost.c
lib/librte_vhost/vhost.h
lib/librte_vhost/virtio_net.c

index 19474bc..fa813b0 100644 (file)
@@ -274,7 +274,7 @@ rte_vhost_va_from_guest_pa(struct rte_vhost_memory *mem,
  * @param vid
  *  vhost device ID
  * @param addr
- *  the starting address for write
+ *  the starting address for write (in guest physical address space)
  * @param len
  *  the length to write
  */
index 8e45ce9..2b86708 100644 (file)
@@ -201,7 +201,8 @@ rte_vdpa_relay_vring_used(int vid, uint16_t qid, void *vring_m)
                                goto fail;
                        desc = desc_ring[desc_id];
                        if (desc.flags & VRING_DESC_F_WRITE)
-                               vhost_log_write(dev, desc.addr, desc.len);
+                               vhost_log_write_iova(dev, vq, desc.addr,
+                                                    desc.len);
                        desc_id = desc.next;
                } while (desc.flags & VRING_DESC_F_NEXT);
 
index 76e7534..6fb3dc2 100644 (file)
@@ -115,6 +115,26 @@ __vhost_log_write(struct virtio_net *dev, uint64_t addr, uint64_t len)
        }
 }
 
+void
+__vhost_log_write_iova(struct virtio_net *dev, struct vhost_virtqueue *vq,
+                            uint64_t iova, uint64_t len)
+{
+       uint64_t hva, gpa, map_len;
+       map_len = len;
+
+       hva = __vhost_iova_to_vva(dev, vq, iova, &map_len, VHOST_ACCESS_RW);
+       if (map_len != len) {
+               RTE_LOG(ERR, VHOST_CONFIG,
+                       "Failed to write log for IOVA 0x%" PRIx64 ". No IOTLB entry found\n",
+                       iova);
+               return;
+       }
+
+       gpa = hva_to_gpa(dev, hva, len);
+       if (gpa)
+               __vhost_log_write(dev, gpa, len);
+}
+
 void
 __vhost_log_cache_sync(struct virtio_net *dev, struct vhost_virtqueue *vq)
 {
@@ -200,6 +220,26 @@ __vhost_log_cache_write(struct virtio_net *dev, struct vhost_virtqueue *vq,
        }
 }
 
+void
+__vhost_log_cache_write_iova(struct virtio_net *dev, struct vhost_virtqueue *vq,
+                            uint64_t iova, uint64_t len)
+{
+       uint64_t hva, gpa, map_len;
+       map_len = len;
+
+       hva = __vhost_iova_to_vva(dev, vq, iova, &map_len, VHOST_ACCESS_RW);
+       if (map_len != len) {
+               RTE_LOG(ERR, VHOST_CONFIG,
+                       "Failed to write log for IOVA 0x%" PRIx64 ". No IOTLB entry found\n",
+                       iova);
+               return;
+       }
+
+       gpa = hva_to_gpa(dev, hva, len);
+       if (gpa)
+               __vhost_log_cache_write(dev, vq, gpa, len);
+}
+
 void *
 vhost_alloc_copy_ind_table(struct virtio_net *dev, struct vhost_virtqueue *vq,
                uint64_t desc_addr, uint64_t desc_len)
index 7a31471..cfea138 100644 (file)
@@ -353,9 +353,14 @@ desc_is_avail(struct vring_packed_desc *desc, bool wrap_counter)
 void __vhost_log_cache_write(struct virtio_net *dev,
                struct vhost_virtqueue *vq,
                uint64_t addr, uint64_t len);
+void __vhost_log_cache_write_iova(struct virtio_net *dev,
+               struct vhost_virtqueue *vq,
+               uint64_t iova, uint64_t len);
 void __vhost_log_cache_sync(struct virtio_net *dev,
                struct vhost_virtqueue *vq);
 void __vhost_log_write(struct virtio_net *dev, uint64_t addr, uint64_t len);
+void __vhost_log_write_iova(struct virtio_net *dev, struct vhost_virtqueue *vq,
+                           uint64_t iova, uint64_t len);
 
 static __rte_always_inline void
 vhost_log_write(struct virtio_net *dev, uint64_t addr, uint64_t len)
@@ -393,6 +398,32 @@ vhost_log_used_vring(struct virtio_net *dev, struct vhost_virtqueue *vq,
        vhost_log_write(dev, vq->log_guest_addr + offset, len);
 }
 
+static __rte_always_inline void
+vhost_log_cache_write_iova(struct virtio_net *dev, struct vhost_virtqueue *vq,
+                          uint64_t iova, uint64_t len)
+{
+       if (likely(!(dev->features & (1ULL << VHOST_F_LOG_ALL))))
+               return;
+
+       if (dev->features & (1ULL << VIRTIO_F_IOMMU_PLATFORM))
+               __vhost_log_cache_write_iova(dev, vq, iova, len);
+       else
+               __vhost_log_cache_write(dev, vq, iova, len);
+}
+
+static __rte_always_inline void
+vhost_log_write_iova(struct virtio_net *dev, struct vhost_virtqueue *vq,
+                          uint64_t iova, uint64_t len)
+{
+       if (likely(!(dev->features & (1ULL << VHOST_F_LOG_ALL))))
+               return;
+
+       if (dev->features & (1ULL << VIRTIO_F_IOMMU_PLATFORM))
+               __vhost_log_write_iova(dev, vq, iova, len);
+       else
+               __vhost_log_write(dev, iova, len);
+}
+
 /* Macros for printing using RTE_LOG */
 #define RTE_LOGTYPE_VHOST_CONFIG RTE_LOGTYPE_USER1
 #define RTE_LOGTYPE_VHOST_DATA   RTE_LOGTYPE_USER1
index 241d467..beba9b9 100644 (file)
@@ -177,7 +177,8 @@ do_data_copy_enqueue(struct virtio_net *dev, struct vhost_virtqueue *vq)
 
        for (i = 0; i < count; i++) {
                rte_memcpy(elem[i].dst, elem[i].src, elem[i].len);
-               vhost_log_cache_write(dev, vq, elem[i].log_addr, elem[i].len);
+               vhost_log_cache_write_iova(dev, vq, elem[i].log_addr,
+                                          elem[i].len);
                PRINT_PACKET(dev, (uintptr_t)elem[i].dst, elem[i].len, 0);
        }
 
@@ -631,7 +632,7 @@ copy_vnet_hdr_to_desc(struct virtio_net *dev, struct vhost_virtqueue *vq,
 
                PRINT_PACKET(dev, (uintptr_t)dst,
                                (uint32_t)len, 0);
-               vhost_log_cache_write(dev, vq,
+               vhost_log_cache_write_iova(dev, vq,
                                iova, len);
 
                remain -= len;
@@ -731,7 +732,7 @@ copy_mbuf_to_desc(struct virtio_net *dev, struct vhost_virtqueue *vq,
                        } else {
                                PRINT_PACKET(dev, (uintptr_t)hdr_addr,
                                                dev->vhost_hlen, 0);
-                               vhost_log_cache_write(dev, vq,
+                               vhost_log_cache_write_iova(dev, vq,
                                                buf_vec[0].buf_iova,
                                                dev->vhost_hlen);
                        }
@@ -746,8 +747,9 @@ copy_mbuf_to_desc(struct virtio_net *dev, struct vhost_virtqueue *vq,
                        rte_memcpy((void *)((uintptr_t)(buf_addr + buf_offset)),
                                rte_pktmbuf_mtod_offset(m, void *, mbuf_offset),
                                cpy_len);
-                       vhost_log_cache_write(dev, vq, buf_iova + buf_offset,
-                                       cpy_len);
+                       vhost_log_cache_write_iova(dev, vq,
+                                                  buf_iova + buf_offset,
+                                                  cpy_len);
                        PRINT_PACKET(dev, (uintptr_t)(buf_addr + buf_offset),
                                cpy_len, 0);
                } else {