* Re: [PATCH v2 2/9] KVM: x86: Set guest DR6 by kvm_queue_exception_p() in instruction emulation
[not found] ` <9b859ab6a6b59e5ccfdac741459117996fe2da6e.1766066076.git.houwenlong.hwl@antgroup.com>
@ 2026-05-11 15:23 ` Sean Christopherson
2026-05-11 15:26 ` Sean Christopherson
0 siblings, 1 reply; 4+ messages in thread
From: Sean Christopherson @ 2026-05-11 15:23 UTC (permalink / raw)
To: Hou Wenlong
Cc: kvm, Lai Jiangshan, Paolo Bonzini, Thomas Gleixner, Ingo Molnar,
Borislav Petkov, Dave Hansen, x86, H. Peter Anvin, linux-kernel
On Thu, Dec 18, 2025, Hou Wenlong wrote:
> Record DR6 in emulate_db() and use kvm_queue_exception_p() to set DR6
> instead of directly using kvm_set_dr6() in emulation, which keeps the
> handling of DR6 during #DB injection consistent with other code paths.
>
> No functional change intended.
>
> Signed-off-by: Hou Wenlong <houwenlong.hwl@antgroup.com>
> ---
> arch/x86/kvm/emulate.c | 14 ++++----------
> arch/x86/kvm/kvm_emulate.h | 6 +++++-
> arch/x86/kvm/x86.c | 5 ++++-
> 3 files changed, 13 insertions(+), 12 deletions(-)
>
> diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
> index c8e292e9a24d..997cd6e46d90 100644
> --- a/arch/x86/kvm/emulate.c
> +++ b/arch/x86/kvm/emulate.c
> @@ -540,8 +540,9 @@ static int emulate_exception(struct x86_emulate_ctxt *ctxt, int vec,
> return X86EMUL_PROPAGATE_FAULT;
> }
>
> -static int emulate_db(struct x86_emulate_ctxt *ctxt)
> +static int emulate_db(struct x86_emulate_ctxt *ctxt, unsigned long dr6)
> {
> + ctxt->exception.dr6 = dr6;
> return emulate_exception(ctxt, DB_VECTOR, 0, false);
> }
>
> @@ -3834,15 +3835,8 @@ static int check_dr_read(struct x86_emulate_ctxt *ctxt)
> if ((cr4 & X86_CR4_DE) && (dr == 4 || dr == 5))
> return emulate_ud(ctxt);
>
> - if (ctxt->ops->get_dr(ctxt, 7) & DR7_GD) {
> - ulong dr6;
> -
> - dr6 = ctxt->ops->get_dr(ctxt, 6);
> - dr6 &= ~DR_TRAP_BITS;
> - dr6 |= DR6_BD | DR6_ACTIVE_LOW;
> - ctxt->ops->set_dr(ctxt, 6, dr6);
> - return emulate_db(ctxt);
> - }
> + if (ctxt->ops->get_dr(ctxt, 7) & DR7_GD)
> + return emulate_db(ctxt, DR6_BD);
>
> return X86EMUL_CONTINUE;
> }
> diff --git a/arch/x86/kvm/kvm_emulate.h b/arch/x86/kvm/kvm_emulate.h
> index fb3dab4b5a53..7fe38b174e18 100644
> --- a/arch/x86/kvm/kvm_emulate.h
> +++ b/arch/x86/kvm/kvm_emulate.h
> @@ -24,7 +24,11 @@ struct x86_exception {
> bool error_code_valid;
> u16 error_code;
> bool nested_page_fault;
> - u64 address; /* cr2 or nested page fault gpa */
> + union {
> + u64 address; /* cr2 or nested page fault gpa */
> + unsigned long dr6;
> + u64 payload;
Please split the introduction of the union to a separate patch, mainly so that
the effectively zeroing of ctxt.exception.address in init_emulate_ctxt() is
isolated, e.g. in case it somehow causes problems. But that will also allow
introducing the inject_emulated_exception() change separately from the
check_dr_read() change.
> + };
> u8 async_page_fault;
> unsigned long exit_qualification;
> };
> diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
> index ab298bfa7d9f..f33ce947633e 100644
> --- a/arch/x86/kvm/x86.c
> +++ b/arch/x86/kvm/x86.c
> @@ -8925,7 +8925,9 @@ static void inject_emulated_exception(struct kvm_vcpu *vcpu)
> {
> struct x86_exception *ex = &vcpu->arch.emulate_ctxt->exception;
>
> - if (ex->vector == PF_VECTOR)
> + if (ex->vector == DB_VECTOR)
> + kvm_queue_exception_e(vcpu, DB_VECTOR, ex->dr6);
This should be kvm_queue_exception_p(). I also think pivoting on DB_VECTOR is
the wrong approach. Rather than key off the vector, add payload_valid (to match
error_code_valid), and then do:
struct x86_exception *ex = &vcpu->arch.emulate_ctxt->exception;
WARN_ON_ONCE(ex->vector != PF_VECTOR && ex->payload_valid &&
ex->error_code_valid);
if (ex->vector == PF_VECTOR)
kvm_inject_emulated_page_fault(vcpu, ex);
else if (ex->payload_valid)
kvm_queue_exception_p(vcpu, DB_VECTOR, ex->payload);
else if (ex->error_code_valid)
kvm_queue_exception_e(vcpu, ex->vector, ex->error_code);
else
kvm_queue_exception(vcpu, ex->vector);
PF_VECTOR is special because it has both an error code and a payload, and because
it needs additional handling on multiple fronts.
> + else if (ex->vector == PF_VECTOR)
> kvm_inject_emulated_page_fault(vcpu, ex);
> else if (ex->error_code_valid)
> kvm_queue_exception_e(vcpu, ex->vector, ex->error_code);
> @@ -8970,6 +8972,7 @@ static void init_emulate_ctxt(struct kvm_vcpu *vcpu)
> ctxt->interruptibility = 0;
> ctxt->have_exception = false;
> ctxt->exception.vector = -1;
> + ctxt->exception.payload = 0;
> ctxt->perm_ok = false;
>
> init_decode_cache(ctxt);
> --
> 2.31.1
>
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH v2 2/9] KVM: x86: Set guest DR6 by kvm_queue_exception_p() in instruction emulation
2026-05-11 15:23 ` [PATCH v2 2/9] KVM: x86: Set guest DR6 by kvm_queue_exception_p() in instruction emulation Sean Christopherson
@ 2026-05-11 15:26 ` Sean Christopherson
2026-05-11 15:42 ` Sean Christopherson
0 siblings, 1 reply; 4+ messages in thread
From: Sean Christopherson @ 2026-05-11 15:26 UTC (permalink / raw)
To: Hou Wenlong
Cc: kvm, Lai Jiangshan, Paolo Bonzini, Thomas Gleixner, Ingo Molnar,
Borislav Petkov, Dave Hansen, x86, H. Peter Anvin, linux-kernel
On Mon, May 11, 2026, Sean Christopherson wrote:
> On Thu, Dec 18, 2025, Hou Wenlong wrote:
> > diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
> > index ab298bfa7d9f..f33ce947633e 100644
> > --- a/arch/x86/kvm/x86.c
> > +++ b/arch/x86/kvm/x86.c
> > @@ -8925,7 +8925,9 @@ static void inject_emulated_exception(struct kvm_vcpu *vcpu)
> > {
> > struct x86_exception *ex = &vcpu->arch.emulate_ctxt->exception;
> >
> > - if (ex->vector == PF_VECTOR)
> > + if (ex->vector == DB_VECTOR)
> > + kvm_queue_exception_e(vcpu, DB_VECTOR, ex->dr6);
>
> This should be kvm_queue_exception_p(). I also think pivoting on DB_VECTOR is
> the wrong approach.
Gah, never mind, didn't look at the next patch.
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH v2 2/9] KVM: x86: Set guest DR6 by kvm_queue_exception_p() in instruction emulation
2026-05-11 15:26 ` Sean Christopherson
@ 2026-05-11 15:42 ` Sean Christopherson
0 siblings, 0 replies; 4+ messages in thread
From: Sean Christopherson @ 2026-05-11 15:42 UTC (permalink / raw)
To: Hou Wenlong
Cc: kvm, Lai Jiangshan, Paolo Bonzini, Thomas Gleixner, Ingo Molnar,
Borislav Petkov, Dave Hansen, x86, H. Peter Anvin, linux-kernel
On Mon, May 11, 2026, Sean Christopherson wrote:
> On Mon, May 11, 2026, Sean Christopherson wrote:
> > On Thu, Dec 18, 2025, Hou Wenlong wrote:
> > > diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
> > > index ab298bfa7d9f..f33ce947633e 100644
> > > --- a/arch/x86/kvm/x86.c
> > > +++ b/arch/x86/kvm/x86.c
> > > @@ -8925,7 +8925,9 @@ static void inject_emulated_exception(struct kvm_vcpu *vcpu)
> > > {
> > > struct x86_exception *ex = &vcpu->arch.emulate_ctxt->exception;
> > >
> > > - if (ex->vector == PF_VECTOR)
> > > + if (ex->vector == DB_VECTOR)
> > > + kvm_queue_exception_e(vcpu, DB_VECTOR, ex->dr6);
> >
> > This should be kvm_queue_exception_p(). I also think pivoting on DB_VECTOR is
> > the wrong approach.
>
> Gah, never mind, didn't look at the next patch.
Actually, that's a good excuse to provide kvm_inject_emulated_db() in this patch,
even though it doesn't become truly necessary until the next patch. Eliminating
some of the code movement in the next patch will yield a smaller diff, and make
it easier to see that there's change in the !KVM_GUESTDBG_USE_HW_BP case.
@@ -8976,23 +8998,36 @@ static void toggle_interruptibility(struct kvm_vcpu *vcpu, u32 mask)
}
}
-static void kvm_inject_emulated_db(struct kvm_vcpu *vcpu, unsigned long dr6)
+static int kvm_inject_emulated_db(struct kvm_vcpu *vcpu, unsigned long dr6)
{
+ struct kvm_run *kvm_run = vcpu->run;
+
+ if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP) {
+ kvm_run->debug.arch.dr6 = dr6 | DR6_ACTIVE_LOW;
+ kvm_run->debug.arch.pc = kvm_get_linear_rip(vcpu);
+ kvm_run->debug.arch.exception = DB_VECTOR;
+ kvm_run->exit_reason = KVM_EXIT_DEBUG;
+ return 0;
+ }
+
kvm_queue_exception_p(vcpu, DB_VECTOR, dr6);
+ return 1;
}
-static void inject_emulated_exception(struct kvm_vcpu *vcpu)
+static int inject_emulated_exception(struct kvm_vcpu *vcpu)
{
struct x86_exception *ex = &vcpu->arch.emulate_ctxt->exception;
if (ex->vector == DB_VECTOR)
- kvm_inject_emulated_db(vcpu, ex->dr6);
- else if (ex->vector == PF_VECTOR)
+ return kvm_inject_emulated_db(vcpu, ex->dr6);
+
+ if (ex->vector == PF_VECTOR)
kvm_inject_emulated_page_fault(vcpu, ex);
else if (ex->error_code_valid)
kvm_queue_exception_e(vcpu, ex->vector, ex->error_code);
else
kvm_queue_exception(vcpu, ex->vector);
+ return 1;
}
static struct x86_emulate_ctxt *alloc_emulate_ctxt(struct kvm_vcpu *vcpu)
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH v2 0/9] KVM: x86: Improve the handling of debug exceptions during instruction emulation
[not found] <cover.1766066076.git.houwenlong.hwl@antgroup.com>
[not found] ` <9b859ab6a6b59e5ccfdac741459117996fe2da6e.1766066076.git.houwenlong.hwl@antgroup.com>
@ 2026-05-11 15:45 ` Sean Christopherson
1 sibling, 0 replies; 4+ messages in thread
From: Sean Christopherson @ 2026-05-11 15:45 UTC (permalink / raw)
To: Hou Wenlong
Cc: kvm, Lai Jiangshan, Paolo Bonzini, Thomas Gleixner, Ingo Molnar,
Borislav Petkov, Dave Hansen, x86, H. Peter Anvin, Shuah Khan,
linux-kernel, linux-kselftest
On Thu, Dec 18, 2025, Hou Wenlong wrote:
> Hou Wenlong (9):
> KVM: x86: Capture "struct x86_exception" in
> inject_emulated_exception()
> KVM: x86: Set guest DR6 by kvm_queue_exception_p() in instruction
> emulation
> KVM: x86: Check guest debug in DR access instruction emulation
> KVM: x86: Only check effective code breakpoint in emulation
> KVM: x86: Consolidate KVM_GUESTDBG_SINGLESTEP check into the
> kvm_inject_emulated_db()
> KVM: x86: Move kvm_set_rflags() up before kvm_vcpu_do_singlestep()
> KVM: VMX: Refresh 'PENDING_DBG_EXCEPTIONS.BS' bit during instruction
> emulation
> KVM: selftests: Verify guest debug DR7.GD checking during instruction
> emulation
> KVM: selftests: Verify 'BS' bit checking in pending debug exception
> during VM entry
>
> arch/x86/include/asm/kvm-x86-ops.h | 1 +
> arch/x86/include/asm/kvm_host.h | 1 +
> arch/x86/kvm/emulate.c | 14 +--
> arch/x86/kvm/kvm_emulate.h | 7 +-
> arch/x86/kvm/vmx/main.c | 9 ++
> arch/x86/kvm/vmx/vmx.c | 15 ++-
> arch/x86/kvm/vmx/x86_ops.h | 1 +
> arch/x86/kvm/x86.c | 116 ++++++++++--------
> arch/x86/kvm/x86.h | 7 ++
> .../selftests/kvm/include/x86/processor.h | 3 +-
> tools/testing/selftests/kvm/x86/debug_regs.c | 72 ++++++++++-
> 11 files changed, 178 insertions(+), 68 deletions(-)
One goof and some nits on patch 3, but I'll fix them up when applying, i.e. no
need for a v3. I'll probably also add some comments and elaborate on some of
the changelogs.
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-05-11 15:45 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <cover.1766066076.git.houwenlong.hwl@antgroup.com>
[not found] ` <9b859ab6a6b59e5ccfdac741459117996fe2da6e.1766066076.git.houwenlong.hwl@antgroup.com>
2026-05-11 15:23 ` [PATCH v2 2/9] KVM: x86: Set guest DR6 by kvm_queue_exception_p() in instruction emulation Sean Christopherson
2026-05-11 15:26 ` Sean Christopherson
2026-05-11 15:42 ` Sean Christopherson
2026-05-11 15:45 ` [PATCH v2 0/9] KVM: x86: Improve the handling of debug exceptions during " Sean Christopherson
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox