Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm
[sfrench/cifs-2.6.git] / virt / kvm / kvm_main.c
index 0dfee7576e88c1bcee31707aaafe76f5552ada92..a852af5c3214d731a8cd7eb0290c79baa6d7072c 100644 (file)
@@ -154,10 +154,9 @@ static void kvm_uevent_notify_change(unsigned int type, struct kvm *kvm);
 static unsigned long long kvm_createvm_count;
 static unsigned long long kvm_active_vms;
 
-__weak int kvm_arch_mmu_notifier_invalidate_range(struct kvm *kvm,
-               unsigned long start, unsigned long end, bool blockable)
+__weak void kvm_arch_mmu_notifier_invalidate_range(struct kvm *kvm,
+                                                  unsigned long start, unsigned long end)
 {
-       return 0;
 }
 
 bool kvm_is_zone_device_pfn(kvm_pfn_t pfn)
@@ -383,6 +382,18 @@ static inline struct kvm *mmu_notifier_to_kvm(struct mmu_notifier *mn)
        return container_of(mn, struct kvm, mmu_notifier);
 }
 
+static void kvm_mmu_notifier_invalidate_range(struct mmu_notifier *mn,
+                                             struct mm_struct *mm,
+                                             unsigned long start, unsigned long end)
+{
+       struct kvm *kvm = mmu_notifier_to_kvm(mn);
+       int idx;
+
+       idx = srcu_read_lock(&kvm->srcu);
+       kvm_arch_mmu_notifier_invalidate_range(kvm, start, end);
+       srcu_read_unlock(&kvm->srcu, idx);
+}
+
 static void kvm_mmu_notifier_change_pte(struct mmu_notifier *mn,
                                        struct mm_struct *mm,
                                        unsigned long address,
@@ -407,7 +418,6 @@ static int kvm_mmu_notifier_invalidate_range_start(struct mmu_notifier *mn,
 {
        struct kvm *kvm = mmu_notifier_to_kvm(mn);
        int need_tlb_flush = 0, idx;
-       int ret;
 
        idx = srcu_read_lock(&kvm->srcu);
        spin_lock(&kvm->mmu_lock);
@@ -424,14 +434,9 @@ static int kvm_mmu_notifier_invalidate_range_start(struct mmu_notifier *mn,
                kvm_flush_remote_tlbs(kvm);
 
        spin_unlock(&kvm->mmu_lock);
-
-       ret = kvm_arch_mmu_notifier_invalidate_range(kvm, range->start,
-                                       range->end,
-                                       mmu_notifier_range_blockable(range));
-
        srcu_read_unlock(&kvm->srcu, idx);
 
-       return ret;
+       return 0;
 }
 
 static void kvm_mmu_notifier_invalidate_range_end(struct mmu_notifier *mn,
@@ -537,6 +542,7 @@ static void kvm_mmu_notifier_release(struct mmu_notifier *mn,
 }
 
 static const struct mmu_notifier_ops kvm_mmu_notifier_ops = {
+       .invalidate_range       = kvm_mmu_notifier_invalidate_range,
        .invalidate_range_start = kvm_mmu_notifier_invalidate_range_start,
        .invalidate_range_end   = kvm_mmu_notifier_invalidate_range_end,
        .clear_flush_young      = kvm_mmu_notifier_clear_flush_young,
@@ -2970,7 +2976,6 @@ static int kvm_vcpu_release(struct inode *inode, struct file *filp)
 {
        struct kvm_vcpu *vcpu = filp->private_data;
 
-       debugfs_remove_recursive(vcpu->debugfs_dentry);
        kvm_put_kvm(vcpu->kvm);
        return 0;
 }
@@ -2997,16 +3002,17 @@ static int create_vcpu_fd(struct kvm_vcpu *vcpu)
 static void kvm_create_vcpu_debugfs(struct kvm_vcpu *vcpu)
 {
 #ifdef __KVM_HAVE_ARCH_VCPU_DEBUGFS
+       struct dentry *debugfs_dentry;
        char dir_name[ITOA_MAX_LEN * 2];
 
        if (!debugfs_initialized())
                return;
 
        snprintf(dir_name, sizeof(dir_name), "vcpu%d", vcpu->vcpu_id);
-       vcpu->debugfs_dentry = debugfs_create_dir(dir_name,
-                                                 vcpu->kvm->debugfs_dentry);
+       debugfs_dentry = debugfs_create_dir(dir_name,
+                                           vcpu->kvm->debugfs_dentry);
 
-       kvm_arch_create_vcpu_debugfs(vcpu);
+       kvm_arch_create_vcpu_debugfs(vcpu, debugfs_dentry);
 #endif
 }
 
@@ -3743,21 +3749,18 @@ static long kvm_vm_ioctl(struct file *filp,
                if (routing.flags)
                        goto out;
                if (routing.nr) {
-                       r = -ENOMEM;
-                       entries = vmalloc(array_size(sizeof(*entries),
-                                                    routing.nr));
-                       if (!entries)
-                               goto out;
-                       r = -EFAULT;
                        urouting = argp;
-                       if (copy_from_user(entries, urouting->entries,
-                                          routing.nr * sizeof(*entries)))
-                               goto out_free_irq_routing;
+                       entries = vmemdup_user(urouting->entries,
+                                              array_size(sizeof(*entries),
+                                                         routing.nr));
+                       if (IS_ERR(entries)) {
+                               r = PTR_ERR(entries);
+                               goto out;
+                       }
                }
                r = kvm_set_irq_routing(kvm, entries, routing.nr,
                                        routing.flags);
-out_free_irq_routing:
-               vfree(entries);
+               kvfree(entries);
                break;
        }
 #endif /* CONFIG_HAVE_KVM_IRQ_ROUTING */