diff options
| -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); |
