diff mbox series

[RFC,v3,16/29] vhost-vdpa: Add vhost_vdpa_enable_custom_iommu

Message ID 20210519162903.1172366-17-eperezma@redhat.com (mailing list archive)
State New, archived
Headers show
Series vDPA software assisted live migration | expand

Commit Message

Eugenio Perez Martin May 19, 2021, 4:28 p.m. UTC
Implementation of vhost_ops->enable_custom_iommu

Signed-off-by: Eugenio PĂ©rez <eperezma@redhat.com>
---
 hw/virtio/vhost-vdpa.c | 31 +++++++++++++++++++++++++++----
 1 file changed, 27 insertions(+), 4 deletions(-)
diff mbox series

Patch

diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c
index 74fe92935e..9e7a0ce5e0 100644
--- a/hw/virtio/vhost-vdpa.c
+++ b/hw/virtio/vhost-vdpa.c
@@ -272,6 +272,29 @@  static void vhost_vdpa_add_status(struct vhost_dev *dev, uint8_t status)
     vhost_vdpa_call(dev, VHOST_VDPA_SET_STATUS, &s);
 }
 
+static int vhost_vdpa_enable_custom_iommu(struct vhost_dev *dev, bool enable)
+{
+    struct vhost_vdpa *v = dev->opaque;
+    hwaddr iova_range_last = dev->iova_range.last;
+    if (iova_range_last != (hwaddr)-1) {
+        iova_range_last++;
+    }
+
+    if (enable) {
+        int r = vhost_vdpa_dma_unmap(v, dev->iova_range.first, iova_range_last);
+        if (r != 0) {
+            error_report("Fail to invalidate device iotlb");
+        }
+
+        memory_listener_register(&v->listener, &address_space_memory);
+    } else {
+        memory_listener_unregister(&v->listener);
+        return vhost_vdpa_dma_unmap(v, dev->iova_range.first, iova_range_last);
+    }
+
+    return 0;
+}
+
 static int vhost_vdpa_init(struct vhost_dev *dev, void *opaque)
 {
     struct vhost_vdpa *v;
@@ -299,7 +322,7 @@  static int vhost_vdpa_cleanup(struct vhost_dev *dev)
     assert(dev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_VDPA);
     v = dev->opaque;
     trace_vhost_vdpa_cleanup(dev, v);
-    memory_listener_unregister(&v->listener);
+    vhost_vdpa_enable_custom_iommu(dev, false);
 
     dev->opaque = NULL;
     return 0;
@@ -470,11 +493,10 @@  static int vhost_vdpa_get_config(struct vhost_dev *dev, uint8_t *config,
 
 static int vhost_vdpa_dev_start(struct vhost_dev *dev, bool started)
 {
-    struct vhost_vdpa *v = dev->opaque;
     trace_vhost_vdpa_dev_start(dev, started);
     if (started) {
         uint8_t status = 0;
-        memory_listener_register(&v->listener, &address_space_memory);
+        vhost_vdpa_enable_custom_iommu(dev, true);
         vhost_vdpa_set_vring_ready(dev);
         vhost_vdpa_add_status(dev, VIRTIO_CONFIG_S_DRIVER_OK);
         vhost_vdpa_call(dev, VHOST_VDPA_GET_STATUS, &status);
@@ -484,7 +506,7 @@  static int vhost_vdpa_dev_start(struct vhost_dev *dev, bool started)
         vhost_vdpa_reset_device(dev);
         vhost_vdpa_add_status(dev, VIRTIO_CONFIG_S_ACKNOWLEDGE |
                                    VIRTIO_CONFIG_S_DRIVER);
-        memory_listener_unregister(&v->listener);
+        vhost_vdpa_enable_custom_iommu(dev, false);
 
         return 0;
     }
@@ -628,5 +650,6 @@  const VhostOps vdpa_ops = {
         .vhost_get_device_id = vhost_vdpa_get_device_id,
         .vhost_vq_get_addr = vhost_vdpa_vq_get_addr,
         .vhost_force_iommu = vhost_vdpa_force_iommu,
+        .vhost_enable_custom_iommu = vhost_vdpa_enable_custom_iommu,
         .vhost_get_iova_range = vhost_vdpa_get_iova_range,
 };