thebeanogamer / rpms / qemu-kvm

Forked from rpms/qemu-kvm 5 months ago
Clone

Blame SOURCES/kvm-vdpa-add-asid-parameter-to-vhost_vdpa_dma_map-unmap.patch

ed5979
From d0e7f24a8d941ab142f2a1973ae18ed1bfdc074f Mon Sep 17 00:00:00 2001
ed5979
From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= <eperezma@redhat.com>
ed5979
Date: Thu, 15 Dec 2022 12:31:41 +0100
ed5979
Subject: [PATCH 09/14] vdpa: add asid parameter to vhost_vdpa_dma_map/unmap
ed5979
MIME-Version: 1.0
ed5979
Content-Type: text/plain; charset=UTF-8
ed5979
Content-Transfer-Encoding: 8bit
ed5979
ed5979
RH-Author: Eugenio Pérez <eperezma@redhat.com>
ed5979
RH-MergeRequest: 136: vDPA ASID support in Qemu
ed5979
RH-Bugzilla: 2104412
ed5979
RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
ed5979
RH-Acked-by: Cindy Lu <lulu@redhat.com>
ed5979
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
ed5979
RH-Commit: [9/13] 3e7f89e57f73661017ccf0206f2ea77a72ca46bb (eperezmartin/qemu-kvm)
ed5979
ed5979
So the caller can choose which ASID is destined.
ed5979
ed5979
No need to update the batch functions as they will always be called from
ed5979
memory listener updates at the moment. Memory listener updates will
ed5979
always update ASID 0, as it's the passthrough ASID.
ed5979
ed5979
All vhost devices's ASID are 0 at this moment.
ed5979
ed5979
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
ed5979
Acked-by: Jason Wang <jasowang@redhat.com>
ed5979
Message-Id: <20221215113144.322011-10-eperezma@redhat.com>
ed5979
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
ed5979
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
ed5979
(cherry picked from commit cd831ed5c4add8ed6ee980c3645b241cbef5130f)
ed5979
---
ed5979
 hw/virtio/trace-events         |  4 ++--
ed5979
 hw/virtio/vhost-vdpa.c         | 36 +++++++++++++++++++++++-----------
ed5979
 include/hw/virtio/vhost-vdpa.h | 14 ++++++++++---
ed5979
 net/vhost-vdpa.c               |  6 +++---
ed5979
 4 files changed, 41 insertions(+), 19 deletions(-)
ed5979
ed5979
diff --git a/hw/virtio/trace-events b/hw/virtio/trace-events
ed5979
index 46f2faf04e..a87c5f39a2 100644
ed5979
--- a/hw/virtio/trace-events
ed5979
+++ b/hw/virtio/trace-events
ed5979
@@ -30,8 +30,8 @@ vhost_user_write(uint32_t req, uint32_t flags) "req:%d flags:0x%"PRIx32""
ed5979
 vhost_user_create_notifier(int idx, void *n) "idx:%d n:%p"
ed5979
 
ed5979
 # vhost-vdpa.c
ed5979
-vhost_vdpa_dma_map(void *vdpa, int fd, uint32_t msg_type, uint64_t iova, uint64_t size, uint64_t uaddr, uint8_t perm, uint8_t type) "vdpa:%p fd: %d msg_type: %"PRIu32" iova: 0x%"PRIx64" size: 0x%"PRIx64" uaddr: 0x%"PRIx64" perm: 0x%"PRIx8" type: %"PRIu8
ed5979
-vhost_vdpa_dma_unmap(void *vdpa, int fd, uint32_t msg_type, uint64_t iova, uint64_t size, uint8_t type) "vdpa:%p fd: %d msg_type: %"PRIu32" iova: 0x%"PRIx64" size: 0x%"PRIx64" type: %"PRIu8
ed5979
+vhost_vdpa_dma_map(void *vdpa, int fd, uint32_t msg_type, uint32_t asid, uint64_t iova, uint64_t size, uint64_t uaddr, uint8_t perm, uint8_t type) "vdpa:%p fd: %d msg_type: %"PRIu32" asid: %"PRIu32" iova: 0x%"PRIx64" size: 0x%"PRIx64" uaddr: 0x%"PRIx64" perm: 0x%"PRIx8" type: %"PRIu8
ed5979
+vhost_vdpa_dma_unmap(void *vdpa, int fd, uint32_t msg_type, uint32_t asid, uint64_t iova, uint64_t size, uint8_t type) "vdpa:%p fd: %d msg_type: %"PRIu32" asid: %"PRIu32" iova: 0x%"PRIx64" size: 0x%"PRIx64" type: %"PRIu8
ed5979
 vhost_vdpa_listener_begin_batch(void *v, int fd, uint32_t msg_type, uint8_t type)  "vdpa:%p fd: %d msg_type: %"PRIu32" type: %"PRIu8
