mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Paolo Bonzini <pbonzini@redhat.com>
To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org
Cc: peterx@redhat.com, Sean Christopherson <sean.j.christopherson@intel.com>
Subject: [PATCH 8/9] KVM: x86, SVM: do not clobber guest DR6 on KVM_EXIT_DEBUG
Date: Wed,  6 May 2020 07:10:33 -0400	[thread overview]
Message-ID: <20200506111034.11756-9-pbonzini@redhat.com> (raw)
In-Reply-To: <20200506111034.11756-1-pbonzini@redhat.com>

On Intel, #DB exceptions transmit the DR6 value via the exit qualification
field of the VMCS, and the exit qualification only contains the description
of the precise event that caused a vmexit.

On AMD, instead the DR6 field of the VMCB is filled in as if the #DB exception
was to be injected into the guest.  This has two effects when guest debugging
is in use:

* the guest DR6 is clobbered

* the kvm_run->debug.arch.dr6 field can accumulate more debug events, rather
than just the last one that happened.

Fortunately, if guest debugging is in use we debug register reads and writes
are always intercepted.  Now that the guest DR6 is always synchronized with
vcpu->arch.dr6, we can just run the guest with an all-zero DR6 while guest
debugging is enabled, and restore the guest value when it is disabled.  This
fixes both problems.

A testcase for the second issue is added in the next patch.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 arch/x86/kvm/svm/svm.c |  2 ++
 arch/x86/kvm/x86.c     | 12 ++++++++----
 arch/x86/kvm/x86.h     |  2 ++
 3 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
index f03bffafd9e6..29dc7311dbb1 100644
--- a/arch/x86/kvm/svm/svm.c
+++ b/arch/x86/kvm/svm/svm.c
@@ -1750,6 +1750,8 @@ static int db_interception(struct vcpu_svm *svm)
 		kvm_run->exit_reason = KVM_EXIT_DEBUG;
 		kvm_run->debug.arch.dr6 = svm->vmcb->save.dr6;
 		kvm_run->debug.arch.dr7 = svm->vmcb->save.dr7;
+		/* This restores DR6 to all zeros.  */
+		kvm_update_dr6(vcpu);
 		kvm_run->debug.arch.pc =
 			svm->vmcb->save.cs.base + svm->vmcb->save.rip;
 		kvm_run->debug.arch.exception = DB_VECTOR;
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index f4254d716b10..1b5e0fc346bb 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -104,7 +104,6 @@ static u64 __read_mostly cr4_reserved_bits = CR4_RESERVED_BITS;
                                     KVM_X2APIC_API_DISABLE_BROADCAST_QUIRK)
 
 static void update_cr8_intercept(struct kvm_vcpu *vcpu);
-static void kvm_update_dr6(struct kvm_vcpu *vcpu);
 static void process_nmi(struct kvm_vcpu *vcpu);
 static void enter_smm(struct kvm_vcpu *vcpu);
 static void __kvm_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags);
@@ -1048,10 +1047,14 @@ static void kvm_update_dr0123(struct kvm_vcpu *vcpu)
 	}
 }
 
-static void kvm_update_dr6(struct kvm_vcpu *vcpu)
+void kvm_update_dr6(struct kvm_vcpu *vcpu)
 {
-	if (!(vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP) &&
-	    kvm_x86_ops.set_dr6)
+	if (!kvm_x86_ops.set_dr6)
+		return;
+
+	if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP)
+		kvm_x86_ops.set_dr6(vcpu, DR6_FIXED_1 | DR6_RTM);
+	else
 		kvm_x86_ops.set_dr6(vcpu, vcpu->arch.dr6);
 }
 
@@ -9154,6 +9157,7 @@ int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
 		for (i = 0; i < KVM_NR_DB_REGS; i++)
 			vcpu->arch.eff_db[i] = vcpu->arch.db[i];
 	}
+	kvm_update_dr6(vcpu);
 	kvm_update_dr7(vcpu);
 
 	if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP)
diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h
index b968acc0516f..a4c950ad4d60 100644
--- a/arch/x86/kvm/x86.h
+++ b/arch/x86/kvm/x86.h
@@ -240,6 +240,8 @@ static inline bool kvm_vcpu_latch_init(struct kvm_vcpu *vcpu)
 	return is_smm(vcpu) || kvm_x86_ops.apic_init_signal_blocked(vcpu);
 }
 
+void kvm_update_dr6(struct kvm_vcpu *vcpu);
+
 void kvm_set_pending_timer(struct kvm_vcpu *vcpu);
 void kvm_inject_realmode_interrupt(struct kvm_vcpu *vcpu, int irq, int inc_eip);
 
-- 
2.18.2



  parent reply	other threads:[~2020-05-06 11:10 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-05-06 11:10 [PATCH 0/9] KVM_SET_GUEST_DEBUG tests and fixes, DR accessors cleanups Paolo Bonzini
2020-05-06 11:10 ` [PATCH 1/9] KVM: X86: Declare KVM_CAP_SET_GUEST_DEBUG properly Paolo Bonzini
2020-05-06 11:10 ` [PATCH 2/9] KVM: x86: fix DR6 delivery for various cases of #DB injection Paolo Bonzini
2020-05-06 16:01   ` Peter Xu
2020-05-06 11:10 ` [PATCH 3/9] KVM: X86: Set RTM for DB_VECTOR too for KVM_EXIT_DEBUG Paolo Bonzini
2020-05-06 11:10 ` [PATCH 4/9] KVM: X86: Fix single-step with KVM_SET_GUEST_DEBUG Paolo Bonzini
2020-05-06 11:10 ` [PATCH 5/9] KVM: selftests: Add KVM_SET_GUEST_DEBUG test Paolo Bonzini
2020-05-06 11:10 ` [PATCH 6/9] KVM: SVM: keep DR6 synchronized with vcpu->arch.dr6 Paolo Bonzini
2020-05-06 16:04   ` Peter Xu
2020-05-06 11:10 ` [PATCH 7/9] KVM: x86: simplify dr6 accessors in kvm_x86_ops Paolo Bonzini
2020-05-06 16:06   ` Peter Xu
2020-05-06 16:09     ` Paolo Bonzini
2020-05-06 17:52       ` Peter Xu
2020-05-06 11:10 ` Paolo Bonzini [this message]
2020-05-06 18:15   ` [PATCH 8/9] KVM: x86, SVM: do not clobber guest DR6 on KVM_EXIT_DEBUG Peter Xu
2020-05-06 20:07     ` Paolo Bonzini
2020-05-06 21:13       ` Peter Xu
2020-05-06 21:20         ` Sean Christopherson
2020-05-06 23:33           ` Peter Xu
2020-05-06 23:47             ` Sean Christopherson
2020-05-06 11:10 ` [PATCH 9/9] KVM: VMX: pass correct DR6 for GD userspace exit Paolo Bonzini
2020-05-06 17:50   ` Peter Xu

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200506111034.11756-9-pbonzini@redhat.com \
    --to=pbonzini@redhat.com \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=peterx@redhat.com \
    --cc=sean.j.christopherson@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®