aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel
diff options
context:
space:
mode:
authorFrederic Weisbecker <fweisbec@gmail.com>2009-03-13 10:42:12 -0400
committerIngo Molnar <mingo@elte.hu>2009-03-13 11:57:42 -0400
commitf58ba100678f421bdcb000a3c71793f432dfab93 (patch)
tree0f4fee33c458bae9d354e5ec5a3240016a4f0c53 /arch/x86/kernel
parent1b3fa2ce64363c289b3b14723cca7290bf91cfce (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.c63
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
459extern unsigned long __start_syscalls_metadata[];
460extern unsigned long __stop_syscalls_metadata[];
461extern unsigned long *sys_call_table;
462
463static struct syscall_metadata **syscalls_metadata;
464
465static 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
483struct 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
491void 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 */
515end:
516 atomic_dec(&refs);
517}
518#endif