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 | } |
