|
@@ -284,7 +284,7 @@ long vhost_dev_reset_owner(struct vhost_dev *dev)
|
|
|
vhost_dev_cleanup(dev);
|
|
|
|
|
|
memory->nregions = 0;
|
|
|
- dev->memory = memory;
|
|
|
+ RCU_INIT_POINTER(dev->memory, memory);
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -316,8 +316,9 @@ void vhost_dev_cleanup(struct vhost_dev *dev)
|
|
|
fput(dev->log_file);
|
|
|
dev->log_file = NULL;
|
|
|
/* No one will access memory at this point */
|
|
|
- kfree(dev->memory);
|
|
|
- dev->memory = NULL;
|
|
|
+ kfree(rcu_dereference_protected(dev->memory,
|
|
|
+ lockdep_is_held(&dev->mutex)));
|
|
|
+ RCU_INIT_POINTER(dev->memory, NULL);
|
|
|
if (dev->mm)
|
|
|
mmput(dev->mm);
|
|
|
dev->mm = NULL;
|
|
@@ -401,14 +402,22 @@ static int vq_access_ok(unsigned int num,
|
|
|
/* Caller should have device mutex but not vq mutex */
|
|
|
int vhost_log_access_ok(struct vhost_dev *dev)
|
|
|
{
|
|
|
- return memory_access_ok(dev, dev->memory, 1);
|
|
|
+ struct vhost_memory *mp;
|
|
|
+
|
|
|
+ mp = rcu_dereference_protected(dev->memory,
|
|
|
+ lockdep_is_held(&dev->mutex));
|
|
|
+ return memory_access_ok(dev, mp, 1);
|
|
|
}
|
|
|
|
|
|
/* Verify access for write logging. */
|
|
|
/* Caller should have vq mutex and device mutex */
|
|
|
static int vq_log_access_ok(struct vhost_virtqueue *vq, void __user *log_base)
|
|
|
{
|
|
|
- return vq_memory_access_ok(log_base, vq->dev->memory,
|
|
|
+ struct vhost_memory *mp;
|
|
|
+
|
|
|
+ mp = rcu_dereference_protected(vq->dev->memory,
|
|
|
+ lockdep_is_held(&vq->mutex));
|
|
|
+ return vq_memory_access_ok(log_base, mp,
|
|
|
vhost_has_feature(vq->dev, VHOST_F_LOG_ALL)) &&
|
|
|
(!vq->log_used || log_access_ok(log_base, vq->log_addr,
|
|
|
sizeof *vq->used +
|
|
@@ -448,7 +457,8 @@ static long vhost_set_memory(struct vhost_dev *d, struct vhost_memory __user *m)
|
|
|
kfree(newmem);
|
|
|
return -EFAULT;
|
|
|
}
|
|
|
- oldmem = d->memory;
|
|
|
+ oldmem = rcu_dereference_protected(d->memory,
|
|
|
+ lockdep_is_held(&d->mutex));
|
|
|
rcu_assign_pointer(d->memory, newmem);
|
|
|
synchronize_rcu();
|
|
|
kfree(oldmem);
|