Commit 3157858f authored by AKASHI Takahiro's avatar AKASHI Takahiro Committed by Catalin Marinas

arm64: split syscall_trace() into separate functions for enter/exit

As done in arm, this change makes it easy to confirm we invoke syscall
related hooks, including syscall tracepoint, audit and seccomp which would
be implemented later, in correct order. That is, undoing operations in the
opposite order on exit that they were done on entry.
Acked-by: default avatarWill Deacon <will.deacon@arm.com>
Signed-off-by: default avatarAKASHI Takahiro <takahiro.akashi@linaro.org>
Signed-off-by: default avatarWill Deacon <will.deacon@arm.com>
Signed-off-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
parent 449f81a4
...@@ -628,9 +628,8 @@ ENDPROC(el0_svc) ...@@ -628,9 +628,8 @@ ENDPROC(el0_svc)
* switches, and waiting for our parent to respond. * switches, and waiting for our parent to respond.
*/ */
__sys_trace: __sys_trace:
mov x1, sp mov x0, sp
mov w0, #0 // trace entry bl syscall_trace_enter
bl syscall_trace
adr lr, __sys_trace_return // return address adr lr, __sys_trace_return // return address
uxtw scno, w0 // syscall number (possibly new) uxtw scno, w0 // syscall number (possibly new)
mov x1, sp // pointer to regs mov x1, sp // pointer to regs
...@@ -645,9 +644,8 @@ __sys_trace: ...@@ -645,9 +644,8 @@ __sys_trace:
__sys_trace_return: __sys_trace_return:
str x0, [sp] // save returned x0 str x0, [sp] // save returned x0
mov x1, sp mov x0, sp
mov w0, #1 // trace exit bl syscall_trace_exit
bl syscall_trace
b ret_to_user b ret_to_user
/* /*
......
...@@ -1058,35 +1058,43 @@ long arch_ptrace(struct task_struct *child, long request, ...@@ -1058,35 +1058,43 @@ long arch_ptrace(struct task_struct *child, long request,
return ptrace_request(child, request, addr, data); return ptrace_request(child, request, addr, data);
} }
asmlinkage int syscall_trace(int dir, struct pt_regs *regs) enum ptrace_syscall_dir {
PTRACE_SYSCALL_ENTER = 0,
PTRACE_SYSCALL_EXIT,
};
static void tracehook_report_syscall(struct pt_regs *regs,
enum ptrace_syscall_dir dir)
{ {
int regno;
unsigned long saved_reg; unsigned long saved_reg;
if (!test_thread_flag(TIF_SYSCALL_TRACE))
return regs->syscallno;
if (is_compat_task()) {
/* AArch32 uses ip (r12) for scratch */
saved_reg = regs->regs[12];
regs->regs[12] = dir;
} else {
/* /*
* Save X7. X7 is used to denote syscall entry/exit: * A scratch register (ip(r12) on AArch32, x7 on AArch64) is
* X7 = 0 -> entry, = 1 -> exit * used to denote syscall entry/exit:
*/ */
saved_reg = regs->regs[7]; regno = (is_compat_task() ? 12 : 7);
regs->regs[7] = dir; saved_reg = regs->regs[regno];
} regs->regs[regno] = dir;
if (dir) if (dir == PTRACE_SYSCALL_EXIT)
tracehook_report_syscall_exit(regs, 0); tracehook_report_syscall_exit(regs, 0);
else if (tracehook_report_syscall_entry(regs)) else if (tracehook_report_syscall_entry(regs))
regs->syscallno = ~0UL; regs->syscallno = ~0UL;
if (is_compat_task()) regs->regs[regno] = saved_reg;
regs->regs[12] = saved_reg; }
else
regs->regs[7] = saved_reg; asmlinkage int syscall_trace_enter(struct pt_regs *regs)
{
if (test_thread_flag(TIF_SYSCALL_TRACE))
tracehook_report_syscall(regs, PTRACE_SYSCALL_ENTER);
return regs->syscallno; return regs->syscallno;
} }
asmlinkage void syscall_trace_exit(struct pt_regs *regs)
{
if (test_thread_flag(TIF_SYSCALL_TRACE))
tracehook_report_syscall(regs, PTRACE_SYSCALL_EXIT);
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment