From: sai madhu kvm_emulate_halt() calls kvm_skip_emulated_instruction() before kvm_emulate_halt_noskip(). When single-step debugging is active, the skip path can trigger a debug exception and set exit_reason to KVM_EXIT_DEBUG, but halt emulation then overwrites it with KVM_EXIT_HLT on the userspace LAPIC path. Return immediately when a debug exit is already pending so userspace debuggers receive the correct event. Signed-off-by: sai madhu --- arch/x86/kvm/x86.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 0626e835e9eb..2fd6ad49050c 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -8658,10 +8658,16 @@ EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_emulate_halt_noskip); int kvm_emulate_halt(struct kvm_vcpu *vcpu) { int ret = kvm_skip_emulated_instruction(vcpu); + /* - * TODO: we might be squashing a GUESTDBG_SINGLESTEP-triggered - * KVM_EXIT_DEBUG here. + * If kvm_skip_emulated_instruction() triggered a singlestep + * debug exception, return to userspace immediately so the + * debugger can process the event. Do not let halt emulation + * overwrite the KVM_EXIT_DEBUG exit reason. */ + if (vcpu->run->exit_reason == KVM_EXIT_DEBUG) + return ret; + return kvm_emulate_halt_noskip(vcpu) && ret; } EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_emulate_halt); -- 2.43.0