ed5979
 vhost_vdpa_listener_commit(void *v, int fd, uint32_t msg_type, uint8_t type)  "vdpa:%p fd: %d msg_type: %"PRIu32" type: %"PRIu8
ed5979
 vhost_vdpa_listener_region_add(void *vdpa, uint64_t iova, uint64_t llend, void *vaddr, bool readonly) "vdpa: %p iova 0x%"PRIx64" llend 0x%"PRIx64" vaddr: %p read-only: %d"
ed5979
diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c
ed5979
index dd2768634b..0ecf2bbaa0 100644
ed5979
--- a/hw/virtio/vhost-vdpa.c
ed5979
+++ b/hw/virtio/vhost-vdpa.c
ed5979
@@ -72,22 +72,28 @@ static bool vhost_vdpa_listener_skipped_section(MemoryRegionSection *section,
ed5979
     return false;
ed5979
 }
ed5979
 
ed5979
-int vhost_vdpa_dma_map(struct vhost_vdpa *v, hwaddr iova, hwaddr size,
ed5979
-                       void *vaddr, bool readonly)
ed5979
+/*
ed5979
+ * The caller must set asid = 0 if the device does not support asid.
ed5979
+ * This is not an ABI break since it is set to 0 by the initializer anyway.
ed5979
+ */
ed5979
+int vhost_vdpa_dma_map(struct vhost_vdpa *v, uint32_t asid, hwaddr iova,
ed5979
+                       hwaddr size, void *vaddr, bool readonly)
ed5979
 {
ed5979
     struct vhost_msg_v2 msg = {};
ed5979
     int fd = v->device_fd;
ed5979
     int ret = 0;
ed5979
 
ed5979
     msg.type = v->msg_type;
ed5979
+    msg.asid = asid;
ed5979
     msg.iotlb.iova = iova;
ed5979
     msg.iotlb.size = size;
ed5979
     msg.iotlb.uaddr = (uint64_t)(uintptr_t)vaddr;
ed5979
     msg.iotlb.perm = readonly ? VHOST_ACCESS_RO : VHOST_ACCESS_RW;
ed5979
     msg.iotlb.type = VHOST_IOTLB_UPDATE;
ed5979
 
ed5979
-   trace_vhost_vdpa_dma_map(v, fd, msg.type, msg.iotlb.iova, msg.iotlb.size,
ed5979
-                            msg.iotlb.uaddr, msg.iotlb.perm, msg.iotlb.type);
ed5979
+    trace_vhost_vdpa_dma_map(v, fd, msg.type, msg.asid, msg.iotlb.iova,
ed5979
+                             msg.iotlb.size, msg.iotlb.uaddr, msg.iotlb.perm,
ed5979
+                             msg.iotlb.type);
ed5979
 
ed5979
     if (write(fd, &msg, sizeof(msg)) != sizeof(msg)) {
ed5979
         error_report("failed to write, fd=%d, errno=%d (%s)",
ed5979
@@ -98,18 +104,24 @@ int vhost_vdpa_dma_map(struct vhost_vdpa *v, hwaddr iova, hwaddr size,
ed5979
     return ret;
ed5979
 }
ed5979
 
ed5979
-int vhost_vdpa_dma_unmap(struct vhost_vdpa *v, hwaddr iova, hwaddr size)
ed5979
+/*
ed5979
+ * The caller must set asid = 0 if the device does not support asid.
ed5979
+ * This is not an ABI break since it is set to 0 by the initializer anyway.
ed5979
+ */
ed5979
+int vhost_vdpa_dma_unmap(struct vhost_vdpa *v, uint32_t asid, hwaddr iova,
ed5979
+                         hwaddr size)
ed5979
 {
ed5979
     struct vhost_msg_v2 msg = {};
ed5979
     int fd = v->device_fd;
ed5979
     int ret = 0;
ed5979
 
ed5979
     msg.type = v->msg_type;
ed5979
+    msg.asid = asid;
ed5979
     msg.iotlb.iova = iova;
ed5979
     msg.iotlb.size = size;
ed5979
     msg.iotlb.type = VHOST_IOTLB_INVALIDATE;
ed5979
 
ed5979
-    trace_vhost_vdpa_dma_unmap(v, fd, msg.type, msg.iotlb.iova,
ed5979
+    trace_vhost_vdpa_dma_unmap(v, fd, msg.type, msg.asid, msg.iotlb.iova,
ed5979
                                msg.iotlb.size, msg.iotlb.type);
ed5979
 
ed5979
     if (write(fd, &msg, sizeof(msg)) != sizeof(msg)) {
ed5979
@@ -229,8 +241,8 @@ static void vhost_vdpa_listener_region_add(MemoryListener *listener,
ed5979
     }
ed5979
 
ed5979
     vhost_vdpa_iotlb_batch_begin_once(v);
ed5979
-    ret = vhost_vdpa_dma_map(v, iova, int128_get64(llsize),
ed5979
-                             vaddr, section->readonly);
ed5979
+    ret = vhost_vdpa_dma_map(v, VHOST_VDPA_GUEST_PA_ASID, iova,
ed5979
+                             int128_get64(llsize), vaddr, section->readonly);
ed5979
     if (ret) {
ed5979
         error_report("vhost vdpa map fail!");
ed5979
         goto fail_map;
ed5979
@@ -303,7 +315,8 @@ static void vhost_vdpa_listener_region_del(MemoryListener *listener,
ed5979
         vhost_iova_tree_remove(v->iova_tree, *result);
ed5979
     }
ed5979
     vhost_vdpa_iotlb_batch_begin_once(v);
ed5979
-    ret = vhost_vdpa_dma_unmap(v, iova, int128_get64(llsize));
ed5979
+    ret = vhost_vdpa_dma_unmap(v, VHOST_VDPA_GUEST_PA_ASID, iova,
ed5979
+                               int128_get64(llsize));
ed5979
     if (ret) {
ed5979
         error_report("vhost_vdpa dma unmap error!");
ed5979
     }
ed5979
@@ -876,7 +889,7 @@ static void vhost_vdpa_svq_unmap_ring(struct vhost_vdpa *v, hwaddr addr)
ed5979
     }
ed5979
 
ed5979
     size = ROUND_UP(result->size, qemu_real_host_page_size());
ed5979
-    r = vhost_vdpa_dma_unmap(v, result->iova, size);
ed5979
+    r = vhost_vdpa_dma_unmap(v, v->address_space_id, result->iova, size);
ed5979
     if (unlikely(r < 0)) {
ed5979
         error_report("Unable to unmap SVQ vring: %s (%d)", g_strerror(-r), -r);
ed5979
         return;
ed5979
@@ -916,7 +929,8 @@ static bool vhost_vdpa_svq_map_ring(struct vhost_vdpa *v, DMAMap *needle,
ed5979
         return false;
ed5979
     }
ed5979
 
ed5979
-    r = vhost_vdpa_dma_map(v, needle->iova, needle->size + 1,
ed5979
+    r = vhost_vdpa_dma_map(v, v->address_space_id, needle->iova,
ed5979
+                           needle->size + 1,
ed5979
                            (void *)(uintptr_t)needle->translated_addr,
ed5979
                            needle->perm == IOMMU_RO);
ed5979
     if (unlikely(r != 0)) {
ed5979
diff --git a/include/hw/virtio/vhost-vdpa.h b/include/hw/virtio/vhost-vdpa.h
ed5979
index 1111d85643..e57dfa1fd1 100644
ed5979
--- a/include/hw/virtio/vhost-vdpa.h
ed5979
+++ b/include/hw/virtio/vhost-vdpa.h
ed5979
@@ -19,6 +19,12 @@
ed5979
 #include "hw/virtio/virtio.h"
ed5979
 #include "standard-headers/linux/vhost_types.h"
ed5979
 
ed5979
+/*
ed5979
+ * ASID dedicated to map guest's addresses.  If SVQ is disabled it maps GPA to
ed5979
+ * qemu's IOVA.  If SVQ is enabled it maps also the SVQ vring here
ed5979
+ */
ed5979
+#define VHOST_VDPA_GUEST_PA_ASID 0
ed5979
+
ed5979
 typedef struct VhostVDPAHostNotifier {
ed5979
     MemoryRegion mr;
ed5979
     void *addr;
ed5979
@@ -29,6 +35,7 @@ typedef struct vhost_vdpa {
ed5979
     int index;
ed5979
     uint32_t msg_type;
ed5979
     bool iotlb_batch_begin_sent;
ed5979
+    uint32_t address_space_id;
ed5979
     MemoryListener listener;
ed5979
     struct vhost_vdpa_iova_range iova_range;
ed5979
     uint64_t acked_features;
ed5979
@@ -42,8 +49,9 @@ typedef struct vhost_vdpa {
ed5979
     VhostVDPAHostNotifier notifier[VIRTIO_QUEUE_MAX];
ed5979
 } VhostVDPA;
ed5979
 
ed5979
-int vhost_vdpa_dma_map(struct vhost_vdpa *v, hwaddr iova, hwaddr size,
ed5979
-                       void *vaddr, bool readonly);
ed5979
-int vhost_vdpa_dma_unmap(struct vhost_vdpa *v, hwaddr iova, hwaddr size);
ed5979
+int vhost_vdpa_dma_map(struct vhost_vdpa *v, uint32_t asid, hwaddr iova,
ed5979
+                       hwaddr size, void *vaddr, bool readonly);
ed5979
+int vhost_vdpa_dma_unmap(struct vhost_vdpa *v, uint32_t asid, hwaddr iova,
ed5979
+                         hwaddr size);
ed5979
 
ed5979
 #endif
ed5979
diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c
ed5979
index 85aa0da39a..c2f319eb88 100644
ed5979
--- a/net/vhost-vdpa.c
ed5979
+++ b/net/vhost-vdpa.c
ed5979
@@ -258,7 +258,7 @@ static void vhost_vdpa_cvq_unmap_buf(struct vhost_vdpa *v, void *addr)
ed5979
         return;
ed5979
     }
ed5979
 
ed5979
-    r = vhost_vdpa_dma_unmap(v, map->iova, map->size + 1);
ed5979
+    r = vhost_vdpa_dma_unmap(v, v->address_space_id, map->iova, map->size + 1);
ed5979
     if (unlikely(r != 0)) {
ed5979
         error_report("Device cannot unmap: %s(%d)", g_strerror(r), r);
ed5979
     }
ed5979
@@ -298,8 +298,8 @@ static int vhost_vdpa_cvq_map_buf(struct vhost_vdpa *v, void *buf, size_t size,
ed5979
         return r;
ed5979
     }
ed5979
 
ed5979
-    r = vhost_vdpa_dma_map(v, map.iova, vhost_vdpa_net_cvq_cmd_page_len(), buf,
ed5979
-                           !write);
ed5979
+    r = vhost_vdpa_dma_map(v, v->address_space_id, map.iova,
ed5979
+                           vhost_vdpa_net_cvq_cmd_page_len(), buf, !write);
ed5979
     if (unlikely(r < 0)) {
ed5979
         goto dma_map_err;
ed5979
     }
ed5979
-- 
ed5979
2.31.1
ed5979