[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