Commit 86f6c224 authored by Si-Wei Liu's avatar Si-Wei Liu Committed by Michael S. Tsirkin

vdpa_sim: implement .reset_map support

In order to reduce excessive memory mapping cost in live migration and
VM reboot, it is desirable to decouple the vhost-vdpa IOTLB abstraction
from the virtio device life cycle, i.e. mappings can be kept intact
across virtio device reset. Leverage the .reset_map callback, which is
meant to destroy the iotlb on the given ASID and recreate the 1:1
passthrough/identity mapping. To be consistent, the mapping on device
creation is initiailized to passthrough/identity with PA 1:1 mapped as
IOVA. With this the device .reset op doesn't have to maintain and clean
up memory mappings by itself.

Additionally, implement .compat_reset to cater for older userspace,
which may wish to see mapping to be cleared during reset.
Signed-off-by: default avatarSi-Wei Liu <si-wei.liu@oracle.com>
Tested-by: default avatarStefano Garzarella <sgarzare@redhat.com>
Message-Id: <1697880319-4937-8-git-send-email-si-wei.liu@oracle.com>
Signed-off-by: default avatarMichael S. Tsirkin <mst@redhat.com>
Tested-by: default avatarLei Yang <leiyang@redhat.com>
parent 2eacf4b5
...@@ -139,7 +139,7 @@ static void vdpasim_vq_reset(struct vdpasim *vdpasim, ...@@ -139,7 +139,7 @@ static void vdpasim_vq_reset(struct vdpasim *vdpasim,
vq->vring.notify = NULL; vq->vring.notify = NULL;
} }
static void vdpasim_do_reset(struct vdpasim *vdpasim) static void vdpasim_do_reset(struct vdpasim *vdpasim, u32 flags)
{ {
int i; int i;
...@@ -151,11 +151,13 @@ static void vdpasim_do_reset(struct vdpasim *vdpasim) ...@@ -151,11 +151,13 @@ static void vdpasim_do_reset(struct vdpasim *vdpasim)
&vdpasim->iommu_lock); &vdpasim->iommu_lock);
} }
for (i = 0; i < vdpasim->dev_attr.nas; i++) { if (flags & VDPA_RESET_F_CLEAN_MAP) {
vhost_iotlb_reset(&vdpasim->iommu[i]); for (i = 0; i < vdpasim->dev_attr.nas; i++) {
vhost_iotlb_add_range(&vdpasim->iommu[i], 0, ULONG_MAX, vhost_iotlb_reset(&vdpasim->iommu[i]);
0, VHOST_MAP_RW); vhost_iotlb_add_range(&vdpasim->iommu[i], 0, ULONG_MAX,
vdpasim->iommu_pt[i] = true; 0, VHOST_MAP_RW);
vdpasim->iommu_pt[i] = true;
}
} }
vdpasim->running = true; vdpasim->running = true;
...@@ -259,8 +261,12 @@ struct vdpasim *vdpasim_create(struct vdpasim_dev_attr *dev_attr, ...@@ -259,8 +261,12 @@ struct vdpasim *vdpasim_create(struct vdpasim_dev_attr *dev_attr,
if (!vdpasim->iommu_pt) if (!vdpasim->iommu_pt)
goto err_iommu; goto err_iommu;
for (i = 0; i < vdpasim->dev_attr.nas; i++) for (i = 0; i < vdpasim->dev_attr.nas; i++) {
vhost_iotlb_init(&vdpasim->iommu[i], max_iotlb_entries, 0); vhost_iotlb_init(&vdpasim->iommu[i], max_iotlb_entries, 0);
vhost_iotlb_add_range(&vdpasim->iommu[i], 0, ULONG_MAX, 0,
VHOST_MAP_RW);
vdpasim->iommu_pt[i] = true;
}
for (i = 0; i < dev_attr->nvqs; i++) for (i = 0; i < dev_attr->nvqs; i++)
vringh_set_iotlb(&vdpasim->vqs[i].vring, &vdpasim->iommu[0], vringh_set_iotlb(&vdpasim->vqs[i].vring, &vdpasim->iommu[0],
...@@ -480,18 +486,23 @@ static void vdpasim_set_status(struct vdpa_device *vdpa, u8 status) ...@@ -480,18 +486,23 @@ static void vdpasim_set_status(struct vdpa_device *vdpa, u8 status)
mutex_unlock(&vdpasim->mutex); mutex_unlock(&vdpasim->mutex);
} }
static int vdpasim_reset(struct vdpa_device *vdpa) static int vdpasim_compat_reset(struct vdpa_device *vdpa, u32 flags)
{ {
struct vdpasim *vdpasim = vdpa_to_sim(vdpa); struct vdpasim *vdpasim = vdpa_to_sim(vdpa);
mutex_lock(&vdpasim->mutex); mutex_lock(&vdpasim->mutex);
vdpasim->status = 0; vdpasim->status = 0;
vdpasim_do_reset(vdpasim); vdpasim_do_reset(vdpasim, flags);
mutex_unlock(&vdpasim->mutex); mutex_unlock(&vdpasim->mutex);
return 0; return 0;
} }
static int vdpasim_reset(struct vdpa_device *vdpa)
{
return vdpasim_compat_reset(vdpa, 0);
}
static int vdpasim_suspend(struct vdpa_device *vdpa) static int vdpasim_suspend(struct vdpa_device *vdpa)
{ {
struct vdpasim *vdpasim = vdpa_to_sim(vdpa); struct vdpasim *vdpasim = vdpa_to_sim(vdpa);
...@@ -637,6 +648,25 @@ static int vdpasim_set_map(struct vdpa_device *vdpa, unsigned int asid, ...@@ -637,6 +648,25 @@ static int vdpasim_set_map(struct vdpa_device *vdpa, unsigned int asid,
return ret; return ret;
} }
static int vdpasim_reset_map(struct vdpa_device *vdpa, unsigned int asid)
{
struct vdpasim *vdpasim = vdpa_to_sim(vdpa);
if (asid >= vdpasim->dev_attr.nas)
return -EINVAL;
spin_lock(&vdpasim->iommu_lock);
if (vdpasim->iommu_pt[asid])
goto out;
vhost_iotlb_reset(&vdpasim->iommu[asid]);
vhost_iotlb_add_range(&vdpasim->iommu[asid], 0, ULONG_MAX,
0, VHOST_MAP_RW);
vdpasim->iommu_pt[asid] = true;
out:
spin_unlock(&vdpasim->iommu_lock);
return 0;
}
static int vdpasim_bind_mm(struct vdpa_device *vdpa, struct mm_struct *mm) static int vdpasim_bind_mm(struct vdpa_device *vdpa, struct mm_struct *mm)
{ {
struct vdpasim *vdpasim = vdpa_to_sim(vdpa); struct vdpasim *vdpasim = vdpa_to_sim(vdpa);
...@@ -749,6 +779,7 @@ static const struct vdpa_config_ops vdpasim_config_ops = { ...@@ -749,6 +779,7 @@ static const struct vdpa_config_ops vdpasim_config_ops = {
.get_status = vdpasim_get_status, .get_status = vdpasim_get_status,
.set_status = vdpasim_set_status, .set_status = vdpasim_set_status,
.reset = vdpasim_reset, .reset = vdpasim_reset,
.compat_reset = vdpasim_compat_reset,
.suspend = vdpasim_suspend, .suspend = vdpasim_suspend,
.resume = vdpasim_resume, .resume = vdpasim_resume,
.get_config_size = vdpasim_get_config_size, .get_config_size = vdpasim_get_config_size,
...@@ -759,6 +790,7 @@ static const struct vdpa_config_ops vdpasim_config_ops = { ...@@ -759,6 +790,7 @@ static const struct vdpa_config_ops vdpasim_config_ops = {
.set_group_asid = vdpasim_set_group_asid, .set_group_asid = vdpasim_set_group_asid,
.dma_map = vdpasim_dma_map, .dma_map = vdpasim_dma_map,
.dma_unmap = vdpasim_dma_unmap, .dma_unmap = vdpasim_dma_unmap,
.reset_map = vdpasim_reset_map,
.bind_mm = vdpasim_bind_mm, .bind_mm = vdpasim_bind_mm,
.unbind_mm = vdpasim_unbind_mm, .unbind_mm = vdpasim_unbind_mm,
.free = vdpasim_free, .free = vdpasim_free,
...@@ -787,6 +819,7 @@ static const struct vdpa_config_ops vdpasim_batch_config_ops = { ...@@ -787,6 +819,7 @@ static const struct vdpa_config_ops vdpasim_batch_config_ops = {
.get_status = vdpasim_get_status, .get_status = vdpasim_get_status,
.set_status = vdpasim_set_status, .set_status = vdpasim_set_status,
.reset = vdpasim_reset, .reset = vdpasim_reset,
.compat_reset = vdpasim_compat_reset,
.suspend = vdpasim_suspend, .suspend = vdpasim_suspend,
.resume = vdpasim_resume, .resume = vdpasim_resume,
.get_config_size = vdpasim_get_config_size, .get_config_size = vdpasim_get_config_size,
...@@ -796,6 +829,7 @@ static const struct vdpa_config_ops vdpasim_batch_config_ops = { ...@@ -796,6 +829,7 @@ static const struct vdpa_config_ops vdpasim_batch_config_ops = {
.get_iova_range = vdpasim_get_iova_range, .get_iova_range = vdpasim_get_iova_range,
.set_group_asid = vdpasim_set_group_asid, .set_group_asid = vdpasim_set_group_asid,
.set_map = vdpasim_set_map, .set_map = vdpasim_set_map,
.reset_map = vdpasim_reset_map,
.bind_mm = vdpasim_bind_mm, .bind_mm = vdpasim_bind_mm,
.unbind_mm = vdpasim_unbind_mm, .unbind_mm = vdpasim_unbind_mm,
.free = vdpasim_free, .free = vdpasim_free,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment