Commit f53d9910 authored by Stefano Garzarella's avatar Stefano Garzarella Committed by Michael S. Tsirkin

vringh: add 'iotlb_lock' to synchronize iotlb accesses

Usually iotlb accesses are synchronized with a spinlock.
Let's request it as a new parameter in vringh_set_iotlb() and
hold it when we navigate the iotlb in iotlb_translate() to avoid
race conditions with any new additions/deletions of ranges from
the ioltb.
Acked-by: default avatarJason Wang <jasowang@redhat.com>
Signed-off-by: default avatarStefano Garzarella <sgarzare@redhat.com>
Link: https://lore.kernel.org/r/20210315163450.254396-3-sgarzare@redhat.comSigned-off-by: default avatarMichael S. Tsirkin <mst@redhat.com>
parent 4080fc10
...@@ -284,7 +284,8 @@ struct vdpasim *vdpasim_create(struct vdpasim_dev_attr *dev_attr) ...@@ -284,7 +284,8 @@ struct vdpasim *vdpasim_create(struct vdpasim_dev_attr *dev_attr)
goto err_iommu; goto err_iommu;
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); vringh_set_iotlb(&vdpasim->vqs[i].vring, vdpasim->iommu,
&vdpasim->iommu_lock);
ret = iova_cache_get(); ret = iova_cache_get();
if (ret) if (ret)
......
...@@ -1074,6 +1074,8 @@ static int iotlb_translate(const struct vringh *vrh, ...@@ -1074,6 +1074,8 @@ static int iotlb_translate(const struct vringh *vrh,
int ret = 0; int ret = 0;
u64 s = 0; u64 s = 0;
spin_lock(vrh->iotlb_lock);
while (len > s) { while (len > s) {
u64 size, pa, pfn; u64 size, pa, pfn;
...@@ -1103,6 +1105,8 @@ static int iotlb_translate(const struct vringh *vrh, ...@@ -1103,6 +1105,8 @@ static int iotlb_translate(const struct vringh *vrh,
++ret; ++ret;
} }
spin_unlock(vrh->iotlb_lock);
return ret; return ret;
} }
...@@ -1262,10 +1266,13 @@ EXPORT_SYMBOL(vringh_init_iotlb); ...@@ -1262,10 +1266,13 @@ EXPORT_SYMBOL(vringh_init_iotlb);
* vringh_set_iotlb - initialize a vringh for a ring with IOTLB. * vringh_set_iotlb - initialize a vringh for a ring with IOTLB.
* @vrh: the vring * @vrh: the vring
* @iotlb: iotlb associated with this vring * @iotlb: iotlb associated with this vring
* @iotlb_lock: spinlock to synchronize the iotlb accesses
*/ */
void vringh_set_iotlb(struct vringh *vrh, struct vhost_iotlb *iotlb) void vringh_set_iotlb(struct vringh *vrh, struct vhost_iotlb *iotlb,
spinlock_t *iotlb_lock)
{ {
vrh->iotlb = iotlb; vrh->iotlb = iotlb;
vrh->iotlb_lock = iotlb_lock;
} }
EXPORT_SYMBOL(vringh_set_iotlb); EXPORT_SYMBOL(vringh_set_iotlb);
......
...@@ -46,6 +46,9 @@ struct vringh { ...@@ -46,6 +46,9 @@ struct vringh {
/* IOTLB for this vring */ /* IOTLB for this vring */
struct vhost_iotlb *iotlb; struct vhost_iotlb *iotlb;
/* spinlock to synchronize IOTLB accesses */
spinlock_t *iotlb_lock;
/* The function to call to notify the guest about added buffers */ /* The function to call to notify the guest about added buffers */
void (*notify)(struct vringh *); void (*notify)(struct vringh *);
}; };
...@@ -258,7 +261,8 @@ static inline __virtio64 cpu_to_vringh64(const struct vringh *vrh, u64 val) ...@@ -258,7 +261,8 @@ static inline __virtio64 cpu_to_vringh64(const struct vringh *vrh, u64 val)
#if IS_REACHABLE(CONFIG_VHOST_IOTLB) #if IS_REACHABLE(CONFIG_VHOST_IOTLB)
void vringh_set_iotlb(struct vringh *vrh, struct vhost_iotlb *iotlb); void vringh_set_iotlb(struct vringh *vrh, struct vhost_iotlb *iotlb,
spinlock_t *iotlb_lock);
int vringh_init_iotlb(struct vringh *vrh, u64 features, int vringh_init_iotlb(struct vringh *vrh, u64 features,
unsigned int num, bool weak_barriers, unsigned int num, bool weak_barriers,
......
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