diff options
Diffstat (limited to 'arch/sh/kernel')
-rw-r--r-- | arch/sh/kernel/Makefile_32 | 1 | ||||
-rw-r--r-- | arch/sh/kernel/entry-common.S | 18 | ||||
-rw-r--r-- | arch/sh/kernel/ftrace.c | 68 | ||||
-rw-r--r-- | arch/sh/kernel/ptrace_32.c | 8 |
4 files changed, 90 insertions, 5 deletions
diff --git a/arch/sh/kernel/Makefile_32 b/arch/sh/kernel/Makefile_32 index 9411e3e31e68..fee924a9c46c 100644 --- a/arch/sh/kernel/Makefile_32 +++ b/arch/sh/kernel/Makefile_32 | |||
@@ -29,6 +29,7 @@ obj-$(CONFIG_IO_TRAPPED) += io_trapped.o | |||
29 | obj-$(CONFIG_KPROBES) += kprobes.o | 29 | obj-$(CONFIG_KPROBES) += kprobes.o |
30 | obj-$(CONFIG_GENERIC_GPIO) += gpio.o | 30 | obj-$(CONFIG_GENERIC_GPIO) += gpio.o |
31 | obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o | 31 | obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o |
32 | obj-$(CONFIG_FTRACE_SYSCALLS) += ftrace.o | ||
32 | obj-$(CONFIG_DUMP_CODE) += disassemble.o | 33 | obj-$(CONFIG_DUMP_CODE) += disassemble.o |
33 | obj-$(CONFIG_HIBERNATION) += swsusp.o | 34 | obj-$(CONFIG_HIBERNATION) += swsusp.o |
34 | 35 | ||
diff --git a/arch/sh/kernel/entry-common.S b/arch/sh/kernel/entry-common.S index d62359cfbbe2..d62175650c54 100644 --- a/arch/sh/kernel/entry-common.S +++ b/arch/sh/kernel/entry-common.S | |||
@@ -131,7 +131,7 @@ ENTRY(resume_userspace) | |||
131 | nop | 131 | nop |
132 | #endif | 132 | #endif |
133 | mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags | 133 | mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags |
134 | tst #_TIF_WORK_MASK, r0 | 134 | tst #(_TIF_WORK_MASK & 0xff), r0 |
135 | bt/s __restore_all | 135 | bt/s __restore_all |
136 | tst #_TIF_NEED_RESCHED, r0 | 136 | tst #_TIF_NEED_RESCHED, r0 |
137 | 137 | ||
@@ -163,7 +163,7 @@ work_resched: | |||
163 | #endif | 163 | #endif |
164 | ! | 164 | ! |
165 | mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags | 165 | mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags |
166 | tst #_TIF_WORK_MASK, r0 | 166 | tst #(_TIF_WORK_MASK & 0xff), r0 |
167 | bt __restore_all | 167 | bt __restore_all |
168 | bra work_pending | 168 | bra work_pending |
169 | tst #_TIF_NEED_RESCHED, r0 | 169 | tst #_TIF_NEED_RESCHED, r0 |
@@ -181,7 +181,7 @@ work_resched: | |||
181 | syscall_exit_work: | 181 | syscall_exit_work: |
182 | ! r0: current_thread_info->flags | 182 | ! r0: current_thread_info->flags |
183 | ! r8: current_thread_info | 183 | ! r8: current_thread_info |
184 | tst #_TIF_WORK_SYSCALL_MASK, r0 | 184 | tst #(_TIF_WORK_SYSCALL_MASK & 0xff), r0 |
185 | bt/s work_pending | 185 | bt/s work_pending |
186 | tst #_TIF_NEED_RESCHED, r0 | 186 | tst #_TIF_NEED_RESCHED, r0 |
187 | #ifdef CONFIG_TRACE_IRQFLAGS | 187 | #ifdef CONFIG_TRACE_IRQFLAGS |
@@ -331,8 +331,12 @@ ENTRY(system_call) | |||
331 | ! | 331 | ! |
332 | get_current_thread_info r8, r10 | 332 | get_current_thread_info r8, r10 |
333 | mov.l @(TI_FLAGS,r8), r8 | 333 | mov.l @(TI_FLAGS,r8), r8 |
334 | mov #_TIF_WORK_SYSCALL_MASK, r10 | 334 | mov #(_TIF_WORK_SYSCALL_MASK & 0xff), r10 |
335 | mov #(_TIF_WORK_SYSCALL_MASK >> 8), r9 | ||
335 | tst r10, r8 | 336 | tst r10, r8 |
337 | shll8 r9 | ||
338 | bf syscall_trace_entry | ||
339 | tst r9, r8 | ||
336 | bf syscall_trace_entry | 340 | bf syscall_trace_entry |
337 | ! | 341 | ! |
338 | mov.l 2f, r8 ! Number of syscalls | 342 | mov.l 2f, r8 ! Number of syscalls |
@@ -359,7 +363,11 @@ syscall_exit: | |||
359 | ! | 363 | ! |
360 | get_current_thread_info r8, r0 | 364 | get_current_thread_info r8, r0 |
361 | mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags | 365 | mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags |
362 | tst #_TIF_ALLWORK_MASK, r0 | 366 | tst #(_TIF_ALLWORK_MASK & 0xff), r0 |
367 | mov #(_TIF_ALLWORK_MASK >> 8), r1 | ||
368 | bf syscall_exit_work | ||
369 | shlr8 r0 | ||
370 | tst r0, r1 | ||
363 | bf syscall_exit_work | 371 | bf syscall_exit_work |
364 | bra __restore_all | 372 | bra __restore_all |
365 | nop | 373 | nop |
diff --git a/arch/sh/kernel/ftrace.c b/arch/sh/kernel/ftrace.c index 066f37dc32a9..4f62eced0aec 100644 --- a/arch/sh/kernel/ftrace.c +++ b/arch/sh/kernel/ftrace.c | |||
@@ -18,6 +18,8 @@ | |||
18 | #include <linux/io.h> | 18 | #include <linux/io.h> |
19 | #include <asm/ftrace.h> | 19 | #include <asm/ftrace.h> |
20 | #include <asm/cacheflush.h> | 20 | #include <asm/cacheflush.h> |
21 | #include <asm/unistd.h> | ||
22 | #include <trace/syscall.h> | ||
21 | 23 | ||
22 | static unsigned char ftrace_replaced_code[MCOUNT_INSN_SIZE]; | 24 | static unsigned char ftrace_replaced_code[MCOUNT_INSN_SIZE]; |
23 | 25 | ||
@@ -131,3 +133,69 @@ int __init ftrace_dyn_arch_init(void *data) | |||
131 | 133 | ||
132 | return 0; | 134 | return 0; |
133 | } | 135 | } |
136 | |||
137 | #ifdef CONFIG_FTRACE_SYSCALLS | ||
138 | |||
139 | extern unsigned long __start_syscalls_metadata[]; | ||
140 | extern unsigned long __stop_syscalls_metadata[]; | ||
141 | extern unsigned long *sys_call_table; | ||
142 | |||
143 | static struct syscall_metadata **syscalls_metadata; | ||
144 | |||
145 | static struct syscall_metadata *find_syscall_meta(unsigned long *syscall) | ||
146 | { | ||
147 | struct syscall_metadata *start; | ||
148 | struct syscall_metadata *stop; | ||
149 | char str[KSYM_SYMBOL_LEN]; | ||
150 | |||
151 | |||
152 | start = (struct syscall_metadata *)__start_syscalls_metadata; | ||
153 | stop = (struct syscall_metadata *)__stop_syscalls_metadata; | ||
154 | kallsyms_lookup((unsigned long) syscall, NULL, NULL, NULL, str); | ||
155 | |||
156 | for ( ; start < stop; start++) { | ||
157 | if (start->name && !strcmp(start->name, str)) | ||
158 | return start; | ||
159 | } | ||
160 | |||
161 | return NULL; | ||
162 | } | ||
163 | |||
164 | #define FTRACE_SYSCALL_MAX (NR_syscalls - 1) | ||
165 | |||
166 | struct syscall_metadata *syscall_nr_to_meta(int nr) | ||
167 | { | ||
168 | if (!syscalls_metadata || nr >= FTRACE_SYSCALL_MAX || nr < 0) | ||
169 | return NULL; | ||
170 | |||
171 | return syscalls_metadata[nr]; | ||
172 | } | ||
173 | |||
174 | void arch_init_ftrace_syscalls(void) | ||
175 | { | ||
176 | int i; | ||
177 | struct syscall_metadata *meta; | ||
178 | unsigned long **psys_syscall_table = &sys_call_table; | ||
179 | static atomic_t refs; | ||
180 | |||
181 | if (atomic_inc_return(&refs) != 1) | ||
182 | goto end; | ||
183 | |||
184 | syscalls_metadata = kzalloc(sizeof(*syscalls_metadata) * | ||
185 | FTRACE_SYSCALL_MAX, GFP_KERNEL); | ||
186 | if (!syscalls_metadata) { | ||
187 | WARN_ON(1); | ||
188 | return; | ||
189 | } | ||
190 | |||
191 | for (i = 0; i < FTRACE_SYSCALL_MAX; i++) { | ||
192 | meta = find_syscall_meta(psys_syscall_table[i]); | ||
193 | syscalls_metadata[i] = meta; | ||
194 | } | ||
195 | return; | ||
196 | |||
197 | /* Paranoid: avoid overflow */ | ||
198 | end: | ||
199 | atomic_dec(&refs); | ||
200 | } | ||
201 | #endif /* CONFIG_FTRACE_SYSCALLS */ | ||
diff --git a/arch/sh/kernel/ptrace_32.c b/arch/sh/kernel/ptrace_32.c index 3392e835a374..c198eceaee94 100644 --- a/arch/sh/kernel/ptrace_32.c +++ b/arch/sh/kernel/ptrace_32.c | |||
@@ -34,6 +34,8 @@ | |||
34 | #include <asm/syscalls.h> | 34 | #include <asm/syscalls.h> |
35 | #include <asm/fpu.h> | 35 | #include <asm/fpu.h> |
36 | 36 | ||
37 | #include <trace/syscall.h> | ||
38 | |||
37 | /* | 39 | /* |
38 | * This routine will get a word off of the process kernel stack. | 40 | * This routine will get a word off of the process kernel stack. |
39 | */ | 41 | */ |
@@ -459,6 +461,9 @@ asmlinkage long do_syscall_trace_enter(struct pt_regs *regs) | |||
459 | */ | 461 | */ |
460 | ret = -1L; | 462 | ret = -1L; |
461 | 463 | ||
464 | if (unlikely(test_thread_flag(TIF_SYSCALL_FTRACE))) | ||
465 | ftrace_syscall_enter(regs); | ||
466 | |||
462 | if (unlikely(current->audit_context)) | 467 | if (unlikely(current->audit_context)) |
463 | audit_syscall_entry(audit_arch(), regs->regs[3], | 468 | audit_syscall_entry(audit_arch(), regs->regs[3], |
464 | regs->regs[4], regs->regs[5], | 469 | regs->regs[4], regs->regs[5], |
@@ -475,6 +480,9 @@ asmlinkage void do_syscall_trace_leave(struct pt_regs *regs) | |||
475 | audit_syscall_exit(AUDITSC_RESULT(regs->regs[0]), | 480 | audit_syscall_exit(AUDITSC_RESULT(regs->regs[0]), |
476 | regs->regs[0]); | 481 | regs->regs[0]); |
477 | 482 | ||
483 | if (unlikely(test_thread_flag(TIF_SYSCALL_FTRACE))) | ||
484 | ftrace_syscall_exit(regs); | ||
485 | |||
478 | step = test_thread_flag(TIF_SINGLESTEP); | 486 | step = test_thread_flag(TIF_SINGLESTEP); |
479 | if (step || test_thread_flag(TIF_SYSCALL_TRACE)) | 487 | if (step || test_thread_flag(TIF_SYSCALL_TRACE)) |
480 | tracehook_report_syscall_exit(regs, step); | 488 | tracehook_report_syscall_exit(regs, step); |