diff options
-rw-r--r-- | Documentation/trace/ftrace-design.txt | 4 | ||||
-rw-r--r-- | kernel/trace/trace_syscalls.c | 21 |
2 files changed, 18 insertions, 7 deletions
diff --git a/Documentation/trace/ftrace-design.txt b/Documentation/trace/ftrace-design.txt index 6fca17beee2f..79fcafc7fd64 100644 --- a/Documentation/trace/ftrace-design.txt +++ b/Documentation/trace/ftrace-design.txt | |||
@@ -250,6 +250,10 @@ You need very few things to get the syscalls tracing in an arch. | |||
250 | - If the system call table on this arch is more complicated than a simple array | 250 | - If the system call table on this arch is more complicated than a simple array |
251 | of addresses of the system calls, implement an arch_syscall_addr to return | 251 | of addresses of the system calls, implement an arch_syscall_addr to return |
252 | the address of a given system call. | 252 | the address of a given system call. |
253 | - If the symbol names of the system calls do not match the function names on | ||
254 | this arch, define ARCH_HAS_SYSCALL_MATCH_SYM_NAME in asm/ftrace.h and | ||
255 | implement arch_syscall_match_sym_name with the appropriate logic to return | ||
256 | true if the function name corresponds with the symbol name. | ||
253 | - Tag this arch as HAVE_SYSCALL_TRACEPOINTS. | 257 | - Tag this arch as HAVE_SYSCALL_TRACEPOINTS. |
254 | 258 | ||
255 | 259 | ||
diff --git a/kernel/trace/trace_syscalls.c b/kernel/trace/trace_syscalls.c index af831545f656..86a23e7de031 100644 --- a/kernel/trace/trace_syscalls.c +++ b/kernel/trace/trace_syscalls.c | |||
@@ -60,6 +60,19 @@ extern struct syscall_metadata *__stop_syscalls_metadata[]; | |||
60 | 60 | ||
61 | static struct syscall_metadata **syscalls_metadata; | 61 | static struct syscall_metadata **syscalls_metadata; |
62 | 62 | ||
63 | #ifndef ARCH_HAS_SYSCALL_MATCH_SYM_NAME | ||
64 | static inline bool arch_syscall_match_sym_name(const char *sym, const char *name) | ||
65 | { | ||
66 | /* | ||
67 | * Only compare after the "sys" prefix. Archs that use | ||
68 | * syscall wrappers may have syscalls symbols aliases prefixed | ||
69 | * with "SyS" instead of "sys", leading to an unwanted | ||
70 | * mismatch. | ||
71 | */ | ||
72 | return !strcmp(sym + 3, name + 3); | ||
73 | } | ||
74 | #endif | ||
75 | |||
63 | static __init struct syscall_metadata * | 76 | static __init struct syscall_metadata * |
64 | find_syscall_meta(unsigned long syscall) | 77 | find_syscall_meta(unsigned long syscall) |
65 | { | 78 | { |
@@ -73,13 +86,7 @@ find_syscall_meta(unsigned long syscall) | |||
73 | kallsyms_lookup(syscall, NULL, NULL, NULL, str); | 86 | kallsyms_lookup(syscall, NULL, NULL, NULL, str); |
74 | 87 | ||
75 | for ( ; start < stop; start++) { | 88 | for ( ; start < stop; start++) { |
76 | /* | 89 | if ((*start)->name && arch_syscall_match_sym_name(str, (*start)->name)) |
77 | * Only compare after the "sys" prefix. Archs that use | ||
78 | * syscall wrappers may have syscalls symbols aliases prefixed | ||
79 | * with "SyS" instead of "sys", leading to an unwanted | ||
80 | * mismatch. | ||
81 | */ | ||
82 | if ((*start)->name && !strcmp((*start)->name + 3, str + 3)) | ||
83 | return *start; | 90 | return *start; |
84 | } | 91 | } |
85 | return NULL; | 92 | return NULL; |