summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--virt/kvm/kvm_main.c18
1 files changed, 13 insertions, 5 deletions
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 45f09362ee7b..8a1889ccb883 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -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);