On Fri, Jul 31, 2026 at 09:46:38PM +0300, Doru Blânzeanu wrote:
> This series brings guest debugging to the MSHV accelerator by
> implementing software breakpoints and single-stepping, so that gdb can
> attach to an MSHV guest through QEMU's gdbstub.
> 
> It follows the KVM gdbstub implementation closely, and borrows the WHPX
> approach where the MSHV interface differs from KVM:
> 
>   - it installs a partition-wide intercept for the #DB exception
>     (HVCALL_INSTALL_INTERCEPT). #BP (INT3) is deliberately left to the
>     guest's own IDT and is never intercepted, as WHPX does.
> 
>   - only software breakpoints are supported. A breakpoint is an INT1
>     (opcode 0xf1) patched into guest memory, which raises a #DB when
>     executed. Hardware breakpoints and watchpoints are not supported.
> 
>   - it never touches the guest debug registers (DR0-DR7), so guest state
>     is not clobbered. The only guest register used is RFLAGS.TF, toggled
>     around the vCPU run for single-stepping and kept out of env->eflags
>     so it cannot be read back and re-armed.
> 
>   - it re-injects the #DB back into the guest (via
>     HV_REGISTER_PENDING_EVENT0) when the faulting RIP does not match a
>     debugger breakpoint, so a guest-owned #DB is delivered through the
>     guest's own IDT.
> 
> When a vCPU is created we register the accel ops that gdb drives once it
> is attached:
> 
>   - mshv_update_guest_debug
>   - mshv_insert_gdbstub_breakpoint
>   - mshv_remove_gdbstub_breakpoint
>   - mshv_remove_all_gdbstub_breakpoints
> 
> For each insert request from gdb the ops save the original byte at the
> target address and patch in 0xf1; on a remove request the saved byte is
> restored, after which gdb single-steps over the original instruction and
> re-inserts the breakpoint. When the vCPU executes the 0xf1 byte a #DB
> vmexits to QEMU. mshv_handle_debug() then checks whether the RIP where
> the vCPU stopped matches a breakpoint installed by gdb, or whether
> single-stepping is active, and if so reports the stop to gdb. If the RIP
> does not match any debugger breakpoint the #DB is assumed to be
> guest-owned and is re-injected so the guest can handle it.
> 
> Known limitations:
> 
>   - Once installed, the #DB intercept stays for the lifetime
>     of the VM and every #DB - including those the guest raises itself -
>     vmexits to QEMU.
> 
>   - Because attribution relies on matching the faulting RIP against the
>     debugger's breakpoint list, a guest that legitimately executes INT1 or
>     raises its own #DB at an address that also holds a debugger breakpoint
>     cannot be disambiguated; such overlaps are not expected in practice.
> 
> The series is organised as:
> 
>   1. include/hw/hyperv: add ABI for exception intercepts and pending
>      events
>   2. accel/mshv: add gdbstub software breakpoint support
>   3. target/i386/mshv: support single-stepping
>   4. accel/mshv: break the vCPU run loop on exit_request
>      This commit fixes a race condition encountered during testing with guests
>      that run infinite loops with some debugging opcodes.
> 
> I have tested this patch series by using both a guest that doesn't use 
> debugging
> and one that triggers the #DB and #BP exceptions (#DB is re-injected and #BP 
> is
> not intercepted at all).
> 
> Changes since v1:
> - refactored the HVMSG_X64_EXCEPTION_INTERCEPT vmexit handle to be contained 
> in
>   a standalone function handle_exception_interrupt
> - add new commit that checks the mshv vcpu run loop for exit requests before
>   re-entering MSHV_RUN_VP. This ensures a busy vCPU doesn't ignore gdb 
> commands.
> 
> Doru Blânzeanu (4):
>   include/hw/hyperv: add ABI for exception intercepts and pending events
>   accel/mshv: add gdbstub software breakpoint support
>   target/i386/mshv: support single-stepping
>   accel/mshv: break the vCPU run loop on exit_request
> 
>  accel/mshv/mshv-all.c          | 175 ++++++++++++++++++++++++++++++++-
>  include/hw/hyperv/hvgdk_mini.h |  56 +++++++++++
>  include/system/mshv_int.h      |  14 +++
>  target/i386/mshv/mshv-cpu.c    | 154 +++++++++++++++++++++++++++++
>  4 files changed, 398 insertions(+), 1 deletion(-)
> 
> -- 
> 2.53.0

included in mkulke-pull-20261006, skipped 4/4


Reply via email to