Skip to content

Commit

Permalink
arm64: ftrace: Add system call tracepoint
Browse files Browse the repository at this point in the history
This patch allows system call entry or exit to be traced as ftrace events,
ie. sys_enter_*/sys_exit_*, if CONFIG_FTRACE_SYSCALLS is enabled.
Those events appear and can be controlled under
    ${sysfs}/tracing/events/syscalls/

Please note that we can't trace compat system calls here because
AArch32 mode does not share the same syscall table with AArch64.
Just define ARCH_TRACE_IGNORE_COMPAT_SYSCALLS in order to avoid unexpected
results (bogus syscalls reported or even hang-up).

Acked-by: Will Deacon <[email protected]>
Signed-off-by: AKASHI Takahiro <[email protected]>
Signed-off-by: Will Deacon <[email protected]>
  • Loading branch information
AKASHI Takahiro authored and wildea01 committed May 29, 2014
1 parent 3711784 commit 055b121
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 0 deletions.
1 change: 1 addition & 0 deletions arch/arm64/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ config ARM64
select HAVE_PERF_EVENTS
select HAVE_PERF_REGS
select HAVE_PERF_USER_STACK_DUMP
select HAVE_SYSCALL_TRACEPOINTS
select IRQ_DOMAIN
select MODULES_USE_ELF_RELA
select NO_BOOTMEM
Expand Down
18 changes: 18 additions & 0 deletions arch/arm64/include/asm/ftrace.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
#define MCOUNT_INSN_SIZE AARCH64_INSN_SIZE

#ifndef __ASSEMBLY__
#include <linux/compat.h>

extern void _mcount(unsigned long);
extern void *return_address(unsigned int);

Expand All @@ -36,6 +38,22 @@ static inline unsigned long ftrace_call_adjust(unsigned long addr)
}

#define ftrace_return_address(n) return_address(n)

/*
* Because AArch32 mode does not share the same syscall table with AArch64,
* tracing compat syscalls may result in reporting bogus syscalls or even
* hang-up, so just do not trace them.
* See kernel/trace/trace_syscalls.c
*
* x86 code says:
* If the user realy wants these, then they should use the
* raw syscall tracepoints with filtering.
*/
#define ARCH_TRACE_IGNORE_COMPAT_SYSCALLS
static inline bool arch_trace_is_compat_syscall(struct pt_regs *regs)
{
return is_compat_task();
}
#endif /* ifndef __ASSEMBLY__ */

#endif /* __ASM_FTRACE_H */
1 change: 1 addition & 0 deletions arch/arm64/include/asm/syscall.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

#include <linux/err.h>

extern const void *sys_call_table[];

static inline int syscall_get_nr(struct task_struct *task,
struct pt_regs *regs)
Expand Down
2 changes: 2 additions & 0 deletions arch/arm64/include/asm/unistd.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,5 @@
#endif
#define __ARCH_WANT_SYS_CLONE
#include <uapi/asm/unistd.h>

#define NR_syscalls (__NR_syscalls)
9 changes: 9 additions & 0 deletions arch/arm64/kernel/ptrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@
#include <asm/traps.h>
#include <asm/system_misc.h>

#define CREATE_TRACE_POINTS
#include <trace/events/syscalls.h>

/*
* TODO: does not yet catch signals sent when the child dies.
* in exit.c or in signal.c.
Expand Down Expand Up @@ -1093,11 +1096,17 @@ asmlinkage int syscall_trace_enter(struct pt_regs *regs)
if (test_thread_flag(TIF_SYSCALL_TRACE))
tracehook_report_syscall(regs, PTRACE_SYSCALL_ENTER);

if (test_thread_flag(TIF_SYSCALL_TRACEPOINT))
trace_sys_enter(regs, regs->syscallno);

return regs->syscallno;
}

asmlinkage void syscall_trace_exit(struct pt_regs *regs)
{
if (test_thread_flag(TIF_SYSCALL_TRACEPOINT))
trace_sys_exit(regs, regs_return_value(regs));

if (test_thread_flag(TIF_SYSCALL_TRACE))
tracehook_report_syscall(regs, PTRACE_SYSCALL_EXIT);
}

0 comments on commit 055b121

Please sign in to comment.