From: Jinjie Ruan Date: Mon, 22 Dec 2025 11:47:23 +0000 (+0800) Subject: arm64/ptrace: Split report_syscall() X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=741a9000173a036526eb2374e1ba34c466754f1c;p=thirdparty%2Flinux.git arm64/ptrace: Split report_syscall() The generic syscall entry code has the form: | syscall_trace_enter() | { | ptrace_report_syscall_entry() | } | | syscall_exit_work() | { | ptrace_report_syscall_exit() | } In preparation for moving arm64 over to the generic entry code, split report_syscall() to two separate enter and exit functions to align the structure of the arm64 code with syscall_trace_enter() and syscall_exit_work() from the generic entry code. No functional changes. Reviewed-by: Anshuman Khandual Reviewed-by: Kevin Brodsky Suggested-by: Mark Rutland Signed-off-by: Jinjie Ruan Signed-off-by: Will Deacon --- diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c index b9bdd83fbbca0..03fe2f8a4d540 100644 --- a/arch/arm64/kernel/ptrace.c +++ b/arch/arm64/kernel/ptrace.c @@ -2343,9 +2343,10 @@ enum ptrace_syscall_dir { PTRACE_SYSCALL_EXIT, }; -static void report_syscall(struct pt_regs *regs, enum ptrace_syscall_dir dir) +static __always_inline unsigned long ptrace_save_reg(struct pt_regs *regs, + enum ptrace_syscall_dir dir, + int *regno) { - int regno; unsigned long saved_reg; /* @@ -2364,15 +2365,31 @@ static void report_syscall(struct pt_regs *regs, enum ptrace_syscall_dir dir) * - Syscall stops behave differently to seccomp and pseudo-step traps * (the latter do not nobble any registers). */ - regno = (is_compat_task() ? 12 : 7); - saved_reg = regs->regs[regno]; - regs->regs[regno] = dir; + *regno = (is_compat_task() ? 12 : 7); + saved_reg = regs->regs[*regno]; + regs->regs[*regno] = dir; - if (dir == PTRACE_SYSCALL_ENTER) { - if (ptrace_report_syscall_entry(regs)) - forget_syscall(regs); - regs->regs[regno] = saved_reg; - } else if (!test_thread_flag(TIF_SINGLESTEP)) { + return saved_reg; +} + +static void report_syscall_entry(struct pt_regs *regs) +{ + unsigned long saved_reg; + int regno; + + saved_reg = ptrace_save_reg(regs, PTRACE_SYSCALL_ENTER, ®no); + if (ptrace_report_syscall_entry(regs)) + forget_syscall(regs); + regs->regs[regno] = saved_reg; +} + +static void report_syscall_exit(struct pt_regs *regs) +{ + unsigned long saved_reg; + int regno; + + saved_reg = ptrace_save_reg(regs, PTRACE_SYSCALL_EXIT, ®no); + if (!test_thread_flag(TIF_SINGLESTEP)) { ptrace_report_syscall_exit(regs, 0); regs->regs[regno] = saved_reg; } else { @@ -2392,7 +2409,7 @@ int syscall_trace_enter(struct pt_regs *regs) unsigned long flags = read_thread_flags(); if (flags & (_TIF_SYSCALL_EMU | _TIF_SYSCALL_TRACE)) { - report_syscall(regs, PTRACE_SYSCALL_ENTER); + report_syscall_entry(regs); if (flags & _TIF_SYSCALL_EMU) return NO_SYSCALL; } @@ -2420,7 +2437,7 @@ void syscall_trace_exit(struct pt_regs *regs) trace_sys_exit(regs, syscall_get_return_value(current, regs)); if (flags & (_TIF_SYSCALL_TRACE | _TIF_SINGLESTEP)) - report_syscall(regs, PTRACE_SYSCALL_EXIT); + report_syscall_exit(regs); rseq_syscall(regs); }