|
@@ -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);
|