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@xxxxxxxxxxx> --- arch/x86/kvm/vmx.c | 33 ++++++++++++++++++++++++++------- 1 files changed, 26 insertions(+), 7 deletions(-) diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 7012680..d34aea5 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -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; } -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html