diff options
author | Frederic Weisbecker <fweisbec@gmail.com> | 2009-03-13 10:42:12 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-03-13 11:57:42 -0400 |
commit | f58ba100678f421bdcb000a3c71793f432dfab93 (patch) | |
tree | 0f4fee33c458bae9d354e5ec5a3240016a4f0c53 /arch/x86/kernel | |
parent | 1b3fa2ce64363c289b3b14723cca7290bf91cfce (diff) |
tracing/syscalls: support for syscalls tracing on x86
Extend x86 architecture syscall tracing support with syscall
metadata table details.
(The upcoming core syscall tracing modifications rely on this.)
Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
LKML-Reference: <1236955332-10133-3-git-send-email-fweisbec@gmail.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/kernel')
-rw-r--r-- | arch/x86/kernel/ftrace.c | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/arch/x86/kernel/ftrace.c b/arch/x86/kernel/ftrace.c index a85da1764b1c..1d0d7f42efe3 100644 --- a/arch/x86/kernel/ftrace.c +++ b/arch/x86/kernel/ftrace.c | |||
@@ -453,3 +453,66 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr) | |||
453 | } | 453 | } |
454 | } | 454 | } |
455 | #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ | 455 | #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ |
456 | |||
457 | #ifdef CONFIG_FTRACE_SYSCALLS | ||
458 | |||
459 | extern unsigned long __start_syscalls_metadata[]; | ||
460 | extern unsigned long __stop_syscalls_metadata[]; | ||
461 | extern unsigned long *sys_call_table; | ||
462 | |||
463 | static struct syscall_metadata **syscalls_metadata; | ||
464 | |||
465 | static struct syscall_metadata *find_syscall_meta(unsigned long *syscall) | ||
466 | { | ||
467 | struct syscall_metadata *start; | ||
468 | struct syscall_metadata *stop; | ||
469 | char str[KSYM_SYMBOL_LEN]; | ||
470 | |||
471 | |||
472 | start = (struct syscall_metadata *)__start_syscalls_metadata; | ||
473 | stop = (struct syscall_metadata *)__stop_syscalls_metadata; | ||
474 | kallsyms_lookup((unsigned long) syscall, NULL, NULL, NULL, str); | ||
475 | |||
476 | for ( ; start < stop; start++) { | ||
477 | if (start->name && !strcmp(start->name, str)) | ||
478 | return start; | ||
479 | } | ||
480 | return NULL; | ||
481 | } | ||
482 | |||
483 | struct syscall_metadata *syscall_nr_to_meta(int nr) | ||
484 | { | ||
485 | if (!syscalls_metadata || nr >= FTRACE_SYSCALL_MAX || nr < 0) | ||
486 | return NULL; | ||
487 | |||
488 | return syscalls_metadata[nr]; | ||
489 | } | ||
490 | |||
491 | void arch_init_ftrace_syscalls(void) | ||
492 | { | ||
493 | int i; | ||
494 | struct syscall_metadata *meta; | ||
495 | unsigned long **psys_syscall_table = &sys_call_table; | ||
496 | static atomic_t refs; | ||
497 | |||
498 | if (atomic_inc_return(&refs) != 1) | ||
499 | goto end; | ||
500 | |||
501 | syscalls_metadata = kzalloc(sizeof(*syscalls_metadata) * | ||
502 | FTRACE_SYSCALL_MAX, GFP_KERNEL); | ||
503 | if (!syscalls_metadata) { | ||
504 | WARN_ON(1); | ||
505 | return; | ||
506 | } | ||
507 | |||
508 | for (i = 0; i < FTRACE_SYSCALL_MAX; i++) { | ||
509 | meta = find_syscall_meta(psys_syscall_table[i]); | ||
510 | syscalls_metadata[i] = meta; | ||
511 | } | ||
512 | return; | ||
513 | |||
514 | /* Paranoid: avoid overflow */ | ||
515 | end: | ||
516 | atomic_dec(&refs); | ||
517 | } | ||
518 | #endif | ||