diff options
Diffstat (limited to 'virt')
-rw-r--r-- | virt/kvm/arm/vgic.c | 11 | ||||
-rw-r--r-- | virt/kvm/kvm_main.c | 13 |
2 files changed, 14 insertions, 10 deletions
diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c index 24ac123f4ad8..7b490485712c 100644 --- a/virt/kvm/arm/vgic.c +++ b/virt/kvm/arm/vgic.c @@ -1624,12 +1624,8 @@ int kvm_vgic_create(struct kvm *kvm) int i, vcpu_lock_idx = -1, ret; struct kvm_vcpu *vcpu; - mutex_lock(&kvm->lock); - - if (kvm->arch.vgic.vctrl_base) { - ret = -EEXIST; - goto out; - } + if (kvm->arch.vgic.vctrl_base) + return -EEXIST; /* * Any time a vcpu is run, vcpu_load is called which tries to grab the @@ -1659,9 +1655,6 @@ out_unlock: vcpu = kvm_get_vcpu(kvm, vcpu_lock_idx); mutex_unlock(&vcpu->mutex); } - -out: - mutex_unlock(&kvm->lock); return ret; } diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index d98e6cf1e781..f8cbf5ba6136 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -587,6 +587,11 @@ static void kvm_destroy_devices(struct kvm *kvm) { struct list_head *node, *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_safe(node, tmp, &kvm->devices) { struct kvm_device *dev = list_entry(node, struct kvm_device, vm_node); @@ -2322,11 +2327,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); @@ -2334,10 +2343,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; |