tile: support TIF_SYSCALL_TRACEPOINT; select HAVE_SYSCALL_TRACEPOINTS
authorSimon Marchi <simon.marchi@polymtl.ca>
Tue, 22 Jan 2013 00:54:57 +0000 (19:54 -0500)
committerChris Metcalf <cmetcalf@tilera.com>
Fri, 22 Mar 2013 19:46:18 +0000 (15:46 -0400)
This patch adds support for the TIF_SYSCALL_TRACEPOINT on the tile
architecture. Basically, it calls the appropriate tracepoints on syscall
entry and exit.

Signed-off-by: Simon Marchi <simon.marchi@polymtl.ca>
Signed-off-by: Chris Metcalf <cmetcalf@tilera.com>
arch/tile/Kconfig
arch/tile/include/asm/thread_info.h
arch/tile/kernel/intvec_64.S
arch/tile/kernel/ptrace.c

index e911ef6..0e500d9 100644 (file)
@@ -23,6 +23,7 @@ config TILE
        select GENERIC_CLOCKEVENTS
        select MODULES_USE_ELF_RELA
        select HAVE_ARCH_TRACEHOOK
+       select HAVE_SYSCALL_TRACEPOINTS
 
 # FIXME: investigate whether we need/want these options.
 #      select HAVE_IOREMAP_PROT
index e9c670d..c96331e 100644 (file)
@@ -124,6 +124,7 @@ extern void _cpu_idle(void);
 #define TIF_SECCOMP            6       /* secure computing */
 #define TIF_MEMDIE             7       /* OOM killer at work */
 #define TIF_NOTIFY_RESUME      8       /* callback before returning to user */
+#define TIF_SYSCALL_TRACEPOINT 9       /* syscall tracepoint instrumentation */
 
 #define _TIF_SIGPENDING                (1<<TIF_SIGPENDING)
 #define _TIF_NEED_RESCHED      (1<<TIF_NEED_RESCHED)
@@ -134,12 +135,19 @@ extern void _cpu_idle(void);
 #define _TIF_SECCOMP           (1<<TIF_SECCOMP)
 #define _TIF_MEMDIE            (1<<TIF_MEMDIE)
 #define _TIF_NOTIFY_RESUME     (1<<TIF_NOTIFY_RESUME)
+#define _TIF_SYSCALL_TRACEPOINT        (1<<TIF_SYSCALL_TRACEPOINT)
 
 /* Work to do on any return to user space. */
 #define _TIF_ALLWORK_MASK \
   (_TIF_SIGPENDING|_TIF_NEED_RESCHED|_TIF_SINGLESTEP|\
    _TIF_ASYNC_TLB|_TIF_NOTIFY_RESUME)
 
+/* Work to do at syscall entry. */
+#define _TIF_SYSCALL_ENTRY_WORK (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_TRACEPOINT)
+
+/* Work to do at syscall exit. */
+#define _TIF_SYSCALL_EXIT_WORK (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_TRACEPOINT)
+
 /*
  * Thread-synchronous status.
  *
index 21991f7..85d4839 100644 (file)
@@ -1000,8 +1000,11 @@ handle_syscall:
 
        /* Trace syscalls, if requested. */
        addi    r31, r31, THREAD_INFO_FLAGS_OFFSET
-       ld      r30, r31
-       andi    r30, r30, _TIF_SYSCALL_TRACE
+       {
+        ld     r30, r31
+        moveli r32, _TIF_SYSCALL_ENTRY_WORK
+       }
+       and     r30, r30, r32
        {
         addi   r30, r31, THREAD_INFO_STATUS_OFFSET - THREAD_INFO_FLAGS_OFFSET
         beqzt  r30, .Lrestore_syscall_regs
@@ -1074,8 +1077,11 @@ handle_syscall:
        FEEDBACK_REENTER(handle_syscall)
 
        /* Do syscall trace again, if requested. */
-       ld      r30, r31
-       andi    r0, r30, _TIF_SYSCALL_TRACE
+       {
+        ld      r30, r31
+        moveli  r32, _TIF_SYSCALL_EXIT_WORK
+       }
+       and      r0, r30, r32
        {
         andi    r0, r30, _TIF_SINGLESTEP
         beqzt   r0, 1f
index 0ab8b76..363b2dd 100644 (file)
@@ -25,6 +25,9 @@
 #include <asm/traps.h>
 #include <arch/chip.h>
 
+#define CREATE_TRACE_POINTS
+#include <trace/events/syscalls.h>
+
 void user_enable_single_step(struct task_struct *child)
 {
        set_tsk_thread_flag(child, TIF_SINGLESTEP);
@@ -249,16 +252,24 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
 
 int do_syscall_trace_enter(struct pt_regs *regs)
 {
-       if (tracehook_report_syscall_entry(regs)) {
-               regs->regs[TREG_SYSCALL_NR] = -1;
+       if (test_thread_flag(TIF_SYSCALL_TRACE)) {
+               if (tracehook_report_syscall_entry(regs))
+                       regs->regs[TREG_SYSCALL_NR] = -1;
        }
 
+       if (test_thread_flag(TIF_SYSCALL_TRACEPOINT))
+               trace_sys_enter(regs, regs->regs[TREG_SYSCALL_NR]);
+
        return regs->regs[TREG_SYSCALL_NR];
 }
 
 void do_syscall_trace_exit(struct pt_regs *regs)
 {
-       tracehook_report_syscall_exit(regs, 0);
+       if (test_thread_flag(TIF_SYSCALL_TRACE))
+               tracehook_report_syscall_exit(regs, 0);
+
+       if (test_thread_flag(TIF_SYSCALL_TRACEPOINT))
+               trace_sys_exit(regs, regs->regs[TREG_SYSCALL_NR]);
 }
 
 void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int error_code)