diff options
Diffstat (limited to 'arch/x86/kvm/svm.c')
-rw-r--r-- | arch/x86/kvm/svm.c | 13 |
1 files changed, 9 insertions, 4 deletions
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index f54c4f9d286..59fe4d54da1 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c | |||
@@ -316,7 +316,7 @@ static void svm_hardware_disable(void *garbage) | |||
316 | cpu_svm_disable(); | 316 | cpu_svm_disable(); |
317 | } | 317 | } |
318 | 318 | ||
319 | static void svm_hardware_enable(void *garbage) | 319 | static int svm_hardware_enable(void *garbage) |
320 | { | 320 | { |
321 | 321 | ||
322 | struct svm_cpu_data *svm_data; | 322 | struct svm_cpu_data *svm_data; |
@@ -325,16 +325,20 @@ static void svm_hardware_enable(void *garbage) | |||
325 | struct desc_struct *gdt; | 325 | struct desc_struct *gdt; |
326 | int me = raw_smp_processor_id(); | 326 | int me = raw_smp_processor_id(); |
327 | 327 | ||
328 | rdmsrl(MSR_EFER, efer); | ||
329 | if (efer & EFER_SVME) | ||
330 | return -EBUSY; | ||
331 | |||
328 | if (!has_svm()) { | 332 | if (!has_svm()) { |
329 | printk(KERN_ERR "svm_cpu_init: err EOPNOTSUPP on %d\n", me); | 333 | printk(KERN_ERR "svm_cpu_init: err EOPNOTSUPP on %d\n", me); |
330 | return; | 334 | return -EINVAL; |
331 | } | 335 | } |
332 | svm_data = per_cpu(svm_data, me); | 336 | svm_data = per_cpu(svm_data, me); |
333 | 337 | ||
334 | if (!svm_data) { | 338 | if (!svm_data) { |
335 | printk(KERN_ERR "svm_cpu_init: svm_data is NULL on %d\n", | 339 | printk(KERN_ERR "svm_cpu_init: svm_data is NULL on %d\n", |
336 | me); | 340 | me); |
337 | return; | 341 | return -EINVAL; |
338 | } | 342 | } |
339 | 343 | ||
340 | svm_data->asid_generation = 1; | 344 | svm_data->asid_generation = 1; |
@@ -345,11 +349,12 @@ static void svm_hardware_enable(void *garbage) | |||
345 | gdt = (struct desc_struct *)gdt_descr.base; | 349 | gdt = (struct desc_struct *)gdt_descr.base; |
346 | svm_data->tss_desc = (struct kvm_ldttss_desc *)(gdt + GDT_ENTRY_TSS); | 350 | svm_data->tss_desc = (struct kvm_ldttss_desc *)(gdt + GDT_ENTRY_TSS); |
347 | 351 | ||
348 | rdmsrl(MSR_EFER, efer); | ||
349 | wrmsrl(MSR_EFER, efer | EFER_SVME); | 352 | wrmsrl(MSR_EFER, efer | EFER_SVME); |
350 | 353 | ||
351 | wrmsrl(MSR_VM_HSAVE_PA, | 354 | wrmsrl(MSR_VM_HSAVE_PA, |
352 | page_to_pfn(svm_data->save_area) << PAGE_SHIFT); | 355 | page_to_pfn(svm_data->save_area) << PAGE_SHIFT); |
356 | |||
357 | return 0; | ||
353 | } | 358 | } |
354 | 359 | ||
355 | static void svm_cpu_uninit(int cpu) | 360 | static void svm_cpu_uninit(int cpu) |