aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm/vmx.c
diff options
context:
space:
mode:
authorAvi Kivity <avi@qumranet.com>2008-07-14 07:44:59 -0400
committerAvi Kivity <avi@qumranet.com>2008-10-15 04:15:14 -0400
commitc801949ddf0a51074937f488a52072825ed50174 (patch)
tree348a6ec407e4ab9495df203662200e31a60ccdc0 /arch/x86/kvm/vmx.c
parent77ab6db0a1c403387b403e9351ab3f5ae1df83e6 (diff)
KVM: VMX: Unify register save/restore across 32 and 64 bit hosts
Signed-off-by: Avi Kivity <avi@qumranet.com>
Diffstat (limited to 'arch/x86/kvm/vmx.c')
-rw-r--r--arch/x86/kvm/vmx.c90
1 files changed, 36 insertions, 54 deletions
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 2879880076d0..fc8996b1043b 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -2955,6 +2955,14 @@ static void fixup_rmode_irq(struct vcpu_vmx *vmx)
2955 | vmx->rmode.irq.vector; 2955 | vmx->rmode.irq.vector;
2956} 2956}
2957 2957
2958#ifdef CONFIG_X86_64
2959#define R "r"
2960#define Q "q"
2961#else
2962#define R "e"
2963#define Q "l"
2964#endif
2965
2958static void vmx_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) 2966static void vmx_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
2959{ 2967{
2960 struct vcpu_vmx *vmx = to_vmx(vcpu); 2968 struct vcpu_vmx *vmx = to_vmx(vcpu);
@@ -2972,26 +2980,21 @@ static void vmx_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
2972 2980
2973 asm( 2981 asm(
2974 /* Store host registers */ 2982 /* Store host registers */
2975#ifdef CONFIG_X86_64 2983 "push %%"R"dx; push %%"R"bp;"
2976 "push %%rdx; push %%rbp;" 2984 "push %%"R"cx \n\t"
2977 "push %%rcx \n\t"
2978#else
2979 "push %%edx; push %%ebp;"
2980 "push %%ecx \n\t"
2981#endif
2982 __ex(ASM_VMX_VMWRITE_RSP_RDX) "\n\t" 2985 __ex(ASM_VMX_VMWRITE_RSP_RDX) "\n\t"
2983 /* Check if vmlaunch of vmresume is needed */ 2986 /* Check if vmlaunch of vmresume is needed */
2984 "cmpl $0, %c[launched](%0) \n\t" 2987 "cmpl $0, %c[launched](%0) \n\t"
2985 /* Load guest registers. Don't clobber flags. */ 2988 /* Load guest registers. Don't clobber flags. */
2989 "mov %c[cr2](%0), %%"R"ax \n\t"
2990 "mov %%"R"ax, %%cr2 \n\t"
2991 "mov %c[rax](%0), %%"R"ax \n\t"
2992 "mov %c[rbx](%0), %%"R"bx \n\t"
2993 "mov %c[rdx](%0), %%"R"dx \n\t"
2994 "mov %c[rsi](%0), %%"R"si \n\t"
2995 "mov %c[rdi](%0), %%"R"di \n\t"
2996 "mov %c[rbp](%0), %%"R"bp \n\t"
2986#ifdef CONFIG_X86_64 2997#ifdef CONFIG_X86_64
2987 "mov %c[cr2](%0), %%rax \n\t"
2988 "mov %%rax, %%cr2 \n\t"
2989 "mov %c[rax](%0), %%rax \n\t"
2990 "mov %c[rbx](%0), %%rbx \n\t"
2991 "mov %c[rdx](%0), %%rdx \n\t"
2992 "mov %c[rsi](%0), %%rsi \n\t"
2993 "mov %c[rdi](%0), %%rdi \n\t"
2994 "mov %c[rbp](%0), %%rbp \n\t"
2995 "mov %c[r8](%0), %%r8 \n\t" 2998 "mov %c[r8](%0), %%r8 \n\t"
2996 "mov %c[r9](%0), %%r9 \n\t" 2999 "mov %c[r9](%0), %%r9 \n\t"
2997 "mov %c[r10](%0), %%r10 \n\t" 3000 "mov %c[r10](%0), %%r10 \n\t"
@@ -3000,18 +3003,9 @@ static void vmx_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
3000 "mov %c[r13](%0), %%r13 \n\t" 3003 "mov %c[r13](%0), %%r13 \n\t"
3001 "mov %c[r14](%0), %%r14 \n\t" 3004 "mov %c[r14](%0), %%r14 \n\t"
3002 "mov %c[r15](%0), %%r15 \n\t" 3005 "mov %c[r15](%0), %%r15 \n\t"
3003 "mov %c[rcx](%0), %%rcx \n\t" /* kills %0 (rcx) */
3004#else
3005 "mov %c[cr2](%0), %%eax \n\t"
3006 "mov %%eax, %%cr2 \n\t"
3007 "mov %c[rax](%0), %%eax \n\t"
3008 "mov %c[rbx](%0), %%ebx \n\t"
3009 "mov %c[rdx](%0), %%edx \n\t"
3010 "mov %c[rsi](%0), %%esi \n\t"
3011 "mov %c[rdi](%0), %%edi \n\t"
3012 "mov %c[rbp](%0), %%ebp \n\t"
3013 "mov %c[rcx](%0), %%ecx \n\t" /* kills %0 (ecx) */
3014#endif 3006#endif
3007 "mov %c[rcx](%0), %%"R"cx \n\t" /* kills %0 (ecx) */
3008
3015 /* Enter guest mode */ 3009 /* Enter guest mode */
3016 "jne .Llaunched \n\t" 3010 "jne .Llaunched \n\t"
3017 __ex(ASM_VMX_VMLAUNCH) "\n\t" 3011 __ex(ASM_VMX_VMLAUNCH) "\n\t"
@@ -3019,15 +3013,15 @@ static void vmx_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
3019 ".Llaunched: " __ex(ASM_VMX_VMRESUME) "\n\t" 3013 ".Llaunched: " __ex(ASM_VMX_VMRESUME) "\n\t"
3020 ".Lkvm_vmx_return: " 3014 ".Lkvm_vmx_return: "
3021 /* Save guest registers, load host registers, keep flags */ 3015 /* Save guest registers, load host registers, keep flags */
3016 "xchg %0, (%%"R"sp) \n\t"
3017 "mov %%"R"ax, %c[rax](%0) \n\t"
3018 "mov %%"R"bx, %c[rbx](%0) \n\t"
3019 "push"Q" (%%"R"sp); pop"Q" %c[rcx](%0) \n\t"
3020 "mov %%"R"dx, %c[rdx](%0) \n\t"
3021 "mov %%"R"si, %c[rsi](%0) \n\t"
3022 "mov %%"R"di, %c[rdi](%0) \n\t"
3023 "mov %%"R"bp, %c[rbp](%0) \n\t"
3022#ifdef CONFIG_X86_64 3024#ifdef CONFIG_X86_64
3023 "xchg %0, (%%rsp) \n\t"
3024 "mov %%rax, %c[rax](%0) \n\t"
3025 "mov %%rbx, %c[rbx](%0) \n\t"
3026 "pushq (%%rsp); popq %c[rcx](%0) \n\t"
3027 "mov %%rdx, %c[rdx](%0) \n\t"
3028 "mov %%rsi, %c[rsi](%0) \n\t"
3029 "mov %%rdi, %c[rdi](%0) \n\t"
3030 "mov %%rbp, %c[rbp](%0) \n\t"
3031 "mov %%r8, %c[r8](%0) \n\t" 3025 "mov %%r8, %c[r8](%0) \n\t"
3032 "mov %%r9, %c[r9](%0) \n\t" 3026 "mov %%r9, %c[r9](%0) \n\t"
3033 "mov %%r10, %c[r10](%0) \n\t" 3027 "mov %%r10, %c[r10](%0) \n\t"
@@ -3036,24 +3030,11 @@ static void vmx_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
3036 "mov %%r13, %c[r13](%0) \n\t" 3030 "mov %%r13, %c[r13](%0) \n\t"
3037 "mov %%r14, %c[r14](%0) \n\t" 3031 "mov %%r14, %c[r14](%0) \n\t"
3038 "mov %%r15, %c[r15](%0) \n\t" 3032 "mov %%r15, %c[r15](%0) \n\t"
3039 "mov %%cr2, %%rax \n\t"
3040 "mov %%rax, %c[cr2](%0) \n\t"
3041
3042 "pop %%rbp; pop %%rbp; pop %%rdx \n\t"
3043#else
3044 "xchg %0, (%%esp) \n\t"
3045 "mov %%eax, %c[rax](%0) \n\t"
3046 "mov %%ebx, %c[rbx](%0) \n\t"
3047 "pushl (%%esp); popl %c[rcx](%0) \n\t"
3048 "mov %%edx, %c[rdx](%0) \n\t"
3049 "mov %%esi, %c[rsi](%0) \n\t"
3050 "mov %%edi, %c[rdi](%0) \n\t"
3051 "mov %%ebp, %c[rbp](%0) \n\t"
3052 "mov %%cr2, %%eax \n\t"
3053 "mov %%eax, %c[cr2](%0) \n\t"
3054
3055 "pop %%ebp; pop %%ebp; pop %%edx \n\t"
3056#endif 3033#endif
3034 "mov %%cr2, %%"R"ax \n\t"
3035 "mov %%"R"ax, %c[cr2](%0) \n\t"
3036
3037 "pop %%"R"bp; pop %%"R"bp; pop %%"R"dx \n\t"
3057 "setbe %c[fail](%0) \n\t" 3038 "setbe %c[fail](%0) \n\t"
3058 : : "c"(vmx), "d"((unsigned long)HOST_RSP), 3039 : : "c"(vmx), "d"((unsigned long)HOST_RSP),
3059 [launched]"i"(offsetof(struct vcpu_vmx, launched)), 3040 [launched]"i"(offsetof(struct vcpu_vmx, launched)),
@@ -3077,11 +3058,9 @@ static void vmx_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
3077#endif 3058#endif
3078 [cr2]"i"(offsetof(struct vcpu_vmx, vcpu.arch.cr2)) 3059 [cr2]"i"(offsetof(struct vcpu_vmx, vcpu.arch.cr2))
3079 : "cc", "memory" 3060 : "cc", "memory"
3061 , R"bx", R"di", R"si"
3080#ifdef CONFIG_X86_64 3062#ifdef CONFIG_X86_64
3081 , "rbx", "rdi", "rsi"
3082 , "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15" 3063 , "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
3083#else
3084 , "ebx", "edi", "rsi"
3085#endif 3064#endif
3086 ); 3065 );
3087 3066
@@ -3111,6 +3090,9 @@ static void vmx_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
3111 vmx_complete_interrupts(vmx); 3090 vmx_complete_interrupts(vmx);
3112} 3091}
3113 3092
3093#undef R
3094#undef Q
3095
3114static void vmx_free_vmcs(struct kvm_vcpu *vcpu) 3096static void vmx_free_vmcs(struct kvm_vcpu *vcpu)
3115{ 3097{
3116 struct vcpu_vmx *vmx = to_vmx(vcpu); 3098 struct vcpu_vmx *vmx = to_vmx(vcpu);