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>
This commit is contained in:
Родитель
1b3fa2ce64
Коммит
f58ba10067
|
@ -28,6 +28,13 @@
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* FIXME: I don't want to stay hardcoded */
|
||||||
|
#ifdef CONFIG_X86_64
|
||||||
|
# define FTRACE_SYSCALL_MAX 296
|
||||||
|
#else
|
||||||
|
# define FTRACE_SYSCALL_MAX 333
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_FUNCTION_TRACER
|
#ifdef CONFIG_FUNCTION_TRACER
|
||||||
#define MCOUNT_ADDR ((long)(mcount))
|
#define MCOUNT_ADDR ((long)(mcount))
|
||||||
#define MCOUNT_INSN_SIZE 5 /* sizeof mcount call */
|
#define MCOUNT_INSN_SIZE 5 /* sizeof mcount call */
|
||||||
|
|
|
@ -453,3 +453,66 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
|
#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
|
||||||
|
|
||||||
|
#ifdef CONFIG_FTRACE_SYSCALLS
|
||||||
|
|
||||||
|
extern unsigned long __start_syscalls_metadata[];
|
||||||
|
extern unsigned long __stop_syscalls_metadata[];
|
||||||
|
extern unsigned long *sys_call_table;
|
||||||
|
|
||||||
|
static struct syscall_metadata **syscalls_metadata;
|
||||||
|
|
||||||
|
static struct syscall_metadata *find_syscall_meta(unsigned long *syscall)
|
||||||
|
{
|
||||||
|
struct syscall_metadata *start;
|
||||||
|
struct syscall_metadata *stop;
|
||||||
|
char str[KSYM_SYMBOL_LEN];
|
||||||
|
|
||||||
|
|
||||||
|
start = (struct syscall_metadata *)__start_syscalls_metadata;
|
||||||
|
stop = (struct syscall_metadata *)__stop_syscalls_metadata;
|
||||||
|
kallsyms_lookup((unsigned long) syscall, NULL, NULL, NULL, str);
|
||||||
|
|
||||||
|
for ( ; start < stop; start++) {
|
||||||
|
if (start->name && !strcmp(start->name, str))
|
||||||
|
return start;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct syscall_metadata *syscall_nr_to_meta(int nr)
|
||||||
|
{
|
||||||
|
if (!syscalls_metadata || nr >= FTRACE_SYSCALL_MAX || nr < 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return syscalls_metadata[nr];
|
||||||
|
}
|
||||||
|
|
||||||
|
void arch_init_ftrace_syscalls(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
struct syscall_metadata *meta;
|
||||||
|
unsigned long **psys_syscall_table = &sys_call_table;
|
||||||
|
static atomic_t refs;
|
||||||
|
|
||||||
|
if (atomic_inc_return(&refs) != 1)
|
||||||
|
goto end;
|
||||||
|
|
||||||
|
syscalls_metadata = kzalloc(sizeof(*syscalls_metadata) *
|
||||||
|
FTRACE_SYSCALL_MAX, GFP_KERNEL);
|
||||||
|
if (!syscalls_metadata) {
|
||||||
|
WARN_ON(1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < FTRACE_SYSCALL_MAX; i++) {
|
||||||
|
meta = find_syscall_meta(psys_syscall_table[i]);
|
||||||
|
syscalls_metadata[i] = meta;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Paranoid: avoid overflow */
|
||||||
|
end:
|
||||||
|
atomic_dec(&refs);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
Загрузка…
Ссылка в новой задаче