diff options
author | Sergey Matyukevich <sergey.matyukevich@synopsys.com> | 2022-04-14 11:17:23 +0300 |
---|---|---|
committer | Vineet Gupta <vgupta@kernel.org> | 2022-04-25 13:09:47 -0700 |
commit | fb0b54909b153ac6195378fa8ddee3f7531f8e51 (patch) | |
tree | 7d74e0f30de818900f5b8f9a4e160ac96e64b593 /arch/arc | |
parent | b3bbf6a70ba0f827938525e285cd2be6c76a6a00 (diff) | |
download | linux-fb0b54909b153ac6195378fa8ddee3f7531f8e51.tar.gz linux-fb0b54909b153ac6195378fa8ddee3f7531f8e51.tar.bz2 linux-fb0b54909b153ac6195378fa8ddee3f7531f8e51.zip |
ARC: implement syscall tracepoints
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>
Diffstat (limited to 'arch/arc')
-rw-r--r-- | arch/arc/Kconfig | 1 | ||||
-rw-r--r-- | arch/arc/include/asm/syscall.h | 2 | ||||
-rw-r--r-- | arch/arc/include/asm/thread_info.h | 5 | ||||
-rw-r--r-- | arch/arc/kernel/entry.S | 12 | ||||
-rw-r--r-- | arch/arc/kernel/ptrace.c | 21 |
5 files changed, 31 insertions, 10 deletions
diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig index 3c850d0f431c..9e3653253ef2 100644 --- a/arch/arc/Kconfig +++ b/arch/arc/Kconfig @@ -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 diff --git a/arch/arc/include/asm/syscall.h b/arch/arc/include/asm/syscall.h index 94529e89dff0..9709256e31c8 100644 --- a/arch/arc/include/asm/syscall.h +++ b/arch/arc/include/asm/syscall.h @@ -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) { diff --git a/arch/arc/include/asm/thread_info.h b/arch/arc/include/asm/thread_info.h index 1e0b2e3914d5..6ba7fe417095 100644 --- a/arch/arc/include/asm/thread_info.h +++ b/arch/arc/include/asm/thread_info.h @@ -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 diff --git a/arch/arc/kernel/entry.S b/arch/arc/kernel/entry.S index 66ba549b520f..54e91df678dd 100644 --- a/arch/arc/kernel/entry.S +++ b/arch/arc/kernel/entry.S @@ -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 diff --git a/arch/arc/kernel/ptrace.c b/arch/arc/kernel/ptrace.c index 5fa5bceb83f3..da7542cea0d8 100644 --- a/arch/arc/kernel/ptrace.c +++ b/arch/arc/kernel/ptrace.c @@ -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) |