diff options
author | Gleb Natapov <gleb@redhat.com> | 2010-04-13 03:05:23 -0400 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2010-05-17 05:17:39 -0400 |
commit | 020df0794f5764e742feaa718be88b8f1b4ce04f (patch) | |
tree | ce0fca4af2beba046c8632e663bfc082681c6afa /arch/x86/kvm/vmx.c | |
parent | 6bc31bdc55cad6609b1610b4cecad312664f2808 (diff) |
KVM: move DR register access handling into generic code
Currently both SVM and VMX have their own DR handling code. Move it to
x86.c.
Acked-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Gleb Natapov <gleb@redhat.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Diffstat (limited to 'arch/x86/kvm/vmx.c')
-rw-r--r-- | arch/x86/kvm/vmx.c | 78 |
1 files changed, 11 insertions, 67 deletions
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 1cceca1c59be..fb4a8869bb99 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c | |||
@@ -3089,19 +3089,9 @@ static int handle_cr(struct kvm_vcpu *vcpu) | |||
3089 | return 0; | 3089 | return 0; |
3090 | } | 3090 | } |
3091 | 3091 | ||
3092 | static int check_dr_alias(struct kvm_vcpu *vcpu) | ||
3093 | { | ||
3094 | if (kvm_read_cr4_bits(vcpu, X86_CR4_DE)) { | ||
3095 | kvm_queue_exception(vcpu, UD_VECTOR); | ||
3096 | return -1; | ||
3097 | } | ||
3098 | return 0; | ||
3099 | } | ||
3100 | |||
3101 | static int handle_dr(struct kvm_vcpu *vcpu) | 3092 | static int handle_dr(struct kvm_vcpu *vcpu) |
3102 | { | 3093 | { |
3103 | unsigned long exit_qualification; | 3094 | unsigned long exit_qualification; |
3104 | unsigned long val; | ||
3105 | int dr, reg; | 3095 | int dr, reg; |
3106 | 3096 | ||
3107 | /* Do not handle if the CPL > 0, will trigger GP on re-entry */ | 3097 | /* Do not handle if the CPL > 0, will trigger GP on re-entry */ |
@@ -3136,67 +3126,20 @@ static int handle_dr(struct kvm_vcpu *vcpu) | |||
3136 | dr = exit_qualification & DEBUG_REG_ACCESS_NUM; | 3126 | dr = exit_qualification & DEBUG_REG_ACCESS_NUM; |
3137 | reg = DEBUG_REG_ACCESS_REG(exit_qualification); | 3127 | reg = DEBUG_REG_ACCESS_REG(exit_qualification); |
3138 | if (exit_qualification & TYPE_MOV_FROM_DR) { | 3128 | if (exit_qualification & TYPE_MOV_FROM_DR) { |
3139 | switch (dr) { | 3129 | unsigned long val; |
3140 | case 0 ... 3: | 3130 | if (!kvm_get_dr(vcpu, dr, &val)) |
3141 | val = vcpu->arch.db[dr]; | 3131 | kvm_register_write(vcpu, reg, val); |
3142 | break; | 3132 | } else |
3143 | case 4: | 3133 | kvm_set_dr(vcpu, dr, vcpu->arch.regs[reg]); |
3144 | if (check_dr_alias(vcpu) < 0) | ||
3145 | return 1; | ||
3146 | /* fall through */ | ||
3147 | case 6: | ||
3148 | val = vcpu->arch.dr6; | ||
3149 | break; | ||
3150 | case 5: | ||
3151 | if (check_dr_alias(vcpu) < 0) | ||
3152 | return 1; | ||
3153 | /* fall through */ | ||
3154 | default: /* 7 */ | ||
3155 | val = vcpu->arch.dr7; | ||
3156 | break; | ||
3157 | } | ||
3158 | kvm_register_write(vcpu, reg, val); | ||
3159 | } else { | ||
3160 | val = vcpu->arch.regs[reg]; | ||
3161 | switch (dr) { | ||
3162 | case 0 ... 3: | ||
3163 | vcpu->arch.db[dr] = val; | ||
3164 | if (!(vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP)) | ||
3165 | vcpu->arch.eff_db[dr] = val; | ||
3166 | break; | ||
3167 | case 4: | ||
3168 | if (check_dr_alias(vcpu) < 0) | ||
3169 | return 1; | ||
3170 | /* fall through */ | ||
3171 | case 6: | ||
3172 | if (val & 0xffffffff00000000ULL) { | ||
3173 | kvm_inject_gp(vcpu, 0); | ||
3174 | return 1; | ||
3175 | } | ||
3176 | vcpu->arch.dr6 = (val & DR6_VOLATILE) | DR6_FIXED_1; | ||
3177 | break; | ||
3178 | case 5: | ||
3179 | if (check_dr_alias(vcpu) < 0) | ||
3180 | return 1; | ||
3181 | /* fall through */ | ||
3182 | default: /* 7 */ | ||
3183 | if (val & 0xffffffff00000000ULL) { | ||
3184 | kvm_inject_gp(vcpu, 0); | ||
3185 | return 1; | ||
3186 | } | ||
3187 | vcpu->arch.dr7 = (val & DR7_VOLATILE) | DR7_FIXED_1; | ||
3188 | if (!(vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP)) { | ||
3189 | vmcs_writel(GUEST_DR7, vcpu->arch.dr7); | ||
3190 | vcpu->arch.switch_db_regs = | ||
3191 | (val & DR7_BP_EN_MASK); | ||
3192 | } | ||
3193 | break; | ||
3194 | } | ||
3195 | } | ||
3196 | skip_emulated_instruction(vcpu); | 3134 | skip_emulated_instruction(vcpu); |
3197 | return 1; | 3135 | return 1; |
3198 | } | 3136 | } |
3199 | 3137 | ||
3138 | static void vmx_set_dr7(struct kvm_vcpu *vcpu, unsigned long val) | ||
3139 | { | ||
3140 | vmcs_writel(GUEST_DR7, val); | ||
3141 | } | ||
3142 | |||
3200 | static int handle_cpuid(struct kvm_vcpu *vcpu) | 3143 | static int handle_cpuid(struct kvm_vcpu *vcpu) |
3201 | { | 3144 | { |
3202 | kvm_emulate_cpuid(vcpu); | 3145 | kvm_emulate_cpuid(vcpu); |
@@ -4187,6 +4130,7 @@ static struct kvm_x86_ops vmx_x86_ops = { | |||
4187 | .set_idt = vmx_set_idt, | 4130 | .set_idt = vmx_set_idt, |
4188 | .get_gdt = vmx_get_gdt, | 4131 | .get_gdt = vmx_get_gdt, |
4189 | .set_gdt = vmx_set_gdt, | 4132 | .set_gdt = vmx_set_gdt, |
4133 | .set_dr7 = vmx_set_dr7, | ||
4190 | .cache_reg = vmx_cache_reg, | 4134 | .cache_reg = vmx_cache_reg, |
4191 | .get_rflags = vmx_get_rflags, | 4135 | .get_rflags = vmx_get_rflags, |
4192 | .set_rflags = vmx_set_rflags, | 4136 | .set_rflags = vmx_set_rflags, |