diff options
author | Avi Kivity <avi@qumranet.com> | 2008-07-14 07:44:59 -0400 |
---|---|---|
committer | Avi Kivity <avi@qumranet.com> | 2008-10-15 04:15:14 -0400 |
commit | c801949ddf0a51074937f488a52072825ed50174 (patch) | |
tree | 348a6ec407e4ab9495df203662200e31a60ccdc0 /arch/x86/kvm/vmx.c | |
parent | 77ab6db0a1c403387b403e9351ab3f5ae1df83e6 (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.c | 90 |
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 | |||
2958 | static void vmx_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | 2966 | static 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 | |||
3114 | static void vmx_free_vmcs(struct kvm_vcpu *vcpu) | 3096 | static 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); |