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 <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>
This commit is contained in:
Jinjie Ruan 2025-12-22 19:47:23 +08:00 committed by Will Deacon
parent e7e7afdc7c
commit 741a900017

View 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);
}