diff options
author | Joerg Roedel <joerg.roedel@amd.com> | 2008-07-02 10:02:11 -0400 |
---|---|---|
committer | Avi Kivity <avi@qumranet.com> | 2008-07-20 05:42:37 -0400 |
commit | 0da1db75a2feca54564add30828bab658982481c (patch) | |
tree | 7b4a148573e0e6df60682124b26de5d71af0fad3 | |
parent | 180c12fb22bd17c7187ae1bce023d24a42b2980c (diff) |
KVM: SVM: fix suspend/resume support
On suspend the svm_hardware_disable function is called which frees all svm_data
variables. On resume they are not re-allocated. This patch removes the
deallocation of svm_data from the hardware_disable function to the
hardware_unsetup function which is not called on suspend.
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
-rw-r--r-- | arch/x86/kvm/svm.c | 34 |
1 files changed, 22 insertions, 12 deletions
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 238e8f3afaf4..858e29702232 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c | |||
@@ -272,19 +272,11 @@ static int has_svm(void) | |||
272 | 272 | ||
273 | static void svm_hardware_disable(void *garbage) | 273 | static void svm_hardware_disable(void *garbage) |
274 | { | 274 | { |
275 | struct svm_cpu_data *svm_data | 275 | uint64_t efer; |
276 | = per_cpu(svm_data, raw_smp_processor_id()); | ||
277 | |||
278 | if (svm_data) { | ||
279 | uint64_t efer; | ||
280 | 276 | ||
281 | wrmsrl(MSR_VM_HSAVE_PA, 0); | 277 | wrmsrl(MSR_VM_HSAVE_PA, 0); |
282 | rdmsrl(MSR_EFER, efer); | 278 | rdmsrl(MSR_EFER, efer); |
283 | wrmsrl(MSR_EFER, efer & ~MSR_EFER_SVME_MASK); | 279 | wrmsrl(MSR_EFER, efer & ~MSR_EFER_SVME_MASK); |
284 | per_cpu(svm_data, raw_smp_processor_id()) = NULL; | ||
285 | __free_page(svm_data->save_area); | ||
286 | kfree(svm_data); | ||
287 | } | ||
288 | } | 280 | } |
289 | 281 | ||
290 | static void svm_hardware_enable(void *garbage) | 282 | static void svm_hardware_enable(void *garbage) |
@@ -323,6 +315,19 @@ static void svm_hardware_enable(void *garbage) | |||
323 | page_to_pfn(svm_data->save_area) << PAGE_SHIFT); | 315 | page_to_pfn(svm_data->save_area) << PAGE_SHIFT); |
324 | } | 316 | } |
325 | 317 | ||
318 | static void svm_cpu_uninit(int cpu) | ||
319 | { | ||
320 | struct svm_cpu_data *svm_data | ||
321 | = per_cpu(svm_data, raw_smp_processor_id()); | ||
322 | |||
323 | if (!svm_data) | ||
324 | return; | ||
325 | |||
326 | per_cpu(svm_data, raw_smp_processor_id()) = NULL; | ||
327 | __free_page(svm_data->save_area); | ||
328 | kfree(svm_data); | ||
329 | } | ||
330 | |||
326 | static int svm_cpu_init(int cpu) | 331 | static int svm_cpu_init(int cpu) |
327 | { | 332 | { |
328 | struct svm_cpu_data *svm_data; | 333 | struct svm_cpu_data *svm_data; |
@@ -460,6 +465,11 @@ err: | |||
460 | 465 | ||
461 | static __exit void svm_hardware_unsetup(void) | 466 | static __exit void svm_hardware_unsetup(void) |
462 | { | 467 | { |
468 | int cpu; | ||
469 | |||
470 | for_each_online_cpu(cpu) | ||
471 | svm_cpu_uninit(cpu); | ||
472 | |||
463 | __free_pages(pfn_to_page(iopm_base >> PAGE_SHIFT), IOPM_ALLOC_ORDER); | 473 | __free_pages(pfn_to_page(iopm_base >> PAGE_SHIFT), IOPM_ALLOC_ORDER); |
464 | iopm_base = 0; | 474 | iopm_base = 0; |
465 | } | 475 | } |