|
@@ -696,6 +696,11 @@ static void kvm_destroy_devices(struct kvm *kvm)
|
|
|
{
|
|
|
struct kvm_device *dev, *tmp;
|
|
|
|
|
|
+ /*
|
|
|
+ * We do not need to take the kvm->lock here, because nobody else
|
|
|
+ * has a reference to the struct kvm at this point and therefore
|
|
|
+ * cannot access the devices list anyhow.
|
|
|
+ */
|
|
|
list_for_each_entry_safe(dev, tmp, &kvm->devices, vm_node) {
|
|
|
list_del(&dev->vm_node);
|
|
|
dev->ops->destroy(dev);
|
|
@@ -2832,11 +2837,15 @@ static int kvm_ioctl_create_device(struct kvm *kvm,
|
|
|
dev->ops = ops;
|
|
|
dev->kvm = kvm;
|
|
|
|
|
|
+ mutex_lock(&kvm->lock);
|
|
|
ret = ops->create(dev, cd->type);
|
|
|
if (ret < 0) {
|
|
|
+ mutex_unlock(&kvm->lock);
|
|
|
kfree(dev);
|
|
|
return ret;
|
|
|
}
|
|
|
+ list_add(&dev->vm_node, &kvm->devices);
|
|
|
+ mutex_unlock(&kvm->lock);
|
|
|
|
|
|
if (ops->init)
|
|
|
ops->init(dev);
|
|
@@ -2844,10 +2853,12 @@ static int kvm_ioctl_create_device(struct kvm *kvm,
|
|
|
ret = anon_inode_getfd(ops->name, &kvm_device_fops, dev, O_RDWR | O_CLOEXEC);
|
|
|
if (ret < 0) {
|
|
|
ops->destroy(dev);
|
|
|
+ mutex_lock(&kvm->lock);
|
|
|
+ list_del(&dev->vm_node);
|
|
|
+ mutex_unlock(&kvm->lock);
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
- list_add(&dev->vm_node, &kvm->devices);
|
|
|
kvm_get_kvm(kvm);
|
|
|
cd->fd = ret;
|
|
|
return 0;
|