Re: [PATCH 4/7] KVM: x86: Consolidate KVM_GUESTDBG_SINGLESTEP check into the kvm_inject_emulated_db()
From: Sean Christopherson
Date: Fri Dec 12 2025 - 12:53:22 EST
On Fri, Dec 12, 2025, Hou Wenlong wrote:
> On Thu, Dec 11, 2025 at 09:19:39AM -0800, Sean Christopherson wrote:
> > On Thu, Dec 11, 2025, Hou Wenlong wrote:
> > +static noinline unsigned long singlestep_with_code_db(void)
> > +{
> > + unsigned long start;
> > +
> > + asm volatile (
> > + "lea 1f(%%rip), %0\n\t"
> > + "mov %0, %%dr2\n\t"
> > + "mov $" xstr(DR7_FIXED_1 | DR7_EXECUTE_DRx(2) | DR7_GLOBAL_ENABLE_DR2) ", %0\n\t"
> > + "mov %0, %%dr7\n\t"
> > + "pushf\n\t"
> > + "pop %%rax\n\t"
> > + "or $(1<<8),%%rax\n\t"
> > + "push %%rax\n\t"
> > + "popf\n\t"
> > + "and $~(1<<8),%%rax\n\t"
> In my previous understanding, I thought there would be two #DBs
> generated at the instruction boundary. First, the single-step trap #DB
> would be handled, and then, when resuming to start the new instruction,
> it would check for the code breakpoint and generate a code fault #DB.
> However, it turns out that the check for the code breakpoint happened
> before the instruction boundary.
Yeah, that's what I was trying to explain by describing code breakpoint as fault-like.
> I also see in the kernel hardware breakpoint handler that it notes that code
> breakpoints and single-step can be detected together. Is this due to
> instruction prefetch?
Nope, it's just how #DBs work, everything pending gets smushed together. Note,
data #DBs can also be coincident. E.g. it's entirely possible that you could
observe a code breakpoint, a data breakpoint, and a single-step breakpoint in a
single #DB.
> If we want to emulate the hardware behavior in the emulator, does that
> mean we need to check for code breakpoints in kvm_vcpu_do_single_step()
> and set the DR_TRAP_BITS along with the DR6_BS bit?
Hmm, ya, I think so? I don't think the CPU will fetch and merge the imminent
code #DB with the injected single-step #DB.