diff options
Diffstat (limited to 'arch/x86')
-rw-r--r-- | arch/x86/include/asm/kvm_host.h | 2 | ||||
-rw-r--r-- | arch/x86/kvm/svm.c | 13 | ||||
-rw-r--r-- | arch/x86/kvm/vmx.c | 11 | ||||
-rw-r--r-- | arch/x86/kvm/x86.c | 4 |
4 files changed, 20 insertions, 10 deletions
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index a46e2dd9aca..295c7c4d9c9 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h | |||
@@ -459,7 +459,7 @@ struct descriptor_table { | |||
459 | struct kvm_x86_ops { | 459 | struct kvm_x86_ops { |
460 | int (*cpu_has_kvm_support)(void); /* __init */ | 460 | int (*cpu_has_kvm_support)(void); /* __init */ |
461 | int (*disabled_by_bios)(void); /* __init */ | 461 | int (*disabled_by_bios)(void); /* __init */ |
462 | void (*hardware_enable)(void *dummy); /* __init */ | 462 | int (*hardware_enable)(void *dummy); |
463 | void (*hardware_disable)(void *dummy); | 463 | void (*hardware_disable)(void *dummy); |
464 | void (*check_processor_compatibility)(void *rtn); | 464 | void (*check_processor_compatibility)(void *rtn); |
465 | int (*hardware_setup)(void); /* __init */ | 465 | int (*hardware_setup)(void); /* __init */ |
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) |
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 73cb5dd960c..a187570e483 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c | |||
@@ -1138,12 +1138,15 @@ static __init int vmx_disabled_by_bios(void) | |||
1138 | /* locked but not enabled */ | 1138 | /* locked but not enabled */ |
1139 | } | 1139 | } |
1140 | 1140 | ||
1141 | static void hardware_enable(void *garbage) | 1141 | static int hardware_enable(void *garbage) |
1142 | { | 1142 | { |
1143 | int cpu = raw_smp_processor_id(); | 1143 | int cpu = raw_smp_processor_id(); |
1144 | u64 phys_addr = __pa(per_cpu(vmxarea, cpu)); | 1144 | u64 phys_addr = __pa(per_cpu(vmxarea, cpu)); |
1145 | u64 old; | 1145 | u64 old; |
1146 | 1146 | ||
1147 | if (read_cr4() & X86_CR4_VMXE) | ||
1148 | return -EBUSY; | ||
1149 | |||
1147 | INIT_LIST_HEAD(&per_cpu(vcpus_on_cpu, cpu)); | 1150 | INIT_LIST_HEAD(&per_cpu(vcpus_on_cpu, cpu)); |
1148 | rdmsrl(MSR_IA32_FEATURE_CONTROL, old); | 1151 | rdmsrl(MSR_IA32_FEATURE_CONTROL, old); |
1149 | if ((old & (FEATURE_CONTROL_LOCKED | | 1152 | if ((old & (FEATURE_CONTROL_LOCKED | |
@@ -1158,6 +1161,10 @@ static void hardware_enable(void *garbage) | |||
1158 | asm volatile (ASM_VMX_VMXON_RAX | 1161 | asm volatile (ASM_VMX_VMXON_RAX |
1159 | : : "a"(&phys_addr), "m"(phys_addr) | 1162 | : : "a"(&phys_addr), "m"(phys_addr) |
1160 | : "memory", "cc"); | 1163 | : "memory", "cc"); |
1164 | |||
1165 | ept_sync_global(); | ||
1166 | |||
1167 | return 0; | ||
1161 | } | 1168 | } |
1162 | 1169 | ||
1163 | static void vmclear_local_vcpus(void) | 1170 | static void vmclear_local_vcpus(void) |
@@ -4040,8 +4047,6 @@ static int __init vmx_init(void) | |||
4040 | if (bypass_guest_pf) | 4047 | if (bypass_guest_pf) |
4041 | kvm_mmu_set_nonpresent_ptes(~0xffeull, 0ull); | 4048 | kvm_mmu_set_nonpresent_ptes(~0xffeull, 0ull); |
4042 | 4049 | ||
4043 | ept_sync_global(); | ||
4044 | |||
4045 | return 0; | 4050 | return 0; |
4046 | 4051 | ||
4047 | out3: | 4052 | out3: |
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 829e3063e2a..3d83de8bcbf 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c | |||
@@ -4691,9 +4691,9 @@ int kvm_arch_vcpu_reset(struct kvm_vcpu *vcpu) | |||
4691 | return kvm_x86_ops->vcpu_reset(vcpu); | 4691 | return kvm_x86_ops->vcpu_reset(vcpu); |
4692 | } | 4692 | } |
4693 | 4693 | ||
4694 | void kvm_arch_hardware_enable(void *garbage) | 4694 | int kvm_arch_hardware_enable(void *garbage) |
4695 | { | 4695 | { |
4696 | kvm_x86_ops->hardware_enable(garbage); | 4696 | return kvm_x86_ops->hardware_enable(garbage); |
4697 | } | 4697 | } |
4698 | 4698 | ||
4699 | void kvm_arch_hardware_disable(void *garbage) | 4699 | void kvm_arch_hardware_disable(void *garbage) |