aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sh/kernel')
-rw-r--r--arch/sh/kernel/Makefile_321
-rw-r--r--arch/sh/kernel/entry-common.S18
-rw-r--r--arch/sh/kernel/ftrace.c68
-rw-r--r--arch/sh/kernel/ptrace_32.c8
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
29obj-$(CONFIG_KPROBES) += kprobes.o 29obj-$(CONFIG_KPROBES) += kprobes.o
30obj-$(CONFIG_GENERIC_GPIO) += gpio.o 30obj-$(CONFIG_GENERIC_GPIO) += gpio.o
31obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o 31obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o
32obj-$(CONFIG_FTRACE_SYSCALLS) += ftrace.o
32obj-$(CONFIG_DUMP_CODE) += disassemble.o 33obj-$(CONFIG_DUMP_CODE) += disassemble.o
33obj-$(CONFIG_HIBERNATION) += swsusp.o 34obj-$(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:
181syscall_exit_work: 181syscall_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
22static unsigned char ftrace_replaced_code[MCOUNT_INSN_SIZE]; 24static 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
139extern unsigned long __start_syscalls_metadata[];
140extern unsigned long __stop_syscalls_metadata[];
141extern unsigned long *sys_call_table;
142
143static struct syscall_metadata **syscalls_metadata;
144
145static 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
166struct 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
174void 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 */
198end:
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);