aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm/svm.c
diff options
context:
space:
mode:
authorJoerg Roedel <joerg.roedel@amd.com>2008-07-02 10:02:11 -0400
committerAvi Kivity <avi@qumranet.com>2008-07-20 05:42:37 -0400
commit0da1db75a2feca54564add30828bab658982481c (patch)
tree7b4a148573e0e6df60682124b26de5d71af0fad3 /arch/x86/kvm/svm.c
parent180c12fb22bd17c7187ae1bce023d24a42b2980c (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>
Diffstat (limited to 'arch/x86/kvm/svm.c')
-rw-r--r--arch/x86/kvm/svm.c34
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
273static void svm_hardware_disable(void *garbage) 273static 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
290static void svm_hardware_enable(void *garbage) 282static 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
318static 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
326static int svm_cpu_init(int cpu) 331static 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
461static __exit void svm_hardware_unsetup(void) 466static __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}