diff options
Diffstat (limited to 'virt/kvm/kvm_main.c')
-rw-r--r-- | virt/kvm/kvm_main.c | 16 |
1 files changed, 15 insertions, 1 deletions
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index cc081ccfcaa3..195078225aa5 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c | |||
@@ -696,6 +696,11 @@ static void kvm_destroy_devices(struct kvm *kvm) | |||
696 | { | 696 | { |
697 | struct kvm_device *dev, *tmp; | 697 | struct kvm_device *dev, *tmp; |
698 | 698 | ||
699 | /* | ||
700 | * We do not need to take the kvm->lock here, because nobody else | ||
701 | * has a reference to the struct kvm at this point and therefore | ||
702 | * cannot access the devices list anyhow. | ||
703 | */ | ||
699 | list_for_each_entry_safe(dev, tmp, &kvm->devices, vm_node) { | 704 | list_for_each_entry_safe(dev, tmp, &kvm->devices, vm_node) { |
700 | list_del(&dev->vm_node); | 705 | list_del(&dev->vm_node); |
701 | dev->ops->destroy(dev); | 706 | dev->ops->destroy(dev); |
@@ -2832,19 +2837,28 @@ static int kvm_ioctl_create_device(struct kvm *kvm, | |||
2832 | dev->ops = ops; | 2837 | dev->ops = ops; |
2833 | dev->kvm = kvm; | 2838 | dev->kvm = kvm; |
2834 | 2839 | ||
2840 | mutex_lock(&kvm->lock); | ||
2835 | ret = ops->create(dev, cd->type); | 2841 | ret = ops->create(dev, cd->type); |
2836 | if (ret < 0) { | 2842 | if (ret < 0) { |
2843 | mutex_unlock(&kvm->lock); | ||
2837 | kfree(dev); | 2844 | kfree(dev); |
2838 | return ret; | 2845 | return ret; |
2839 | } | 2846 | } |
2847 | list_add(&dev->vm_node, &kvm->devices); | ||
2848 | mutex_unlock(&kvm->lock); | ||
2849 | |||
2850 | if (ops->init) | ||
2851 | ops->init(dev); | ||
2840 | 2852 | ||
2841 | ret = anon_inode_getfd(ops->name, &kvm_device_fops, dev, O_RDWR | O_CLOEXEC); | 2853 | ret = anon_inode_getfd(ops->name, &kvm_device_fops, dev, O_RDWR | O_CLOEXEC); |
2842 | if (ret < 0) { | 2854 | if (ret < 0) { |
2843 | ops->destroy(dev); | 2855 | ops->destroy(dev); |
2856 | mutex_lock(&kvm->lock); | ||
2857 | list_del(&dev->vm_node); | ||
2858 | mutex_unlock(&kvm->lock); | ||
2844 | return ret; | 2859 | return ret; |
2845 | } | 2860 | } |
2846 | 2861 | ||
2847 | list_add(&dev->vm_node, &kvm->devices); | ||
2848 | kvm_get_kvm(kvm); | 2862 | kvm_get_kvm(kvm); |
2849 | cd->fd = ret; | 2863 | cd->fd = ret; |
2850 | return 0; | 2864 | return 0; |