diff options
author | Paolo Bonzini <pbonzini@redhat.com> | 2016-02-26 06:28:40 -0500 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2016-02-26 07:03:39 -0500 |
commit | 70e4da7a8ff62f2775337b705f45c804bb450454 (patch) | |
tree | f5e3b9eb0a03dc3655eb492748c45d2e19abd315 | |
parent | 0fb00d326ffc36844fac0bfefd8644585a86d4a6 (diff) |
KVM: x86: fix root cause for missed hardware breakpoints
Commit 172b2386ed16 ("KVM: x86: fix missed hardware breakpoints",
2016-02-10) worked around a case where the debug registers are not loaded
correctly on preemption and on the first entry to KVM_RUN.
However, Xiao Guangrong pointed out that the root cause must be that
KVM_DEBUGREG_BP_ENABLED is not being set correctly. This can indeed
happen due to the lazy debug exit mechanism, which does not call
kvm_update_dr7. Fix it by replacing the existing loop (more or less
equivalent to kvm_update_dr0123) with calls to all the kvm_update_dr*
functions.
Cc: stable@vger.kernel.org # 4.1+
Fixes: 172b2386ed16a9143d9a456aae5ec87275c61489
Reviewed-by: Xiao Guangrong <guangrong.xiao@linux.intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rw-r--r-- | arch/x86/kvm/x86.c | 9 |
1 files changed, 4 insertions, 5 deletions
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index f4891f2ece23..eaf6ee8c28b8 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c | |||
@@ -2752,7 +2752,6 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) | |||
2752 | } | 2752 | } |
2753 | 2753 | ||
2754 | kvm_make_request(KVM_REQ_STEAL_UPDATE, vcpu); | 2754 | kvm_make_request(KVM_REQ_STEAL_UPDATE, vcpu); |
2755 | vcpu->arch.switch_db_regs |= KVM_DEBUGREG_RELOAD; | ||
2756 | } | 2755 | } |
2757 | 2756 | ||
2758 | void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) | 2757 | void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) |
@@ -6619,12 +6618,12 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu) | |||
6619 | * KVM_DEBUGREG_WONT_EXIT again. | 6618 | * KVM_DEBUGREG_WONT_EXIT again. |
6620 | */ | 6619 | */ |
6621 | if (unlikely(vcpu->arch.switch_db_regs & KVM_DEBUGREG_WONT_EXIT)) { | 6620 | if (unlikely(vcpu->arch.switch_db_regs & KVM_DEBUGREG_WONT_EXIT)) { |
6622 | int i; | ||
6623 | |||
6624 | WARN_ON(vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP); | 6621 | WARN_ON(vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP); |
6625 | kvm_x86_ops->sync_dirty_debug_regs(vcpu); | 6622 | kvm_x86_ops->sync_dirty_debug_regs(vcpu); |
6626 | for (i = 0; i < KVM_NR_DB_REGS; i++) | 6623 | kvm_update_dr0123(vcpu); |
6627 | vcpu->arch.eff_db[i] = vcpu->arch.db[i]; | 6624 | kvm_update_dr6(vcpu); |
6625 | kvm_update_dr7(vcpu); | ||
6626 | vcpu->arch.switch_db_regs &= ~KVM_DEBUGREG_RELOAD; | ||
6628 | } | 6627 | } |
6629 | 6628 | ||
6630 | /* | 6629 | /* |