aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86')
-rw-r--r--arch/x86/include/asm/kvm_host.h2
-rw-r--r--arch/x86/kvm/svm.c13
-rw-r--r--arch/x86/kvm/vmx.c11
-rw-r--r--arch/x86/kvm/x86.c4
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 {
459struct kvm_x86_ops { 459struct 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
319static void svm_hardware_enable(void *garbage) 319static 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
355static void svm_cpu_uninit(int cpu) 360static 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
1141static void hardware_enable(void *garbage) 1141static 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
1163static void vmclear_local_vcpus(void) 1170static 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
4047out3: 4052out3:
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
4694void kvm_arch_hardware_enable(void *garbage) 4694int 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
4699void kvm_arch_hardware_disable(void *garbage) 4699void kvm_arch_hardware_disable(void *garbage)