Merge tag 'drm-fixes-for-v4.16-rc2' of git://people.freedesktop.org/~airlied/linux
[sfrench/cifs-2.6.git] / virt / kvm / kvm_main.c
index 001085b611ad8f866f4c3c9a74549ad2852ac6c3..4501e658e8d6fc97f39b54bceff8f8b1f36cb95a 100644 (file)
@@ -151,17 +151,12 @@ bool kvm_is_reserved_pfn(kvm_pfn_t pfn)
 /*
  * Switches to specified vcpu, until a matching vcpu_put()
  */
-int vcpu_load(struct kvm_vcpu *vcpu)
+void vcpu_load(struct kvm_vcpu *vcpu)
 {
-       int cpu;
-
-       if (mutex_lock_killable(&vcpu->mutex))
-               return -EINTR;
-       cpu = get_cpu();
+       int cpu = get_cpu();
        preempt_notifier_register(&vcpu->preempt_notifier);
        kvm_arch_vcpu_load(vcpu, cpu);
        put_cpu();
-       return 0;
 }
 EXPORT_SYMBOL_GPL(vcpu_load);
 
@@ -171,7 +166,6 @@ void vcpu_put(struct kvm_vcpu *vcpu)
        kvm_arch_vcpu_put(vcpu);
        preempt_notifier_unregister(&vcpu->preempt_notifier);
        preempt_enable();
-       mutex_unlock(&vcpu->mutex);
 }
 EXPORT_SYMBOL_GPL(vcpu_put);
 
@@ -1416,7 +1410,8 @@ static bool vma_is_valid(struct vm_area_struct *vma, bool write_fault)
 
 static int hva_to_pfn_remapped(struct vm_area_struct *vma,
                               unsigned long addr, bool *async,
-                              bool write_fault, kvm_pfn_t *p_pfn)
+                              bool write_fault, bool *writable,
+                              kvm_pfn_t *p_pfn)
 {
        unsigned long pfn;
        int r;
@@ -1442,6 +1437,8 @@ static int hva_to_pfn_remapped(struct vm_area_struct *vma,
 
        }
 
+       if (writable)
+               *writable = true;
 
        /*
         * Get a reference here because callers of *hva_to_pfn* and
@@ -1507,7 +1504,7 @@ retry:
        if (vma == NULL)
                pfn = KVM_PFN_ERR_FAULT;
        else if (vma->vm_flags & (VM_IO | VM_PFNMAP)) {
-               r = hva_to_pfn_remapped(vma, addr, async, write_fault, &pfn);
+               r = hva_to_pfn_remapped(vma, addr, async, write_fault, writable, &pfn);
                if (r == -EAGAIN)
                        goto retry;
                if (r < 0)
@@ -2400,7 +2397,10 @@ static struct file_operations kvm_vcpu_fops = {
  */
 static int create_vcpu_fd(struct kvm_vcpu *vcpu)
 {
-       return anon_inode_getfd("kvm-vcpu", &kvm_vcpu_fops, vcpu, O_RDWR | O_CLOEXEC);
+       char name[8 + 1 + ITOA_MAX_LEN + 1];
+
+       snprintf(name, sizeof(name), "kvm-vcpu:%d", vcpu->vcpu_id);
+       return anon_inode_getfd(name, &kvm_vcpu_fops, vcpu, O_RDWR | O_CLOEXEC);
 }
 
 static int kvm_create_vcpu_debugfs(struct kvm_vcpu *vcpu)
@@ -2532,19 +2532,16 @@ static long kvm_vcpu_ioctl(struct file *filp,
        if (unlikely(_IOC_TYPE(ioctl) != KVMIO))
                return -EINVAL;
 
-#if defined(CONFIG_S390) || defined(CONFIG_PPC) || defined(CONFIG_MIPS)
        /*
-        * Special cases: vcpu ioctls that are asynchronous to vcpu execution,
-        * so vcpu_load() would break it.
+        * Some architectures have vcpu ioctls that are asynchronous to vcpu
+        * execution; mutex_lock() would break them.
         */
-       if (ioctl == KVM_S390_INTERRUPT || ioctl == KVM_S390_IRQ || ioctl == KVM_INTERRUPT)
-               return kvm_arch_vcpu_ioctl(filp, ioctl, arg);
-#endif
-
-
-       r = vcpu_load(vcpu);
-       if (r)
+       r = kvm_arch_vcpu_async_ioctl(filp, ioctl, arg);
+       if (r != -ENOIOCTLCMD)
                return r;
+
+       if (mutex_lock_killable(&vcpu->mutex))
+               return -EINTR;
        switch (ioctl) {
        case KVM_RUN: {
                struct pid *oldpid;
@@ -2716,7 +2713,7 @@ out_free1:
                r = kvm_arch_vcpu_ioctl(filp, ioctl, arg);
        }
 out:
-       vcpu_put(vcpu);
+       mutex_unlock(&vcpu->mutex);
        kfree(fpu);
        kfree(kvm_sregs);
        return r;
@@ -3168,21 +3165,18 @@ static int kvm_dev_ioctl_create_vm(unsigned long type)
                return PTR_ERR(kvm);
 #ifdef CONFIG_KVM_MMIO
        r = kvm_coalesced_mmio_init(kvm);
-       if (r < 0) {
-               kvm_put_kvm(kvm);
-               return r;
-       }
+       if (r < 0)
+               goto put_kvm;
 #endif
        r = get_unused_fd_flags(O_CLOEXEC);
-       if (r < 0) {
-               kvm_put_kvm(kvm);
-               return r;
-       }
+       if (r < 0)
+               goto put_kvm;
+
        file = anon_inode_getfile("kvm-vm", &kvm_vm_fops, kvm, O_RDWR);
        if (IS_ERR(file)) {
                put_unused_fd(r);
-               kvm_put_kvm(kvm);
-               return PTR_ERR(file);
+               r = PTR_ERR(file);
+               goto put_kvm;
        }
 
        /*
@@ -3200,6 +3194,10 @@ static int kvm_dev_ioctl_create_vm(unsigned long type)
 
        fd_install(r, file);
        return r;
+
+put_kvm:
+       kvm_put_kvm(kvm);
+       return r;
 }
 
 static long kvm_dev_ioctl(struct file *filp,