mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-15 06:55:13 +08:00
KVM: VMX: Fix emulation of DR4 and DR5
Make sure DR4 and DR5 are aliased to DR6 and DR7, respectively, if CR4.DE is not set. Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com> Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
This commit is contained in:
parent
f248341529
commit
138ac8d88f
@ -3039,6 +3039,15 @@ static int handle_cr(struct kvm_vcpu *vcpu)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int check_dr_alias(struct kvm_vcpu *vcpu)
|
||||||
|
{
|
||||||
|
if (kvm_read_cr4_bits(vcpu, X86_CR4_DE)) {
|
||||||
|
kvm_queue_exception(vcpu, UD_VECTOR);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int handle_dr(struct kvm_vcpu *vcpu)
|
static int handle_dr(struct kvm_vcpu *vcpu)
|
||||||
{
|
{
|
||||||
unsigned long exit_qualification;
|
unsigned long exit_qualification;
|
||||||
@ -3081,14 +3090,20 @@ static int handle_dr(struct kvm_vcpu *vcpu)
|
|||||||
case 0 ... 3:
|
case 0 ... 3:
|
||||||
val = vcpu->arch.db[dr];
|
val = vcpu->arch.db[dr];
|
||||||
break;
|
break;
|
||||||
|
case 4:
|
||||||
|
if (check_dr_alias(vcpu) < 0)
|
||||||
|
return 1;
|
||||||
|
/* fall through */
|
||||||
case 6:
|
case 6:
|
||||||
val = vcpu->arch.dr6;
|
val = vcpu->arch.dr6;
|
||||||
break;
|
break;
|
||||||
case 7:
|
case 5:
|
||||||
|
if (check_dr_alias(vcpu) < 0)
|
||||||
|
return 1;
|
||||||
|
/* fall through */
|
||||||
|
default: /* 7 */
|
||||||
val = vcpu->arch.dr7;
|
val = vcpu->arch.dr7;
|
||||||
break;
|
break;
|
||||||
default:
|
|
||||||
val = 0;
|
|
||||||
}
|
}
|
||||||
kvm_register_write(vcpu, reg, val);
|
kvm_register_write(vcpu, reg, val);
|
||||||
} else {
|
} else {
|
||||||
@ -3099,12 +3114,10 @@ static int handle_dr(struct kvm_vcpu *vcpu)
|
|||||||
if (!(vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP))
|
if (!(vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP))
|
||||||
vcpu->arch.eff_db[dr] = val;
|
vcpu->arch.eff_db[dr] = val;
|
||||||
break;
|
break;
|
||||||
case 4 ... 5:
|
case 4:
|
||||||
if (kvm_read_cr4_bits(vcpu, X86_CR4_DE)) {
|
if (check_dr_alias(vcpu) < 0)
|
||||||
kvm_queue_exception(vcpu, UD_VECTOR);
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
/* fall through */
|
||||||
break;
|
|
||||||
case 6:
|
case 6:
|
||||||
if (val & 0xffffffff00000000ULL) {
|
if (val & 0xffffffff00000000ULL) {
|
||||||
kvm_inject_gp(vcpu, 0);
|
kvm_inject_gp(vcpu, 0);
|
||||||
@ -3112,7 +3125,11 @@ static int handle_dr(struct kvm_vcpu *vcpu)
|
|||||||
}
|
}
|
||||||
vcpu->arch.dr6 = (val & DR6_VOLATILE) | DR6_FIXED_1;
|
vcpu->arch.dr6 = (val & DR6_VOLATILE) | DR6_FIXED_1;
|
||||||
break;
|
break;
|
||||||
case 7:
|
case 5:
|
||||||
|
if (check_dr_alias(vcpu) < 0)
|
||||||
|
return 1;
|
||||||
|
/* fall through */
|
||||||
|
default: /* 7 */
|
||||||
if (val & 0xffffffff00000000ULL) {
|
if (val & 0xffffffff00000000ULL) {
|
||||||
kvm_inject_gp(vcpu, 0);
|
kvm_inject_gp(vcpu, 0);
|
||||||
return 1;
|
return 1;
|
||||||
|
Loading…
Reference in New Issue
Block a user