xtensa: implement syscall tracepoints
authorMax Filippov <jcmvbkbc@gmail.com>
Mon, 12 Nov 2018 05:51:49 +0000 (21:51 -0800)
committerMax Filippov <jcmvbkbc@gmail.com>
Mon, 17 Dec 2018 21:50:25 +0000 (13:50 -0800)
Add TIF_SYSCALL_TRACEPOINT flag definition; add _TIF_SYSCALL_TRACEPOINT
to _TIF_WORK_MASK. Call trace_sys_enter from do_syscall_trace_enter and
trace_sys_exit from do_syscall_trace_leave when TIF_SYSCALL_TRACEPOINT
flag is set.
Add declaration of sys_call_table to arch/xtensa/include/asm/syscall.h
Add definition of NR_syscalls to arch/xtensa/include/asm/unistd.h
Select HAVE_SYSCALL_TRACEPOINTS.

This change allows tracing each syscall entry and exit through the
ftrace mechanism.

Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
arch/xtensa/Kconfig
arch/xtensa/include/asm/ptrace.h
arch/xtensa/include/asm/syscall.h
arch/xtensa/include/asm/thread_info.h
arch/xtensa/include/asm/unistd.h
arch/xtensa/kernel/ptrace.c
arch/xtensa/kernel/syscall.c

index 55d13b589ff3e462fc9697e4a0ba0bdb734c8431..5a27a6fd3a1c4f22fb333e353e80f24f1bddcdc0 100644 (file)
@@ -29,6 +29,7 @@ config XTENSA
        select HAVE_OPROFILE
        select HAVE_PERF_EVENTS
        select HAVE_STACKPROTECTOR
+       select HAVE_SYSCALL_TRACEPOINTS
        select IRQ_DOMAIN
        select MODULES_USE_ELF_RELA
        select PERF_USE_VMALLOC
index f1b1de526d1d12bcdaed8cbc9ce6cec18cb32061..62a58d2567e94459d0cdbf4c5f9f95236b4d7858 100644 (file)
@@ -102,6 +102,11 @@ struct pt_regs {
 
 #define user_stack_pointer(regs) ((regs)->areg[1])
 
+static inline unsigned long regs_return_value(struct pt_regs *regs)
+{
+       return regs->areg[2];
+}
+
 #else  /* __ASSEMBLY__ */
 
 # include <asm/asm-offsets.h>
index e47470ec8ea8d8bd09a33a8751b18d78e9b199e9..a168bf81c7f4701a036abaa251fa5dce7fad6c19 100644 (file)
@@ -19,6 +19,9 @@ static inline int syscall_get_arch(void)
        return AUDIT_ARCH_XTENSA;
 }
 
+typedef void (*syscall_t)(void);
+extern syscall_t sys_call_table[];
+
 static inline long syscall_get_nr(struct task_struct *task,
                                  struct pt_regs *regs)
 {
index c823dddfebdfe4e92cab323b3de804a873781e16..f333f10a7650dbfe9cbd1771d307bae577104f7d 100644 (file)
@@ -106,6 +106,7 @@ static inline struct thread_info *current_thread_info(void)
 #define TIF_SIGPENDING         1       /* signal pending */
 #define TIF_NEED_RESCHED       2       /* rescheduling necessary */
 #define TIF_SINGLESTEP         3       /* restore singlestep on return to user mode */
+#define TIF_SYSCALL_TRACEPOINT 4       /* syscall tracepoint instrumentation */
 #define TIF_MEMDIE             5       /* is terminating due to OOM killer */
 #define TIF_RESTORE_SIGMASK    6       /* restore signal mask in do_signal() */
 #define TIF_NOTIFY_RESUME      7       /* callback before returning to user */
@@ -115,8 +116,10 @@ static inline struct thread_info *current_thread_info(void)
 #define _TIF_SIGPENDING                (1<<TIF_SIGPENDING)
 #define _TIF_NEED_RESCHED      (1<<TIF_NEED_RESCHED)
 #define _TIF_SINGLESTEP                (1<<TIF_SINGLESTEP)
+#define _TIF_SYSCALL_TRACEPOINT        (1<<TIF_SYSCALL_TRACEPOINT)
 
-#define _TIF_WORK_MASK         (_TIF_SYSCALL_TRACE | _TIF_SINGLESTEP)
+#define _TIF_WORK_MASK         (_TIF_SYSCALL_TRACE | _TIF_SINGLESTEP | \
+                                _TIF_SYSCALL_TRACEPOINT)
 
 /*
  * Thread-synchronous status.
index 574e5520968c263e3147271abca3f4eba4df3378..0d34629dafc5194a93641f00f7ea60a7769aa752 100644 (file)
@@ -22,4 +22,6 @@
 #define __IGNORE_vfork                         /* use clone */
 #define __IGNORE_fadvise64                     /* use fadvise64_64 */
 
+#define NR_syscalls                            __NR_syscalls
+
 #endif /* _XTENSA_UNISTD_H */
index 207aa272b48cd584a5cbb9d6c12e6dd3f35fbfdb..b964f0b2d8864ea091ecca93ab0cf14754aaac80 100644 (file)
@@ -27,6 +27,9 @@
 #include <linux/tracehook.h>
 #include <linux/uaccess.h>
 
+#define CREATE_TRACE_POINTS
+#include <trace/events/syscalls.h>
+
 #include <asm/coprocessor.h>
 #include <asm/elf.h>
 #include <asm/page.h>
@@ -545,12 +548,17 @@ void do_syscall_trace_enter(struct pt_regs *regs)
            tracehook_report_syscall_entry(regs))
                regs->syscall = NO_SYSCALL;
 
+       if (test_thread_flag(TIF_SYSCALL_TRACEPOINT))
+               trace_sys_enter(regs, syscall_get_nr(current, regs));
 }
 
 void do_syscall_trace_leave(struct pt_regs *regs)
 {
        int step;
 
+       if (test_thread_flag(TIF_SYSCALL_TRACEPOINT))
+               trace_sys_exit(regs, regs_return_value(regs));
+
        step = test_thread_flag(TIF_SINGLESTEP);
 
        if (step || test_thread_flag(TIF_SYSCALL_TRACE))
index b8240e08f1f180da861c2929dc12a69bf0a35533..2c415fce6801ac448f9b13c47e092fe21234911f 100644 (file)
@@ -28,8 +28,6 @@
 #include <linux/sched/mm.h>
 #include <linux/shm.h>
 
-typedef void (*syscall_t)(void);
-
 syscall_t sys_call_table[__NR_syscalls] /* FIXME __cacheline_aligned */= {
        [0 ... __NR_syscalls - 1] = (syscall_t)&sys_ni_syscall,