[PATCH v19 01/14] arm64: ptrace: Fix redundant syscall exit stop for PTRACE_SYSEMU_SINGLESTEP
Jinjie Ruan
ruanjinjie at huawei.com
Wed Sep 23 01:28:27 PDT 2026
Will fix the pseudo-singlestep problem as sashiko pointed as below.
https://sashiko.dev/#/patchset/20260922035510.1090299-1-ruanjinjie%40huawei.com
在 2026/9/22 11:54, Jinjie Ruan 写道:
> PTRACE_SYSEMU_SINGLESTEP sets both _TIF_SYSCALL_EMU and _TIF_SINGLESTEP.
> arm64 currently reports a syscall exit stop whenever _TIF_SINGLESTEP is
> set, regardless of emulation state.
>
> This violates the ptrace man page (Syscall-stops section):
>
> "If the tracee was restarted by PTRACE_SYSCALL or PTRACE_SYSEMU,
> the tracee enters syscall-enter-stop just prior to entering any
> system call (which will not be executed if the restart was using
> PTRACE_SYSEMU, regardless of any change made to registers at this
> point or how the tracee is restarted after this stop). ...
> If the tracee is continued using any other method (including
> PTRACE_SYSEMU), no syscall-exit-stop occurs. Note that all mentions
> PTRACE_SYSEMU apply equally to PTRACE_SYSEMU_SINGLESTEP."
>
> Fix by introducing report_single_step(), which returns false when
> _TIF_SYSCALL_EMU is set, skipping the redundant exit stop.
>
> Cc: Mark Rutland <mark.rutland at arm.com>
> Cc: Will Deacon <will at kernel.org>
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Oleg Nesterov <oleg at redhat.com>
> Fixes: ac2081cdc4d9 ("arm64: ptrace: Consistently use pseudo-singlestep exceptions")
> Reviewed-by: Ada Couprie Diaz <ada.coupriediaz at arm.com>
> Reviewed-by: Linus Walleij <linusw at kernel.org>
> Reviewed-by: Yeoreum Yun <yeoreum.yun at arm.com>
> Signed-off-by: Jinjie Ruan <ruanjinjie at huawei.com>
> ---
> arch/arm64/kernel/ptrace.c | 12 +++++++++++-
> 1 file changed, 11 insertions(+), 1 deletion(-)
>
> diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
> index f743cbec1c3a..96462de75d4b 100644
> --- a/arch/arm64/kernel/ptrace.c
> +++ b/arch/arm64/kernel/ptrace.c
> @@ -2482,16 +2482,26 @@ int syscall_trace_enter(struct pt_regs *regs)
> return regs->syscallno;
> }
>
> +static inline bool report_single_step(unsigned long flags)
> +{
> + if (flags & _TIF_SYSCALL_EMU)
> + return false;
> +
> + return flags & _TIF_SINGLESTEP;
> +}
> +
> void syscall_trace_exit(struct pt_regs *regs)
> {
> unsigned long flags = read_thread_flags();
> + bool step;
>
> audit_syscall_exit(regs);
>
> if (flags & _TIF_SYSCALL_TRACEPOINT)
> trace_sys_exit(regs, syscall_get_return_value(current, regs));
>
> - if (flags & (_TIF_SYSCALL_TRACE | _TIF_SINGLESTEP))
> + step = report_single_step(flags);
> + if (step || flags & _TIF_SYSCALL_TRACE)
> report_syscall_exit(regs);
>
> rseq_syscall(regs);
--
Best regards,
Jinjie
More information about the linux-arm-kernel
mailing list