Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Sergey Matyukevich and committed by
Vineet Gupta
fb0b5490 b3bbf6a7

+31 -10
+1
arch/arc/Kconfig
··· 39 39 select HAVE_REGS_AND_STACK_ACCESS_API 40 40 select HAVE_MOD_ARCH_SPECIFIC 41 41 select HAVE_PERF_EVENTS 42 + select HAVE_SYSCALL_TRACEPOINTS 42 43 select IRQ_DOMAIN 43 44 select MODULES_USE_ELF_RELA 44 45 select OF
+2
arch/arc/include/asm/syscall.h
··· 12 12 #include <asm/unistd.h> 13 13 #include <asm/ptrace.h> /* in_syscall() */ 14 14 15 + extern void *sys_call_table[]; 16 + 15 17 static inline long 16 18 syscall_get_nr(struct task_struct *task, struct pt_regs *regs) 17 19 {
+4 -1
arch/arc/include/asm/thread_info.h
··· 78 78 #define TIF_SYSCALL_AUDIT 4 /* syscall auditing active */ 79 79 #define TIF_NOTIFY_SIGNAL 5 /* signal notifications exist */ 80 80 #define TIF_SYSCALL_TRACE 15 /* syscall trace active */ 81 - 82 81 /* true if poll_idle() is polling TIF_NEED_RESCHED */ 83 82 #define TIF_MEMDIE 16 83 + #define TIF_SYSCALL_TRACEPOINT 17 /* syscall tracepoint instrumentation */ 84 84 85 85 #define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE) 86 86 #define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME) ··· 89 89 #define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT) 90 90 #define _TIF_NOTIFY_SIGNAL (1<<TIF_NOTIFY_SIGNAL) 91 91 #define _TIF_MEMDIE (1<<TIF_MEMDIE) 92 + #define _TIF_SYSCALL_TRACEPOINT (1<<TIF_SYSCALL_TRACEPOINT) 92 93 93 94 /* work to do on interrupt/exception return */ 94 95 #define _TIF_WORK_MASK (_TIF_NEED_RESCHED | _TIF_SIGPENDING | \ 95 96 _TIF_NOTIFY_RESUME | _TIF_NOTIFY_SIGNAL) 97 + 98 + #define _TIF_SYSCALL_WORK (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_TRACEPOINT) 96 99 97 100 /* 98 101 * _TIF_ALLWORK_MASK includes SYSCALL_TRACE, but we don't need it.
+6 -6
arch/arc/kernel/entry.S
··· 29 29 DISCARD_CALLEE_SAVED_USER 30 30 31 31 GET_CURR_THR_INFO_FLAGS r10 32 - btst r10, TIF_SYSCALL_TRACE 33 - bnz tracesys_exit 32 + and.f 0, r10, _TIF_SYSCALL_WORK 33 + bnz tracesys_exit 34 34 35 35 b .Lret_from_system_call 36 36 END(sys_clone_wrapper) ··· 41 41 DISCARD_CALLEE_SAVED_USER 42 42 43 43 GET_CURR_THR_INFO_FLAGS r10 44 - btst r10, TIF_SYSCALL_TRACE 45 - bnz tracesys_exit 44 + and.f 0, r10, _TIF_SYSCALL_WORK 45 + bnz tracesys_exit 46 46 47 47 b .Lret_from_system_call 48 48 END(sys_clone3_wrapper) ··· 247 247 248 248 ; If syscall tracing ongoing, invoke pre-post-hooks 249 249 GET_CURR_THR_INFO_FLAGS r10 250 - btst r10, TIF_SYSCALL_TRACE 251 - bnz tracesys ; this never comes back 250 + and.f 0, r10, _TIF_SYSCALL_WORK 251 + bnz tracesys ; this never comes back 252 252 253 253 ;============ Normal syscall case 254 254
+18 -3
arch/arc/kernel/ptrace.c
··· 9 9 #include <linux/unistd.h> 10 10 #include <linux/elf.h> 11 11 12 + #define CREATE_TRACE_POINTS 13 + #include <trace/events/syscalls.h> 14 + 12 15 struct pt_regs_offset { 13 16 const char *name; 14 17 int offset; ··· 343 340 344 341 asmlinkage int syscall_trace_entry(struct pt_regs *regs) 345 342 { 346 - if (ptrace_report_syscall_entry(regs)) 347 - return ULONG_MAX; 343 + if (test_thread_flag(TIF_SYSCALL_TRACE)) 344 + if (ptrace_report_syscall_entry(regs)) 345 + return ULONG_MAX; 346 + 347 + #ifdef CONFIG_HAVE_SYSCALL_TRACEPOINTS 348 + if (test_thread_flag(TIF_SYSCALL_TRACEPOINT)) 349 + trace_sys_enter(regs, syscall_get_nr(current, regs)); 350 + #endif 348 351 349 352 return regs->r8; 350 353 } 351 354 352 355 asmlinkage void syscall_trace_exit(struct pt_regs *regs) 353 356 { 354 - ptrace_report_syscall_exit(regs, 0); 357 + if (test_thread_flag(TIF_SYSCALL_TRACE)) 358 + ptrace_report_syscall_exit(regs, 0); 359 + 360 + #ifdef CONFIG_HAVE_SYSCALL_TRACEPOINTS 361 + if (test_thread_flag(TIF_SYSCALL_TRACEPOINT)) 362 + trace_sys_exit(regs, regs_return_value(regs)); 363 + #endif 355 364 } 356 365 357 366 int regs_query_register_offset(const char *name)