diff options
Diffstat (limited to 'virt/kvm')
-rw-r--r-- | virt/kvm/kvm_main.c | 34 |
1 files changed, 22 insertions, 12 deletions
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index f69fca7a88b5..5156d458a84d 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c | |||
@@ -2059,7 +2059,7 @@ static struct miscdevice kvm_dev = { | |||
2059 | &kvm_chardev_ops, | 2059 | &kvm_chardev_ops, |
2060 | }; | 2060 | }; |
2061 | 2061 | ||
2062 | static void hardware_enable(void *junk) | 2062 | static void hardware_enable_nolock(void *junk) |
2063 | { | 2063 | { |
2064 | int cpu = raw_smp_processor_id(); | 2064 | int cpu = raw_smp_processor_id(); |
2065 | int r; | 2065 | int r; |
@@ -2079,7 +2079,14 @@ static void hardware_enable(void *junk) | |||
2079 | } | 2079 | } |
2080 | } | 2080 | } |
2081 | 2081 | ||
2082 | static void hardware_disable(void *junk) | 2082 | static void hardware_enable(void *junk) |
2083 | { | ||
2084 | spin_lock(&kvm_lock); | ||
2085 | hardware_enable_nolock(junk); | ||
2086 | spin_unlock(&kvm_lock); | ||
2087 | } | ||
2088 | |||
2089 | static void hardware_disable_nolock(void *junk) | ||
2083 | { | 2090 | { |
2084 | int cpu = raw_smp_processor_id(); | 2091 | int cpu = raw_smp_processor_id(); |
2085 | 2092 | ||
@@ -2089,13 +2096,20 @@ static void hardware_disable(void *junk) | |||
2089 | kvm_arch_hardware_disable(NULL); | 2096 | kvm_arch_hardware_disable(NULL); |
2090 | } | 2097 | } |
2091 | 2098 | ||
2099 | static void hardware_disable(void *junk) | ||
2100 | { | ||
2101 | spin_lock(&kvm_lock); | ||
2102 | hardware_disable_nolock(junk); | ||
2103 | spin_unlock(&kvm_lock); | ||
2104 | } | ||
2105 | |||
2092 | static void hardware_disable_all_nolock(void) | 2106 | static void hardware_disable_all_nolock(void) |
2093 | { | 2107 | { |
2094 | BUG_ON(!kvm_usage_count); | 2108 | BUG_ON(!kvm_usage_count); |
2095 | 2109 | ||
2096 | kvm_usage_count--; | 2110 | kvm_usage_count--; |
2097 | if (!kvm_usage_count) | 2111 | if (!kvm_usage_count) |
2098 | on_each_cpu(hardware_disable, NULL, 1); | 2112 | on_each_cpu(hardware_disable_nolock, NULL, 1); |
2099 | } | 2113 | } |
2100 | 2114 | ||
2101 | static void hardware_disable_all(void) | 2115 | static void hardware_disable_all(void) |
@@ -2114,7 +2128,7 @@ static int hardware_enable_all(void) | |||
2114 | kvm_usage_count++; | 2128 | kvm_usage_count++; |
2115 | if (kvm_usage_count == 1) { | 2129 | if (kvm_usage_count == 1) { |
2116 | atomic_set(&hardware_enable_failed, 0); | 2130 | atomic_set(&hardware_enable_failed, 0); |
2117 | on_each_cpu(hardware_enable, NULL, 1); | 2131 | on_each_cpu(hardware_enable_nolock, NULL, 1); |
2118 | 2132 | ||
2119 | if (atomic_read(&hardware_enable_failed)) { | 2133 | if (atomic_read(&hardware_enable_failed)) { |
2120 | hardware_disable_all_nolock(); | 2134 | hardware_disable_all_nolock(); |
@@ -2140,16 +2154,12 @@ static int kvm_cpu_hotplug(struct notifier_block *notifier, unsigned long val, | |||
2140 | case CPU_DYING: | 2154 | case CPU_DYING: |
2141 | printk(KERN_INFO "kvm: disabling virtualization on CPU%d\n", | 2155 | printk(KERN_INFO "kvm: disabling virtualization on CPU%d\n", |
2142 | cpu); | 2156 | cpu); |
2143 | spin_lock(&kvm_lock); | ||
2144 | hardware_disable(NULL); | 2157 | hardware_disable(NULL); |
2145 | spin_unlock(&kvm_lock); | ||
2146 | break; | 2158 | break; |
2147 | case CPU_STARTING: | 2159 | case CPU_STARTING: |
2148 | printk(KERN_INFO "kvm: enabling virtualization on CPU%d\n", | 2160 | printk(KERN_INFO "kvm: enabling virtualization on CPU%d\n", |
2149 | cpu); | 2161 | cpu); |
2150 | spin_lock(&kvm_lock); | ||
2151 | hardware_enable(NULL); | 2162 | hardware_enable(NULL); |
2152 | spin_unlock(&kvm_lock); | ||
2153 | break; | 2163 | break; |
2154 | } | 2164 | } |
2155 | return NOTIFY_OK; | 2165 | return NOTIFY_OK; |
@@ -2180,7 +2190,7 @@ static int kvm_reboot(struct notifier_block *notifier, unsigned long val, | |||
2180 | */ | 2190 | */ |
2181 | printk(KERN_INFO "kvm: exiting hardware virtualization\n"); | 2191 | printk(KERN_INFO "kvm: exiting hardware virtualization\n"); |
2182 | kvm_rebooting = true; | 2192 | kvm_rebooting = true; |
2183 | on_each_cpu(hardware_disable, NULL, 1); | 2193 | on_each_cpu(hardware_disable_nolock, NULL, 1); |
2184 | return NOTIFY_OK; | 2194 | return NOTIFY_OK; |
2185 | } | 2195 | } |
2186 | 2196 | ||
@@ -2350,7 +2360,7 @@ static void kvm_exit_debug(void) | |||
2350 | static int kvm_suspend(struct sys_device *dev, pm_message_t state) | 2360 | static int kvm_suspend(struct sys_device *dev, pm_message_t state) |
2351 | { | 2361 | { |
2352 | if (kvm_usage_count) | 2362 | if (kvm_usage_count) |
2353 | hardware_disable(NULL); | 2363 | hardware_disable_nolock(NULL); |
2354 | return 0; | 2364 | return 0; |
2355 | } | 2365 | } |
2356 | 2366 | ||
@@ -2358,7 +2368,7 @@ static int kvm_resume(struct sys_device *dev) | |||
2358 | { | 2368 | { |
2359 | if (kvm_usage_count) { | 2369 | if (kvm_usage_count) { |
2360 | WARN_ON(spin_is_locked(&kvm_lock)); | 2370 | WARN_ON(spin_is_locked(&kvm_lock)); |
2361 | hardware_enable(NULL); | 2371 | hardware_enable_nolock(NULL); |
2362 | } | 2372 | } |
2363 | return 0; | 2373 | return 0; |
2364 | } | 2374 | } |
@@ -2535,7 +2545,7 @@ void kvm_exit(void) | |||
2535 | sysdev_class_unregister(&kvm_sysdev_class); | 2545 | sysdev_class_unregister(&kvm_sysdev_class); |
2536 | unregister_reboot_notifier(&kvm_reboot_notifier); | 2546 | unregister_reboot_notifier(&kvm_reboot_notifier); |
2537 | unregister_cpu_notifier(&kvm_cpu_notifier); | 2547 | unregister_cpu_notifier(&kvm_cpu_notifier); |
2538 | on_each_cpu(hardware_disable, NULL, 1); | 2548 | on_each_cpu(hardware_disable_nolock, NULL, 1); |
2539 | kvm_arch_hardware_unsetup(); | 2549 | kvm_arch_hardware_unsetup(); |
2540 | kvm_arch_exit(); | 2550 | kvm_arch_exit(); |
2541 | free_cpumask_var(cpus_hardware_enabled); | 2551 | free_cpumask_var(cpus_hardware_enabled); |