diff options
author | Heiko Carstens <heiko.carstens@de.ibm.com> | 2009-06-12 04:26:47 -0400 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2009-06-12 04:27:39 -0400 |
commit | 9bf1226b33dc2f94fc37ffd70ee161e2bda1ff5c (patch) | |
tree | 3bad5cab583d2940bf9755398a1da7bc77e1b759 /arch/s390/kernel/ftrace.c | |
parent | 88dbd2037229bd2ed7543ffd0d8f2d9dec9d31d2 (diff) |
[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>
Diffstat (limited to 'arch/s390/kernel/ftrace.c')
-rw-r--r-- | arch/s390/kernel/ftrace.c | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/arch/s390/kernel/ftrace.c b/arch/s390/kernel/ftrace.c index c92a10953279..82ddfd3a75af 100644 --- a/arch/s390/kernel/ftrace.c +++ b/arch/s390/kernel/ftrace.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/ftrace.h> | 12 | #include <linux/ftrace.h> |
13 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
14 | #include <linux/types.h> | 14 | #include <linux/types.h> |
15 | #include <trace/syscall.h> | ||
15 | #include <asm/lowcore.h> | 16 | #include <asm/lowcore.h> |
16 | 17 | ||
17 | #ifdef CONFIG_DYNAMIC_FTRACE | 18 | #ifdef CONFIG_DYNAMIC_FTRACE |
@@ -202,3 +203,58 @@ out: | |||
202 | return parent; | 203 | return parent; |
203 | } | 204 | } |
204 | #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ | 205 | #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ |
206 | |||
207 | #ifdef CONFIG_FTRACE_SYSCALLS | ||
208 | |||
209 | extern unsigned long __start_syscalls_metadata[]; | ||
210 | extern unsigned long __stop_syscalls_metadata[]; | ||
211 | extern unsigned int sys_call_table[]; | ||
212 | |||
213 | static struct syscall_metadata **syscalls_metadata; | ||
214 | |||
215 | struct syscall_metadata *syscall_nr_to_meta(int nr) | ||
216 | { | ||
217 | if (!syscalls_metadata || nr >= NR_syscalls || nr < 0) | ||
218 | return NULL; | ||
219 | |||
220 | return syscalls_metadata[nr]; | ||
221 | } | ||
222 | |||
223 | static struct syscall_metadata *find_syscall_meta(unsigned long syscall) | ||
224 | { | ||
225 | struct syscall_metadata *start; | ||
226 | struct syscall_metadata *stop; | ||
227 | char str[KSYM_SYMBOL_LEN]; | ||
228 | |||
229 | start = (struct syscall_metadata *)__start_syscalls_metadata; | ||
230 | stop = (struct syscall_metadata *)__stop_syscalls_metadata; | ||
231 | kallsyms_lookup(syscall, NULL, NULL, NULL, str); | ||
232 | |||
233 | for ( ; start < stop; start++) { | ||
234 | if (start->name && !strcmp(start->name + 3, str + 3)) | ||
235 | return start; | ||
236 | } | ||
237 | return NULL; | ||
238 | } | ||
239 | |||
240 | void arch_init_ftrace_syscalls(void) | ||
241 | { | ||
242 | struct syscall_metadata *meta; | ||
243 | int i; | ||
244 | static atomic_t refs; | ||
245 | |||
246 | if (atomic_inc_return(&refs) != 1) | ||
247 | goto out; | ||
248 | syscalls_metadata = kzalloc(sizeof(*syscalls_metadata) * NR_syscalls, | ||
249 | GFP_KERNEL); | ||
250 | if (!syscalls_metadata) | ||
251 | goto out; | ||
252 | for (i = 0; i < NR_syscalls; i++) { | ||
253 | meta = find_syscall_meta((unsigned long)sys_call_table[i]); | ||
254 | syscalls_metadata[i] = meta; | ||
255 | } | ||
256 | return; | ||
257 | out: | ||
258 | atomic_dec(&refs); | ||
259 | } | ||
260 | #endif | ||