diff options
-rw-r--r-- | drivers/kvm/kvm_main.c | 41 |
1 files changed, 40 insertions, 1 deletions
diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c index 291d298868fc..af866147ff25 100644 --- a/drivers/kvm/kvm_main.c +++ b/drivers/kvm/kvm_main.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/highmem.h> | 34 | #include <linux/highmem.h> |
35 | #include <linux/file.h> | 35 | #include <linux/file.h> |
36 | #include <asm/desc.h> | 36 | #include <asm/desc.h> |
37 | #include <linux/sysdev.h> | ||
37 | #include <linux/cpu.h> | 38 | #include <linux/cpu.h> |
38 | 39 | ||
39 | #include "x86_emulate.h" | 40 | #include "x86_emulate.h" |
@@ -2117,6 +2118,30 @@ static void kvm_exit_debug(void) | |||
2117 | debugfs_remove(debugfs_dir); | 2118 | debugfs_remove(debugfs_dir); |
2118 | } | 2119 | } |
2119 | 2120 | ||
2121 | static int kvm_suspend(struct sys_device *dev, pm_message_t state) | ||
2122 | { | ||
2123 | decache_vcpus_on_cpu(raw_smp_processor_id()); | ||
2124 | on_each_cpu(kvm_arch_ops->hardware_disable, 0, 0, 1); | ||
2125 | return 0; | ||
2126 | } | ||
2127 | |||
2128 | static int kvm_resume(struct sys_device *dev) | ||
2129 | { | ||
2130 | on_each_cpu(kvm_arch_ops->hardware_enable, 0, 0, 1); | ||
2131 | return 0; | ||
2132 | } | ||
2133 | |||
2134 | static struct sysdev_class kvm_sysdev_class = { | ||
2135 | set_kset_name("kvm"), | ||
2136 | .suspend = kvm_suspend, | ||
2137 | .resume = kvm_resume, | ||
2138 | }; | ||
2139 | |||
2140 | static struct sys_device kvm_sysdev = { | ||
2141 | .id = 0, | ||
2142 | .cls = &kvm_sysdev_class, | ||
2143 | }; | ||
2144 | |||
2120 | hpa_t bad_page_address; | 2145 | hpa_t bad_page_address; |
2121 | 2146 | ||
2122 | int kvm_init_arch(struct kvm_arch_ops *ops, struct module *module) | 2147 | int kvm_init_arch(struct kvm_arch_ops *ops, struct module *module) |
@@ -2149,6 +2174,14 @@ int kvm_init_arch(struct kvm_arch_ops *ops, struct module *module) | |||
2149 | goto out_free_1; | 2174 | goto out_free_1; |
2150 | register_reboot_notifier(&kvm_reboot_notifier); | 2175 | register_reboot_notifier(&kvm_reboot_notifier); |
2151 | 2176 | ||
2177 | r = sysdev_class_register(&kvm_sysdev_class); | ||
2178 | if (r) | ||
2179 | goto out_free_2; | ||
2180 | |||
2181 | r = sysdev_register(&kvm_sysdev); | ||
2182 | if (r) | ||
2183 | goto out_free_3; | ||
2184 | |||
2152 | kvm_chardev_ops.owner = module; | 2185 | kvm_chardev_ops.owner = module; |
2153 | 2186 | ||
2154 | r = misc_register(&kvm_dev); | 2187 | r = misc_register(&kvm_dev); |
@@ -2160,6 +2193,10 @@ int kvm_init_arch(struct kvm_arch_ops *ops, struct module *module) | |||
2160 | return r; | 2193 | return r; |
2161 | 2194 | ||
2162 | out_free: | 2195 | out_free: |
2196 | sysdev_unregister(&kvm_sysdev); | ||
2197 | out_free_3: | ||
2198 | sysdev_class_unregister(&kvm_sysdev_class); | ||
2199 | out_free_2: | ||
2163 | unregister_reboot_notifier(&kvm_reboot_notifier); | 2200 | unregister_reboot_notifier(&kvm_reboot_notifier); |
2164 | unregister_cpu_notifier(&kvm_cpu_notifier); | 2201 | unregister_cpu_notifier(&kvm_cpu_notifier); |
2165 | out_free_1: | 2202 | out_free_1: |
@@ -2171,8 +2208,10 @@ out_free_1: | |||
2171 | void kvm_exit_arch(void) | 2208 | void kvm_exit_arch(void) |
2172 | { | 2209 | { |
2173 | misc_deregister(&kvm_dev); | 2210 | misc_deregister(&kvm_dev); |
2174 | 2211 | sysdev_unregister(&kvm_sysdev); | |
2212 | sysdev_class_unregister(&kvm_sysdev_class); | ||
2175 | unregister_reboot_notifier(&kvm_reboot_notifier); | 2213 | unregister_reboot_notifier(&kvm_reboot_notifier); |
2214 | unregister_cpu_notifier(&kvm_cpu_notifier); | ||
2176 | on_each_cpu(kvm_arch_ops->hardware_disable, NULL, 0, 1); | 2215 | on_each_cpu(kvm_arch_ops->hardware_disable, NULL, 0, 1); |
2177 | kvm_arch_ops->hardware_unsetup(); | 2216 | kvm_arch_ops->hardware_unsetup(); |
2178 | kvm_arch_ops = NULL; | 2217 | kvm_arch_ops = NULL; |