[S390] ftrace: add system call tracer support

System call tracer support for s390.

Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>

authored by Heiko Carstens and committed by Martin Schwidefsky 9bf1226b 88dbd203

+73 -2
+1
arch/s390/Kconfig
··· 84 select HAVE_FUNCTION_TRACER 85 select HAVE_FUNCTION_TRACE_MCOUNT_TEST 86 select HAVE_FTRACE_MCOUNT_RECORD 87 select HAVE_DYNAMIC_FTRACE 88 select HAVE_FUNCTION_GRAPH_TRACER 89 select HAVE_DEFAULT_NO_SPIN_MUTEXES
··· 84 select HAVE_FUNCTION_TRACER 85 select HAVE_FUNCTION_TRACE_MCOUNT_TEST 86 select HAVE_FTRACE_MCOUNT_RECORD 87 + select HAVE_FTRACE_SYSCALLS 88 select HAVE_DYNAMIC_FTRACE 89 select HAVE_FUNCTION_GRAPH_TRACER 90 select HAVE_DEFAULT_NO_SPIN_MUTEXES
+1
arch/s390/include/asm/syscall.h
··· 12 #ifndef _ASM_SYSCALL_H 13 #define _ASM_SYSCALL_H 1 14 15 #include <asm/ptrace.h> 16 17 static inline long syscall_get_nr(struct task_struct *task,
··· 12 #ifndef _ASM_SYSCALL_H 13 #define _ASM_SYSCALL_H 1 14 15 + #include <linux/sched.h> 16 #include <asm/ptrace.h> 17 18 static inline long syscall_get_nr(struct task_struct *task,
+2
arch/s390/include/asm/thread_info.h
··· 92 #define TIF_SYSCALL_TRACE 8 /* syscall trace active */ 93 #define TIF_SYSCALL_AUDIT 9 /* syscall auditing active */ 94 #define TIF_SECCOMP 10 /* secure computing */ 95 #define TIF_USEDFPU 16 /* FPU was used by this task this quantum (SMP) */ 96 #define TIF_POLLING_NRFLAG 17 /* true if poll_idle() is polling 97 TIF_NEED_RESCHED */ ··· 111 #define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE) 112 #define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT) 113 #define _TIF_SECCOMP (1<<TIF_SECCOMP) 114 #define _TIF_USEDFPU (1<<TIF_USEDFPU) 115 #define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG) 116 #define _TIF_31BIT (1<<TIF_31BIT)
··· 92 #define TIF_SYSCALL_TRACE 8 /* syscall trace active */ 93 #define TIF_SYSCALL_AUDIT 9 /* syscall auditing active */ 94 #define TIF_SECCOMP 10 /* secure computing */ 95 + #define TIF_SYSCALL_FTRACE 11 /* ftrace syscall instrumentation */ 96 #define TIF_USEDFPU 16 /* FPU was used by this task this quantum (SMP) */ 97 #define TIF_POLLING_NRFLAG 17 /* true if poll_idle() is polling 98 TIF_NEED_RESCHED */ ··· 110 #define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE) 111 #define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT) 112 #define _TIF_SECCOMP (1<<TIF_SECCOMP) 113 + #define _TIF_SYSCALL_FTRACE (1<<TIF_SYSCALL_FTRACE) 114 #define _TIF_USEDFPU (1<<TIF_USEDFPU) 115 #define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG) 116 #define _TIF_31BIT (1<<TIF_31BIT)
+3 -1
arch/s390/kernel/entry.S
··· 53 _TIF_MCCK_PENDING | _TIF_RESTART_SVC | _TIF_SINGLE_STEP ) 54 _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \ 55 _TIF_MCCK_PENDING) 56 - _TIF_SYSCALL = (_TIF_SYSCALL_TRACE>>8 | _TIF_SYSCALL_AUDIT>>8 | _TIF_SECCOMP>>8) 57 58 STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER 59 STACK_SIZE = 1 << STACK_SHIFT ··· 1109 1110 .section .rodata, "a" 1111 #define SYSCALL(esa,esame,emu) .long esa 1112 sys_call_table: 1113 #include "syscalls.S" 1114 #undef SYSCALL
··· 53 _TIF_MCCK_PENDING | _TIF_RESTART_SVC | _TIF_SINGLE_STEP ) 54 _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \ 55 _TIF_MCCK_PENDING) 56 + _TIF_SYSCALL = (_TIF_SYSCALL_TRACE>>8 | _TIF_SYSCALL_AUDIT>>8 | \ 57 + _TIF_SECCOMP>>8 | _TIF_SYSCALL_FTRACE>>8) 58 59 STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER 60 STACK_SIZE = 1 << STACK_SHIFT ··· 1108 1109 .section .rodata, "a" 1110 #define SYSCALL(esa,esame,emu) .long esa 1111 + .globl sys_call_table 1112 sys_call_table: 1113 #include "syscalls.S" 1114 #undef SYSCALL
+3 -1
arch/s390/kernel/entry64.S
··· 56 _TIF_MCCK_PENDING | _TIF_RESTART_SVC | _TIF_SINGLE_STEP ) 57 _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \ 58 _TIF_MCCK_PENDING) 59 - _TIF_SYSCALL = (_TIF_SYSCALL_TRACE>>8 | _TIF_SYSCALL_AUDIT>>8 | _TIF_SECCOMP>>8) 60 61 #define BASED(name) name-system_call(%r13) 62 ··· 1060 1061 .section .rodata, "a" 1062 #define SYSCALL(esa,esame,emu) .long esame 1063 sys_call_table: 1064 #include "syscalls.S" 1065 #undef SYSCALL
··· 56 _TIF_MCCK_PENDING | _TIF_RESTART_SVC | _TIF_SINGLE_STEP ) 57 _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \ 58 _TIF_MCCK_PENDING) 59 + _TIF_SYSCALL = (_TIF_SYSCALL_TRACE>>8 | _TIF_SYSCALL_AUDIT>>8 | \ 60 + _TIF_SECCOMP>>8 | _TIF_SYSCALL_FTRACE>>8) 61 62 #define BASED(name) name-system_call(%r13) 63 ··· 1059 1060 .section .rodata, "a" 1061 #define SYSCALL(esa,esame,emu) .long esame 1062 + .globl sys_call_table 1063 sys_call_table: 1064 #include "syscalls.S" 1065 #undef SYSCALL
+56
arch/s390/kernel/ftrace.c
··· 12 #include <linux/ftrace.h> 13 #include <linux/kernel.h> 14 #include <linux/types.h> 15 #include <asm/lowcore.h> 16 17 #ifdef CONFIG_DYNAMIC_FTRACE ··· 203 return parent; 204 } 205 #endif /* CONFIG_FUNCTION_GRAPH_TRACER */
··· 12 #include <linux/ftrace.h> 13 #include <linux/kernel.h> 14 #include <linux/types.h> 15 + #include <trace/syscall.h> 16 #include <asm/lowcore.h> 17 18 #ifdef CONFIG_DYNAMIC_FTRACE ··· 202 return parent; 203 } 204 #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ 205 + 206 + #ifdef CONFIG_FTRACE_SYSCALLS 207 + 208 + extern unsigned long __start_syscalls_metadata[]; 209 + extern unsigned long __stop_syscalls_metadata[]; 210 + extern unsigned int sys_call_table[]; 211 + 212 + static struct syscall_metadata **syscalls_metadata; 213 + 214 + struct syscall_metadata *syscall_nr_to_meta(int nr) 215 + { 216 + if (!syscalls_metadata || nr >= NR_syscalls || nr < 0) 217 + return NULL; 218 + 219 + return syscalls_metadata[nr]; 220 + } 221 + 222 + static struct syscall_metadata *find_syscall_meta(unsigned long syscall) 223 + { 224 + struct syscall_metadata *start; 225 + struct syscall_metadata *stop; 226 + char str[KSYM_SYMBOL_LEN]; 227 + 228 + start = (struct syscall_metadata *)__start_syscalls_metadata; 229 + stop = (struct syscall_metadata *)__stop_syscalls_metadata; 230 + kallsyms_lookup(syscall, NULL, NULL, NULL, str); 231 + 232 + for ( ; start < stop; start++) { 233 + if (start->name && !strcmp(start->name + 3, str + 3)) 234 + return start; 235 + } 236 + return NULL; 237 + } 238 + 239 + void arch_init_ftrace_syscalls(void) 240 + { 241 + struct syscall_metadata *meta; 242 + int i; 243 + static atomic_t refs; 244 + 245 + if (atomic_inc_return(&refs) != 1) 246 + goto out; 247 + syscalls_metadata = kzalloc(sizeof(*syscalls_metadata) * NR_syscalls, 248 + GFP_KERNEL); 249 + if (!syscalls_metadata) 250 + goto out; 251 + for (i = 0; i < NR_syscalls; i++) { 252 + meta = find_syscall_meta((unsigned long)sys_call_table[i]); 253 + syscalls_metadata[i] = meta; 254 + } 255 + return; 256 + out: 257 + atomic_dec(&refs); 258 + } 259 + #endif
+7
arch/s390/kernel/ptrace.c
··· 37 #include <linux/regset.h> 38 #include <linux/tracehook.h> 39 #include <linux/seccomp.h> 40 #include <asm/compat.h> 41 #include <asm/segment.h> 42 #include <asm/page.h> ··· 662 ret = -1; 663 } 664 665 if (unlikely(current->audit_context)) 666 audit_syscall_entry(is_compat_task() ? 667 AUDIT_ARCH_S390 : AUDIT_ARCH_S390X, ··· 679 if (unlikely(current->audit_context)) 680 audit_syscall_exit(AUDITSC_RESULT(regs->gprs[2]), 681 regs->gprs[2]); 682 683 if (test_thread_flag(TIF_SYSCALL_TRACE)) 684 tracehook_report_syscall_exit(regs, 0);
··· 37 #include <linux/regset.h> 38 #include <linux/tracehook.h> 39 #include <linux/seccomp.h> 40 + #include <trace/syscall.h> 41 #include <asm/compat.h> 42 #include <asm/segment.h> 43 #include <asm/page.h> ··· 661 ret = -1; 662 } 663 664 + if (unlikely(test_thread_flag(TIF_SYSCALL_FTRACE))) 665 + ftrace_syscall_enter(regs); 666 + 667 if (unlikely(current->audit_context)) 668 audit_syscall_entry(is_compat_task() ? 669 AUDIT_ARCH_S390 : AUDIT_ARCH_S390X, ··· 675 if (unlikely(current->audit_context)) 676 audit_syscall_exit(AUDITSC_RESULT(regs->gprs[2]), 677 regs->gprs[2]); 678 + 679 + if (unlikely(test_thread_flag(TIF_SYSCALL_FTRACE))) 680 + ftrace_syscall_exit(regs); 681 682 if (test_thread_flag(TIF_SYSCALL_TRACE)) 683 tracehook_report_syscall_exit(regs, 0);