summaryrefslogtreecommitdiff
path: root/virt/kvm/kvm_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'virt/kvm/kvm_main.c')
-rw-r--r--virt/kvm/kvm_main.c41
1 files changed, 18 insertions, 23 deletions
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index d1ed34856412..bcfc0bc15153 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -102,7 +102,7 @@ EXPORT_SYMBOL_GPL(halt_poll_ns_shrink);
DEFINE_MUTEX(kvm_lock);
LIST_HEAD(vm_list);
-static cpumask_var_t cpus_hardware_enabled;
+static DEFINE_PER_CPU(bool, hardware_enabled);
static int kvm_usage_count;
static atomic_t hardware_enable_failed;
@@ -5096,21 +5096,17 @@ static struct miscdevice kvm_dev = {
static void hardware_enable_nolock(void *junk)
{
- int cpu = smp_processor_id();
- int r;
-
- if (cpumask_test_cpu(cpu, cpus_hardware_enabled))
+ if (__this_cpu_read(hardware_enabled))
return;
- cpumask_set_cpu(cpu, cpus_hardware_enabled);
-
- r = kvm_arch_hardware_enable();
-
- if (r) {
- cpumask_clear_cpu(cpu, cpus_hardware_enabled);
+ if (kvm_arch_hardware_enable()) {
atomic_inc(&hardware_enable_failed);
- pr_info("kvm: enabling virtualization on CPU%d failed\n", cpu);
+ pr_info("kvm: enabling virtualization on CPU%d failed\n",
+ raw_smp_processor_id());
+ return;
}
+
+ __this_cpu_write(hardware_enabled, true);
}
static int kvm_online_cpu(unsigned int cpu)
@@ -5139,12 +5135,16 @@ static int kvm_online_cpu(unsigned int cpu)
static void hardware_disable_nolock(void *junk)
{
- int cpu = smp_processor_id();
-
- if (!cpumask_test_cpu(cpu, cpus_hardware_enabled))
+ /*
+ * Note, hardware_disable_all_nolock() tells all online CPUs to disable
+ * hardware, not just CPUs that successfully enabled hardware!
+ */
+ if (!__this_cpu_read(hardware_enabled))
return;
- cpumask_clear_cpu(cpu, cpus_hardware_enabled);
+
kvm_arch_hardware_disable();
+
+ __this_cpu_write(hardware_enabled, false);
}
static int kvm_offline_cpu(unsigned int cpu)
@@ -5945,13 +5945,11 @@ int kvm_init(unsigned vcpu_size, unsigned vcpu_align, struct module *module)
int r;
int cpu;
- if (!zalloc_cpumask_var(&cpus_hardware_enabled, GFP_KERNEL))
- return -ENOMEM;
-
r = cpuhp_setup_state_nocalls(CPUHP_AP_KVM_ONLINE, "kvm/cpu:online",
kvm_online_cpu, kvm_offline_cpu);
if (r)
- goto out_free_2;
+ return r;
+
register_reboot_notifier(&kvm_reboot_notifier);
/* A kmem cache lets us meet the alignment requirements of fx_save. */
@@ -6024,8 +6022,6 @@ out_free_4:
out_free_3:
unregister_reboot_notifier(&kvm_reboot_notifier);
cpuhp_remove_state_nocalls(CPUHP_AP_KVM_ONLINE);
-out_free_2:
- free_cpumask_var(cpus_hardware_enabled);
return r;
}
EXPORT_SYMBOL_GPL(kvm_init);
@@ -6051,7 +6047,6 @@ void kvm_exit(void)
unregister_reboot_notifier(&kvm_reboot_notifier);
cpuhp_remove_state_nocalls(CPUHP_AP_KVM_ONLINE);
kvm_irqfd_exit();
- free_cpumask_var(cpus_hardware_enabled);
}
EXPORT_SYMBOL_GPL(kvm_exit);