entry: Add arch_ptrace_report_syscall_entry/exit()

ARM64 requires a architecture specific ptrace wrapper as it needs to save
and restore scratch registers.

Provide arch_ptrace_report_syscall_entry/exit() wrappers which fall back to
ptrace_report_syscall_entry/exit() if the architecture does not provide
them.

No functional change intended.

[ tglx: Massaged changelog and comments ]

Suggested-by: Mark Rutland <mark.rutland@arm.com>
Suggested-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
Signed-off-by: Thomas Gleixner <tglx@kernel.org>
Reviewed-by: Kevin Brodsky <kevin.brodsky@arm.com>
Link: https://patch.msgid.link/20260128031934.3906955-11-ruanjinjie@huawei.com
This commit is contained in:
Jinjie Ruan 2026-01-28 11:19:30 +08:00 committed by Thomas Gleixner
parent e1647100c2
commit 578b21fd3a
2 changed files with 38 additions and 2 deletions

View file

@ -45,6 +45,24 @@
SYSCALL_WORK_SYSCALL_EXIT_TRAP | \
ARCH_SYSCALL_WORK_EXIT)
/**
* arch_ptrace_report_syscall_entry - Architecture specific ptrace_report_syscall_entry() wrapper
*
* Invoked from syscall_trace_enter() to wrap ptrace_report_syscall_entry().
*
* This allows architecture specific ptrace_report_syscall_entry()
* implementations. If not defined by the architecture this falls back to
* to ptrace_report_syscall_entry().
*/
static __always_inline int arch_ptrace_report_syscall_entry(struct pt_regs *regs);
#ifndef arch_ptrace_report_syscall_entry
static __always_inline int arch_ptrace_report_syscall_entry(struct pt_regs *regs)
{
return ptrace_report_syscall_entry(regs);
}
#endif
long syscall_trace_enter(struct pt_regs *regs, unsigned long work);
/**
@ -112,6 +130,24 @@ static __always_inline long syscall_enter_from_user_mode(struct pt_regs *regs, l
return ret;
}
/**
* arch_ptrace_report_syscall_exit - Architecture specific ptrace_report_syscall_exit()
*
* This allows architecture specific ptrace_report_syscall_exit()
* implementations. If not defined by the architecture this falls back to
* to ptrace_report_syscall_exit().
*/
static __always_inline void arch_ptrace_report_syscall_exit(struct pt_regs *regs,
int step);
#ifndef arch_ptrace_report_syscall_exit
static __always_inline void arch_ptrace_report_syscall_exit(struct pt_regs *regs,
int step)
{
ptrace_report_syscall_exit(regs, step);
}
#endif
/**
* syscall_exit_work - Handle work before returning to user mode
* @regs: Pointer to current pt_regs

View file

@ -33,7 +33,7 @@ long syscall_trace_enter(struct pt_regs *regs, unsigned long work)
/* Handle ptrace */
if (work & (SYSCALL_WORK_SYSCALL_TRACE | SYSCALL_WORK_SYSCALL_EMU)) {
ret = ptrace_report_syscall_entry(regs);
ret = arch_ptrace_report_syscall_entry(regs);
if (ret || (work & SYSCALL_WORK_SYSCALL_EMU))
return -1L;
}
@ -99,5 +99,5 @@ void syscall_exit_work(struct pt_regs *regs, unsigned long work)
step = report_single_step(work);
if (step || work & SYSCALL_WORK_SYSCALL_TRACE)
ptrace_report_syscall_exit(regs, step);
arch_ptrace_report_syscall_exit(regs, step);
}