ARC: implement syscall tracepoints
authorSergey Matyukevich <sergey.matyukevich@synopsys.com>
Thu, 14 Apr 2022 08:17:23 +0000 (11:17 +0300)
committerVineet Gupta <vgupta@kernel.org>
Mon, 25 Apr 2022 20:09:47 +0000 (13:09 -0700)
Implement all the bits required to support HAVE_SYSCALL_TRACEPOINTS
according to Documentation/trace/ftrace-design.rst.

Signed-off-by: Sergey Matyukevich <sergey.matyukevich@synopsys.com>
Signed-off-by: Vineet Gupta <vgupta@kernel.org>
arch/arc/Kconfig
arch/arc/include/asm/syscall.h
arch/arc/include/asm/thread_info.h
arch/arc/kernel/entry.S
arch/arc/kernel/ptrace.c

index 3c850d0..9e36532 100644 (file)
@@ -39,6 +39,7 @@ config ARC
        select HAVE_REGS_AND_STACK_ACCESS_API
        select HAVE_MOD_ARCH_SPECIFIC
        select HAVE_PERF_EVENTS
+       select HAVE_SYSCALL_TRACEPOINTS
        select IRQ_DOMAIN
        select MODULES_USE_ELF_RELA
        select OF
index 94529e8..9709256 100644 (file)
@@ -12,6 +12,8 @@
 #include <asm/unistd.h>
 #include <asm/ptrace.h>                /* in_syscall() */
 
+extern void *sys_call_table[];
+
 static inline long
 syscall_get_nr(struct task_struct *task, struct pt_regs *regs)
 {
index 1e0b2e3..6ba7fe4 100644 (file)
@@ -78,9 +78,9 @@ static inline __attribute_const__ struct thread_info *current_thread_info(void)
 #define TIF_SYSCALL_AUDIT      4       /* syscall auditing active */
 #define TIF_NOTIFY_SIGNAL      5       /* signal notifications exist */
 #define TIF_SYSCALL_TRACE      15      /* syscall trace active */
-
 /* true if poll_idle() is polling TIF_NEED_RESCHED */
 #define TIF_MEMDIE             16
+#define TIF_SYSCALL_TRACEPOINT 17      /* syscall tracepoint instrumentation */
 
 #define _TIF_SYSCALL_TRACE     (1<<TIF_SYSCALL_TRACE)
 #define _TIF_NOTIFY_RESUME     (1<<TIF_NOTIFY_RESUME)
@@ -89,11 +89,14 @@ static inline __attribute_const__ struct thread_info *current_thread_info(void)
 #define _TIF_SYSCALL_AUDIT     (1<<TIF_SYSCALL_AUDIT)
 #define _TIF_NOTIFY_SIGNAL     (1<<TIF_NOTIFY_SIGNAL)
 #define _TIF_MEMDIE            (1<<TIF_MEMDIE)
+#define _TIF_SYSCALL_TRACEPOINT        (1<<TIF_SYSCALL_TRACEPOINT)
 
 /* work to do on interrupt/exception return */
 #define _TIF_WORK_MASK         (_TIF_NEED_RESCHED | _TIF_SIGPENDING | \
                                 _TIF_NOTIFY_RESUME | _TIF_NOTIFY_SIGNAL)
 
+#define _TIF_SYSCALL_WORK      (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_TRACEPOINT)
+
 /*
  * _TIF_ALLWORK_MASK includes SYSCALL_TRACE, but we don't need it.
  * SYSCALL_TRACE is anyway separately/unconditionally tested right after a
index 66ba549..54e91df 100644 (file)
@@ -29,8 +29,8 @@ ENTRY(sys_clone_wrapper)
        DISCARD_CALLEE_SAVED_USER
 
        GET_CURR_THR_INFO_FLAGS   r10
-       btst r10, TIF_SYSCALL_TRACE
-       bnz  tracesys_exit
+       and.f 0, r10, _TIF_SYSCALL_WORK
+       bnz   tracesys_exit
 
        b .Lret_from_system_call
 END(sys_clone_wrapper)
@@ -41,8 +41,8 @@ ENTRY(sys_clone3_wrapper)
        DISCARD_CALLEE_SAVED_USER
 
        GET_CURR_THR_INFO_FLAGS   r10
-       btst r10, TIF_SYSCALL_TRACE
-       bnz  tracesys_exit
+       and.f 0, r10, _TIF_SYSCALL_WORK
+       bnz   tracesys_exit
 
        b .Lret_from_system_call
 END(sys_clone3_wrapper)
@@ -247,8 +247,8 @@ ENTRY(EV_Trap)
 
        ; If syscall tracing ongoing, invoke pre-post-hooks
        GET_CURR_THR_INFO_FLAGS   r10
-       btst r10, TIF_SYSCALL_TRACE
-       bnz tracesys  ; this never comes back
+       and.f 0, r10, _TIF_SYSCALL_WORK
+       bnz   tracesys  ; this never comes back
 
        ;============ Normal syscall case
 
index 5fa5bce..da7542c 100644 (file)
@@ -9,6 +9,9 @@
 #include <linux/unistd.h>
 #include <linux/elf.h>
 
+#define CREATE_TRACE_POINTS
+#include <trace/events/syscalls.h>
+
 struct pt_regs_offset {
        const char *name;
        int offset;
@@ -340,15 +343,27 @@ long arch_ptrace(struct task_struct *child, long request,
 
 asmlinkage int syscall_trace_entry(struct pt_regs *regs)
 {
-       if (ptrace_report_syscall_entry(regs))
-               return ULONG_MAX;
+       if (test_thread_flag(TIF_SYSCALL_TRACE))
+               if (ptrace_report_syscall_entry(regs))
+                       return ULONG_MAX;
+
+#ifdef CONFIG_HAVE_SYSCALL_TRACEPOINTS
+       if (test_thread_flag(TIF_SYSCALL_TRACEPOINT))
+               trace_sys_enter(regs, syscall_get_nr(current, regs));
+#endif
 
        return regs->r8;
 }
 
 asmlinkage void syscall_trace_exit(struct pt_regs *regs)
 {
-       ptrace_report_syscall_exit(regs, 0);
+       if (test_thread_flag(TIF_SYSCALL_TRACE))
+               ptrace_report_syscall_exit(regs, 0);
+
+#ifdef CONFIG_HAVE_SYSCALL_TRACEPOINTS
+       if (test_thread_flag(TIF_SYSCALL_TRACEPOINT))
+               trace_sys_exit(regs, regs_return_value(regs));
+#endif
 }
 
 int regs_query_register_offset(const char *name)