summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLai Jiangshan <laijs@linux.alibaba.com>2021-06-29 01:26:32 +0800
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2021-07-20 16:21:10 +0200
commit7dbeeb70c6d3d0c06d5edbefd1f74df62d7c2f09 (patch)
tree1dca7500cc5fd3b48fea13660b56b698f2021acd
parent5ac7a7b1bdfe45df57eb37696207658bc151bab3 (diff)
downloadlinux-stable-7dbeeb70c6d3d0c06d5edbefd1f74df62d7c2f09.tar.gz
linux-stable-7dbeeb70c6d3d0c06d5edbefd1f74df62d7c2f09.tar.bz2
linux-stable-7dbeeb70c6d3d0c06d5edbefd1f74df62d7c2f09.zip
KVM: X86: Disable hardware breakpoints unconditionally before kvm_x86->run()
commit f85d40160691881a17a397c448d799dfc90987ba upstream. When the host is using debug registers but the guest is not using them nor is the guest in guest-debug state, the kvm code does not reset the host debug registers before kvm_x86->run(). Rather, it relies on the hardware vmentry instruction to automatically reset the dr7 registers which ensures that the host breakpoints do not affect the guest. This however violates the non-instrumentable nature around VM entry and exit; for example, when a host breakpoint is set on vcpu->arch.cr2, Another issue is consistency. When the guest debug registers are active, the host breakpoints are reset before kvm_x86->run(). But when the guest debug registers are inactive, the host breakpoints are delayed to be disabled. The host tracing tools may see different results depending on what the guest is doing. To fix the problems, we clear %db7 unconditionally before kvm_x86->run() if the host has set any breakpoints, no matter if the guest is using them or not. Signed-off-by: Lai Jiangshan <laijs@linux.alibaba.com> Message-Id: <20210628172632.81029-1-jiangshanlai@gmail.com> Cc: stable@vger.kernel.org [Only clear %db7 instead of reloading all debug registers. - Paolo] Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--arch/x86/kvm/x86.c2
1 files changed, 2 insertions, 0 deletions
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index b945f362771f..c959720c7593 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -7044,6 +7044,8 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
set_debugreg(vcpu->arch.eff_db[3], 3);
set_debugreg(vcpu->arch.dr6, 6);
vcpu->arch.switch_db_regs &= ~KVM_DEBUGREG_RELOAD;
+ } else if (unlikely(hw_breakpoint_active())) {
+ set_debugreg(0, 7);
}
kvm_x86_ops->run(vcpu);