aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm/vmx.c
diff options
context:
space:
mode:
authorGleb Natapov <gleb@redhat.com>2010-04-13 03:05:23 -0400
committerAvi Kivity <avi@redhat.com>2010-05-17 05:17:39 -0400
commit020df0794f5764e742feaa718be88b8f1b4ce04f (patch)
treece0fca4af2beba046c8632e663bfc082681c6afa /arch/x86/kvm/vmx.c
parent6bc31bdc55cad6609b1610b4cecad312664f2808 (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.c78
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
3092static 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
3101static int handle_dr(struct kvm_vcpu *vcpu) 3092static 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
3138static void vmx_set_dr7(struct kvm_vcpu *vcpu, unsigned long val)
3139{
3140 vmcs_writel(GUEST_DR7, val);
3141}
3142
3200static int handle_cpuid(struct kvm_vcpu *vcpu) 3143static 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,