On Thu, Dec 18, 2025, Hou Wenlong wrote:
> In the x86's debug_regs test, add a test case to cover the scenario
> where single-step with STI in VMX sets the 'BS' bit in pending debug
> exceptions state for #DB interception and instruction emulation in both
> cases.
...
> +static void guest_db_handler(struct ex_regs *regs)
> +{
> + static int count;
> + unsigned long target_rips[2] = {
> + CAST_TO_RIP(fep_sti_start),
> + CAST_TO_RIP(fep_sti_end),
> + };
> +
> + __GUEST_ASSERT(regs->rip == target_rips[count], "STI: unexpected rip
> 0x%lx (should be 0x%lx)",
> + regs->rip, target_rips[count]);
> + regs->rflags &= ~X86_EFLAGS_TF;
> + count++;
> +}
> +
> +static void guest_irq_handler(struct ex_regs *regs)
> +{
> + unsigned long target_rip = CAST_TO_RIP(fep_bd_start);
> +
> + __GUEST_ASSERT(regs->rip == target_rip, "IRQ: unexpected rip 0x%lx
> (should be 0x%lx)",
> + regs->rip, target_rip);
This is wrong, and the test fails with your series applied verbatim. The IRQ
will arrive at fep_sti_start, because RFLAGS.IF=0 from the CLI at the end of the
ss_start block, and remains that way across fep_bd_start. And to make things
even more confusing, the IRQ arrives on the CLI even though it's in an STI
shadow
due to #DBs not being subjected to _STI_ shadows on Intel, only to MOV-SS/POP-SS
shadows. I.e. the #DB lands on CLI, pushes RFLAGS.IF=1 on the stack, and then
the subsequent IRET from guest_db_handler() fully unmasks IRQs, and voila.