Merge tag 'kvm-3.10-2' of git://git.kernel.org/pub/scm/virt/kvm/kvm
[firefly-linux-kernel-4.4.55.git] / virt / kvm / kvm_main.c
index ae88b719bd2e477bbdb729f0b55555ebc869fcef..302681c4aa4465bb21b69524d7c0d3a5341f4a4e 100644 (file)
@@ -3105,13 +3105,21 @@ int kvm_init(void *opaque, unsigned vcpu_size, unsigned vcpu_align,
        int r;
        int cpu;
 
-       r = kvm_irqfd_init();
-       if (r)
-               goto out_irqfd;
        r = kvm_arch_init(opaque);
        if (r)
                goto out_fail;
 
+       /*
+        * kvm_arch_init makes sure there's at most one caller
+        * for architectures that support multiple implementations,
+        * like intel and amd on x86.
+        * kvm_arch_init must be called before kvm_irqfd_init to avoid creating
+        * conflicts in case kvm is already setup for another implementation.
+        */
+       r = kvm_irqfd_init();
+       if (r)
+               goto out_irqfd;
+
        if (!zalloc_cpumask_var(&cpus_hardware_enabled, GFP_KERNEL)) {
                r = -ENOMEM;
                goto out_free_0;
@@ -3186,10 +3194,10 @@ out_free_1:
 out_free_0a:
        free_cpumask_var(cpus_hardware_enabled);
 out_free_0:
-       kvm_arch_exit();
-out_fail:
        kvm_irqfd_exit();
 out_irqfd:
+       kvm_arch_exit();
+out_fail:
        return r;
 }
 EXPORT_SYMBOL_GPL(kvm_init);