diff mbox series

[RFC,24/27] vhost: iommu changes

Message ID 20201120185105.279030-25-eperezma@redhat.com
State New
Headers show
Series vDPA software assisted live migration | expand

Commit Message

Eugenio Perez Martin Nov. 20, 2020, 6:51 p.m. UTC
Since vhost is now asking for qemu's VA, iommu needs to be bypassed.

Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
---
 hw/virtio/vhost.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

Comments

Stefan Hajnoczi Dec. 8, 2020, 9:02 a.m. UTC | #1
On Fri, Nov 20, 2020 at 07:51:02PM +0100, Eugenio Pérez wrote:
> diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
> index eebfac4455..cb44b9997f 100644
> --- a/hw/virtio/vhost.c
> +++ b/hw/virtio/vhost.c
> @@ -1109,6 +1109,10 @@ static int vhost_sw_live_migration_start(struct vhost_dev *dev)
>  
>      assert(dev->vhost_ops->vhost_set_vring_enable);
>      dev->vhost_ops->vhost_set_vring_enable(dev, false);
> +    if (vhost_dev_has_iommu(dev)) {
> +        r = vhost_backend_invalidate_device_iotlb(dev, 0, -1ULL);
> +        assert(r == 0);
> +    }
>  
>      for (idx = 0; idx < dev->nvqs; ++idx) {
>          struct vhost_virtqueue *vq = &dev->vqs[idx];
> @@ -1269,6 +1273,19 @@ int vhost_device_iotlb_miss(struct vhost_dev *dev, uint64_t iova, int write)
>  
>      trace_vhost_iotlb_miss(dev, 1);
>  
> +    if (dev->sw_lm_enabled) {
> +        uaddr = iova;
> +        len = 4096;
> +        ret = vhost_backend_update_device_iotlb(dev, iova, uaddr, len,
> +                                                IOMMU_RW);

It would be nice to look up the available memory so
vhost_backend_update_device_iotlb() can be called with a much bigger
[uaddr, uaddr+len) range. This will reduce the number of iotlb misses.

Will vIOMMU be required for this feature? If not, then the vring needs
to be added to the vhost memory regions because vhost will not send QEMU
iotlb misses.
diff mbox series

Patch

diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index eebfac4455..cb44b9997f 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -1109,6 +1109,10 @@  static int vhost_sw_live_migration_start(struct vhost_dev *dev)
 
     assert(dev->vhost_ops->vhost_set_vring_enable);
     dev->vhost_ops->vhost_set_vring_enable(dev, false);
+    if (vhost_dev_has_iommu(dev)) {
+        r = vhost_backend_invalidate_device_iotlb(dev, 0, -1ULL);
+        assert(r == 0);
+    }
 
     for (idx = 0; idx < dev->nvqs; ++idx) {
         struct vhost_virtqueue *vq = &dev->vqs[idx];
@@ -1269,6 +1273,19 @@  int vhost_device_iotlb_miss(struct vhost_dev *dev, uint64_t iova, int write)
 
     trace_vhost_iotlb_miss(dev, 1);
 
+    if (dev->sw_lm_enabled) {
+        uaddr = iova;
+        len = 4096;
+        ret = vhost_backend_update_device_iotlb(dev, iova, uaddr, len,
+                                                IOMMU_RW);
+        if (ret) {
+            trace_vhost_iotlb_miss(dev, 2);
+            error_report("Fail to update device iotlb");
+        }
+
+        return ret;
+    }
+
     iotlb = address_space_get_iotlb_entry(dev->vdev->dma_as,
                                           iova, write,
                                           MEMTXATTRS_UNSPECIFIED);