@@ -2963,14 +2963,24 @@ static int handle_dr(struct kvm_vcpu *vcpu)
case 0 ... 3:
val = vcpu->arch.db[dr];
break;
+ case 4:
+ if (vcpu->arch.cr4 & X86_CR4_DE) {
+ kvm_queue_exception(vcpu, UD_VECTOR);
+ goto skip_instr;
+ }
+ /* fall through */
case 6:
val = vcpu->arch.dr6;
break;
- case 7:
+ case 5:
+ if (vcpu->arch.cr4 & X86_CR4_DE) {
+ kvm_queue_exception(vcpu, UD_VECTOR);
+ goto skip_instr;
+ }
+ /* fall through */
+ default: /* 7 */
val = vcpu->arch.dr7;
break;
- default:
- val = 0;
}
kvm_register_write(vcpu, reg, val);
} else {
@@ -2981,10 +2991,12 @@ static int handle_dr(struct kvm_vcpu *vcpu)
if (!(vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP))
vcpu->arch.eff_db[dr] = val;
break;
- case 4 ... 5:
- if (vcpu->arch.cr4 & X86_CR4_DE)
+ case 4:
+ if (vcpu->arch.cr4 & X86_CR4_DE) {
kvm_queue_exception(vcpu, UD_VECTOR);
- break;
+ break;
+ }
+ /* fall through */
case 6:
if (val & 0xffffffff00000000ULL) {
kvm_queue_exception(vcpu, GP_VECTOR);
@@ -2992,7 +3004,13 @@ static int handle_dr(struct kvm_vcpu *vcpu)
}
vcpu->arch.dr6 = (val & DR6_VOLATILE) | DR6_FIXED_1;
break;
- case 7:
+ case 5:
+ if (vcpu->arch.cr4 & X86_CR4_DE) {
+ kvm_queue_exception(vcpu, UD_VECTOR);
+ break;
+ }
+ /* fall through */
+ default: /* 7 */
if (val & 0xffffffff00000000ULL) {
kvm_queue_exception(vcpu, GP_VECTOR);
break;
@@ -3006,6 +3024,7 @@ static int handle_dr(struct kvm_vcpu *vcpu)
break;
}
}
+skip_instr:
skip_emulated_instruction(vcpu);
return 1;
}
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> --- arch/x86/kvm/vmx.c | 33 ++++++++++++++++++++++++++------- 1 files changed, 26 insertions(+), 7 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html