[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH v4 1/2] vhost: register and change IOMMU flag depending on De
|
From: |
Jason Wang |
|
Subject: |
Re: [PATCH v4 1/2] vhost: register and change IOMMU flag depending on Device-TLB state |
|
Date: |
Fri, 26 May 2023 12:07:42 +0800 |
On Thu, May 25, 2023 at 8:58 PM Viktor Prutyanov <viktor@daynix.com> wrote:
>
> The guest can disable or never enable Device-TLB. In these cases,
> it can't be used even if enabled in QEMU. So, check Device-TLB state
> before registering IOMMU notifier and select unmap flag depending on
> that. Also, implement a way to change IOMMU notifier flag if Device-TLB
> state is changed.
>
> Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=2001312
> Signed-off-by: Viktor Prutyanov <viktor@daynix.com>
Acked-by: Jason Wang <jasowang@redhat.com>
Thanks
> ---
> hw/virtio/vhost.c | 38 ++++++++++++++++++++++++++------------
> include/hw/virtio/vhost.h | 1 +
> 2 files changed, 27 insertions(+), 12 deletions(-)
>
> diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
> index 23da579ce2..e48507b5a1 100644
> --- a/hw/virtio/vhost.c
> +++ b/hw/virtio/vhost.c
> @@ -781,7 +781,6 @@ static void vhost_iommu_region_add(MemoryListener
> *listener,
> Int128 end;
> int iommu_idx;
> IOMMUMemoryRegion *iommu_mr;
> - int ret;
>
> if (!memory_region_is_iommu(section->mr)) {
> return;
> @@ -796,7 +795,9 @@ static void vhost_iommu_region_add(MemoryListener
> *listener,
> iommu_idx = memory_region_iommu_attrs_to_index(iommu_mr,
> MEMTXATTRS_UNSPECIFIED);
> iommu_notifier_init(&iommu->n, vhost_iommu_unmap_notify,
> - IOMMU_NOTIFIER_DEVIOTLB_UNMAP,
> + dev->vdev->device_iotlb_enabled ?
> + IOMMU_NOTIFIER_DEVIOTLB_UNMAP :
> + IOMMU_NOTIFIER_UNMAP,
> section->offset_within_region,
> int128_get64(end),
> iommu_idx);
> @@ -804,16 +805,8 @@ static void vhost_iommu_region_add(MemoryListener
> *listener,
> iommu->iommu_offset = section->offset_within_address_space -
> section->offset_within_region;
> iommu->hdev = dev;
> - ret = memory_region_register_iommu_notifier(section->mr, &iommu->n,
> NULL);
> - if (ret) {
> - /*
> - * Some vIOMMUs do not support dev-iotlb yet. If so, try to use the
> - * UNMAP legacy message
> - */
> - iommu->n.notifier_flags = IOMMU_NOTIFIER_UNMAP;
> - memory_region_register_iommu_notifier(section->mr, &iommu->n,
> - &error_fatal);
> - }
> + memory_region_register_iommu_notifier(section->mr, &iommu->n,
> + &error_fatal);
> QLIST_INSERT_HEAD(&dev->iommu_list, iommu, iommu_next);
> /* TODO: can replay help performance here? */
> }
> @@ -841,6 +834,27 @@ static void vhost_iommu_region_del(MemoryListener
> *listener,
> }
> }
>
> +void vhost_toggle_device_iotlb(VirtIODevice *vdev)
> +{
> + VirtioDeviceClass *vdc = VIRTIO_DEVICE_GET_CLASS(vdev);
> + struct vhost_dev *dev;
> + struct vhost_iommu *iommu;
> +
> + if (vdev->vhost_started) {
> + dev = vdc->get_vhost(vdev);
> + } else {
> + return;
> + }
> +
> + QLIST_FOREACH(iommu, &dev->iommu_list, iommu_next) {
> + memory_region_unregister_iommu_notifier(iommu->mr, &iommu->n);
> + iommu->n.notifier_flags = vdev->device_iotlb_enabled ?
> + IOMMU_NOTIFIER_DEVIOTLB_UNMAP : IOMMU_NOTIFIER_UNMAP;
> + memory_region_register_iommu_notifier(iommu->mr, &iommu->n,
> + &error_fatal);
> + }
> +}
> +
> static int vhost_virtqueue_set_addr(struct vhost_dev *dev,
> struct vhost_virtqueue *vq,
> unsigned idx, bool enable_log)
> diff --git a/include/hw/virtio/vhost.h b/include/hw/virtio/vhost.h
> index f7f10c8fb7..6a173cb9fa 100644
> --- a/include/hw/virtio/vhost.h
> +++ b/include/hw/virtio/vhost.h
> @@ -320,6 +320,7 @@ bool vhost_has_free_slot(void);
> int vhost_net_set_backend(struct vhost_dev *hdev,
> struct vhost_vring_file *file);
>
> +void vhost_toggle_device_iotlb(VirtIODevice *vdev);
> int vhost_device_iotlb_miss(struct vhost_dev *dev, uint64_t iova, int write);
>
> int vhost_virtqueue_start(struct vhost_dev *dev, struct VirtIODevice *vdev,
> --
> 2.21.0
>