aboutsummaryrefslogtreecommitdiffstats
path: root/virt/kvm
diff options
context:
space:
mode:
Diffstat (limited to 'virt/kvm')
-rw-r--r--virt/kvm/kvm_main.c34
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
2062static void hardware_enable(void *junk) 2062static 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
2082static void hardware_disable(void *junk) 2082static void hardware_enable(void *junk)
2083{
2084 spin_lock(&kvm_lock);
2085 hardware_enable_nolock(junk);
2086 spin_unlock(&kvm_lock);
2087}
2088
2089static 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
2099static void hardware_disable(void *junk)
2100{
2101 spin_lock(&kvm_lock);
2102 hardware_disable_nolock(junk);
2103 spin_unlock(&kvm_lock);
2104}
2105
2092static void hardware_disable_all_nolock(void) 2106static 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
2101static void hardware_disable_all(void) 2115static 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)
2350static int kvm_suspend(struct sys_device *dev, pm_message_t state) 2360static 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);