aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm/vmx.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kvm/vmx.c')
-rw-r--r--arch/x86/kvm/vmx.c25
1 files changed, 14 insertions, 11 deletions
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index fff8e23433d6..b80b4d141637 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -30,6 +30,8 @@
30#include <asm/io.h> 30#include <asm/io.h>
31#include <asm/desc.h> 31#include <asm/desc.h>
32 32
33#define __ex(x) __kvm_handle_fault_on_reboot(x)
34
33MODULE_AUTHOR("Qumranet"); 35MODULE_AUTHOR("Qumranet");
34MODULE_LICENSE("GPL"); 36MODULE_LICENSE("GPL");
35 37
@@ -278,7 +280,7 @@ static inline void __invvpid(int ext, u16 vpid, gva_t gva)
278 u64 gva; 280 u64 gva;
279 } operand = { vpid, 0, gva }; 281 } operand = { vpid, 0, gva };
280 282
281 asm volatile (ASM_VMX_INVVPID 283 asm volatile (__ex(ASM_VMX_INVVPID)
282 /* CF==1 or ZF==1 --> rc = -1 */ 284 /* CF==1 or ZF==1 --> rc = -1 */
283 "; ja 1f ; ud2 ; 1:" 285 "; ja 1f ; ud2 ; 1:"
284 : : "a"(&operand), "c"(ext) : "cc", "memory"); 286 : : "a"(&operand), "c"(ext) : "cc", "memory");
@@ -290,7 +292,7 @@ static inline void __invept(int ext, u64 eptp, gpa_t gpa)
290 u64 eptp, gpa; 292 u64 eptp, gpa;
291 } operand = {eptp, gpa}; 293 } operand = {eptp, gpa};
292 294
293 asm volatile (ASM_VMX_INVEPT 295 asm volatile (__ex(ASM_VMX_INVEPT)
294 /* CF==1 or ZF==1 --> rc = -1 */ 296 /* CF==1 or ZF==1 --> rc = -1 */
295 "; ja 1f ; ud2 ; 1:\n" 297 "; ja 1f ; ud2 ; 1:\n"
296 : : "a" (&operand), "c" (ext) : "cc", "memory"); 298 : : "a" (&operand), "c" (ext) : "cc", "memory");
@@ -311,7 +313,7 @@ static void vmcs_clear(struct vmcs *vmcs)
311 u64 phys_addr = __pa(vmcs); 313 u64 phys_addr = __pa(vmcs);
312 u8 error; 314 u8 error;
313 315
314 asm volatile (ASM_VMX_VMCLEAR_RAX "; setna %0" 316 asm volatile (__ex(ASM_VMX_VMCLEAR_RAX) "; setna %0"
315 : "=g"(error) : "a"(&phys_addr), "m"(phys_addr) 317 : "=g"(error) : "a"(&phys_addr), "m"(phys_addr)
316 : "cc", "memory"); 318 : "cc", "memory");
317 if (error) 319 if (error)
@@ -378,7 +380,7 @@ static unsigned long vmcs_readl(unsigned long field)
378{ 380{
379 unsigned long value; 381 unsigned long value;
380 382
381 asm volatile (ASM_VMX_VMREAD_RDX_RAX 383 asm volatile (__ex(ASM_VMX_VMREAD_RDX_RAX)
382 : "=a"(value) : "d"(field) : "cc"); 384 : "=a"(value) : "d"(field) : "cc");
383 return value; 385 return value;
384} 386}
@@ -413,7 +415,7 @@ static void vmcs_writel(unsigned long field, unsigned long value)
413{ 415{
414 u8 error; 416 u8 error;
415 417
416 asm volatile (ASM_VMX_VMWRITE_RAX_RDX "; setna %0" 418 asm volatile (__ex(ASM_VMX_VMWRITE_RAX_RDX) "; setna %0"
417 : "=q"(error) : "a"(value), "d"(field) : "cc"); 419 : "=q"(error) : "a"(value), "d"(field) : "cc");
418 if (unlikely(error)) 420 if (unlikely(error))
419 vmwrite_error(field, value); 421 vmwrite_error(field, value);
@@ -621,7 +623,7 @@ static void vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
621 u8 error; 623 u8 error;
622 624
623 per_cpu(current_vmcs, cpu) = vmx->vmcs; 625 per_cpu(current_vmcs, cpu) = vmx->vmcs;
624 asm volatile (ASM_VMX_VMPTRLD_RAX "; setna %0" 626 asm volatile (__ex(ASM_VMX_VMPTRLD_RAX) "; setna %0"
625 : "=g"(error) : "a"(&phys_addr), "m"(phys_addr) 627 : "=g"(error) : "a"(&phys_addr), "m"(phys_addr)
626 : "cc"); 628 : "cc");
627 if (error) 629 if (error)
@@ -1030,13 +1032,14 @@ static void hardware_enable(void *garbage)
1030 MSR_IA32_FEATURE_CONTROL_LOCKED | 1032 MSR_IA32_FEATURE_CONTROL_LOCKED |
1031 MSR_IA32_FEATURE_CONTROL_VMXON_ENABLED); 1033 MSR_IA32_FEATURE_CONTROL_VMXON_ENABLED);
1032 write_cr4(read_cr4() | X86_CR4_VMXE); /* FIXME: not cpu hotplug safe */ 1034 write_cr4(read_cr4() | X86_CR4_VMXE); /* FIXME: not cpu hotplug safe */
1033 asm volatile (ASM_VMX_VMXON_RAX : : "a"(&phys_addr), "m"(phys_addr) 1035 asm volatile (ASM_VMX_VMXON_RAX
1036 : : "a"(&phys_addr), "m"(phys_addr)
1034 : "memory", "cc"); 1037 : "memory", "cc");
1035} 1038}
1036 1039
1037static void hardware_disable(void *garbage) 1040static void hardware_disable(void *garbage)
1038{ 1041{
1039 asm volatile (ASM_VMX_VMXOFF : : : "cc"); 1042 asm volatile (__ex(ASM_VMX_VMXOFF) : : : "cc");
1040 write_cr4(read_cr4() & ~X86_CR4_VMXE); 1043 write_cr4(read_cr4() & ~X86_CR4_VMXE);
1041} 1044}
1042 1045
@@ -2834,7 +2837,7 @@ static void vmx_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
2834 "push %%edx; push %%ebp;" 2837 "push %%edx; push %%ebp;"
2835 "push %%ecx \n\t" 2838 "push %%ecx \n\t"
2836#endif 2839#endif
2837 ASM_VMX_VMWRITE_RSP_RDX "\n\t" 2840 __ex(ASM_VMX_VMWRITE_RSP_RDX) "\n\t"
2838 /* Check if vmlaunch of vmresume is needed */ 2841 /* Check if vmlaunch of vmresume is needed */
2839 "cmpl $0, %c[launched](%0) \n\t" 2842 "cmpl $0, %c[launched](%0) \n\t"
2840 /* Load guest registers. Don't clobber flags. */ 2843 /* Load guest registers. Don't clobber flags. */
@@ -2869,9 +2872,9 @@ static void vmx_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
2869#endif 2872#endif
2870 /* Enter guest mode */ 2873 /* Enter guest mode */
2871 "jne .Llaunched \n\t" 2874 "jne .Llaunched \n\t"
2872 ASM_VMX_VMLAUNCH "\n\t" 2875 __ex(ASM_VMX_VMLAUNCH) "\n\t"
2873 "jmp .Lkvm_vmx_return \n\t" 2876 "jmp .Lkvm_vmx_return \n\t"
2874 ".Llaunched: " ASM_VMX_VMRESUME "\n\t" 2877 ".Llaunched: " __ex(ASM_VMX_VMRESUME) "\n\t"
2875 ".Lkvm_vmx_return: " 2878 ".Lkvm_vmx_return: "
2876 /* Save guest registers, load host registers, keep flags */ 2879 /* Save guest registers, load host registers, keep flags */
2877#ifdef CONFIG_X86_64 2880#ifdef CONFIG_X86_64