]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
arm64/ptrace: Split report_syscall()
authorJinjie Ruan <ruanjinjie@huawei.com>
Mon, 22 Dec 2025 11:47:23 +0000 (19:47 +0800)
committerWill Deacon <will@kernel.org>
Tue, 27 Jan 2026 10:38:35 +0000 (10:38 +0000)
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 <anshuman.khandual@arm.com>
Reviewed-by: Kevin Brodsky <kevin.brodsky@arm.com>
Suggested-by: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
Signed-off-by: Will Deacon <will@kernel.org>
arch/arm64/kernel/ptrace.c

index b9bdd83fbbca0f3ba6b6b0d1458fcfedb8a9a998..03fe2f8a4d5400ff7a6b95eb11b23b86a53cef7b 100644 (file)
@@ -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, &regno);
+       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, &regno);
+       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);
 }