[PATCH v17 01/15] arm64: ptrace: Skip syscall exit reporting for PTRACE_SYSEMU_SINGLESTEP

Jinjie Ruan ruanjinjie at huawei.com
Tue Jul 21 01:18:44 PDT 2026


According to 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."

When a tracer uses PTRACE_SYSEMU_SINGLESTEP, both _TIF_SYSCALL_EMU
and _TIF_SINGLESTEP are set. Currently, arm64 unconditionally reports
a syscall exit stop whenever _TIF_SINGLESTEP is set, regardless of the
emulation state. This deviates from the documented behavior and breaks
consistency with x86, where PTRACE_SYSEMU_SINGLESTEP does not trigger
a redundant exit stop.

[Changes]
- Introduce report_single_step(): Returns false when _TIF_SYSCALL_EMU
  is set, ensuring emulated syscalls do not trigger a duplicate report.

- Update syscall_exit_work(): Use the new helper instead of directly
  checking _TIF_SINGLESTEP.

[Impact]
- PTRACE_SINGLESTEP: Continues to report exit stops for actual
  instructions.
- PTRACE_SYSEMU: Continues to skip exit stops.
- PTRACE_SYSEMU_SINGLESTEP: Now correctly skips the redundant exit stop,
  aligning arm64 with documentation and the generic entry infrastructure.

Cc: Mark Rutland <mark.rutland at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Catalin Marinas <catalin.marinas at arm.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 924805e0c8da..4e9c71d477a5 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);
-- 
2.34.1




More information about the linux-arm-kernel mailing list