diff options
Diffstat (limited to 'kernel/trace/trace_syscalls.c')
-rw-r--r-- | kernel/trace/trace_syscalls.c | 43 |
1 files changed, 38 insertions, 5 deletions
diff --git a/kernel/trace/trace_syscalls.c b/kernel/trace/trace_syscalls.c index 5329e13e74a1..7a809e321058 100644 --- a/kernel/trace/trace_syscalls.c +++ b/kernel/trace/trace_syscalls.c | |||
@@ -1,5 +1,6 @@ | |||
1 | #include <trace/syscall.h> | 1 | #include <trace/syscall.h> |
2 | #include <trace/events/syscalls.h> | 2 | #include <trace/events/syscalls.h> |
3 | #include <linux/syscalls.h> | ||
3 | #include <linux/slab.h> | 4 | #include <linux/slab.h> |
4 | #include <linux/kernel.h> | 5 | #include <linux/kernel.h> |
5 | #include <linux/module.h> /* for MODULE_NAME_LEN via KSYM_SYMBOL_LEN */ | 6 | #include <linux/module.h> /* for MODULE_NAME_LEN via KSYM_SYMBOL_LEN */ |
@@ -47,6 +48,38 @@ static inline bool arch_syscall_match_sym_name(const char *sym, const char *name | |||
47 | } | 48 | } |
48 | #endif | 49 | #endif |
49 | 50 | ||
51 | #ifdef ARCH_TRACE_IGNORE_COMPAT_SYSCALLS | ||
52 | /* | ||
53 | * Some architectures that allow for 32bit applications | ||
54 | * to run on a 64bit kernel, do not map the syscalls for | ||
55 | * the 32bit tasks the same as they do for 64bit tasks. | ||
56 | * | ||
57 | * *cough*x86*cough* | ||
58 | * | ||
59 | * In such a case, instead of reporting the wrong syscalls, | ||
60 | * simply ignore them. | ||
61 | * | ||
62 | * For an arch to ignore the compat syscalls it needs to | ||
63 | * define ARCH_TRACE_IGNORE_COMPAT_SYSCALLS as well as | ||
64 | * define the function arch_trace_is_compat_syscall() to let | ||
65 | * the tracing system know that it should ignore it. | ||
66 | */ | ||
67 | static int | ||
68 | trace_get_syscall_nr(struct task_struct *task, struct pt_regs *regs) | ||
69 | { | ||
70 | if (unlikely(arch_trace_is_compat_syscall(regs))) | ||
71 | return -1; | ||
72 | |||
73 | return syscall_get_nr(task, regs); | ||
74 | } | ||
75 | #else | ||
76 | static inline int | ||
77 | trace_get_syscall_nr(struct task_struct *task, struct pt_regs *regs) | ||
78 | { | ||
79 | return syscall_get_nr(task, regs); | ||
80 | } | ||
81 | #endif /* ARCH_TRACE_IGNORE_COMPAT_SYSCALLS */ | ||
82 | |||
50 | static __init struct syscall_metadata * | 83 | static __init struct syscall_metadata * |
51 | find_syscall_meta(unsigned long syscall) | 84 | find_syscall_meta(unsigned long syscall) |
52 | { | 85 | { |
@@ -276,10 +309,10 @@ static void ftrace_syscall_enter(void *ignore, struct pt_regs *regs, long id) | |||
276 | struct syscall_metadata *sys_data; | 309 | struct syscall_metadata *sys_data; |
277 | struct ring_buffer_event *event; | 310 | struct ring_buffer_event *event; |
278 | struct ring_buffer *buffer; | 311 | struct ring_buffer *buffer; |
279 | int size; | ||
280 | int syscall_nr; | 312 | int syscall_nr; |
313 | int size; | ||
281 | 314 | ||
282 | syscall_nr = syscall_get_nr(current, regs); | 315 | syscall_nr = trace_get_syscall_nr(current, regs); |
283 | if (syscall_nr < 0) | 316 | if (syscall_nr < 0) |
284 | return; | 317 | return; |
285 | if (!test_bit(syscall_nr, enabled_enter_syscalls)) | 318 | if (!test_bit(syscall_nr, enabled_enter_syscalls)) |
@@ -313,7 +346,7 @@ static void ftrace_syscall_exit(void *ignore, struct pt_regs *regs, long ret) | |||
313 | struct ring_buffer *buffer; | 346 | struct ring_buffer *buffer; |
314 | int syscall_nr; | 347 | int syscall_nr; |
315 | 348 | ||
316 | syscall_nr = syscall_get_nr(current, regs); | 349 | syscall_nr = trace_get_syscall_nr(current, regs); |
317 | if (syscall_nr < 0) | 350 | if (syscall_nr < 0) |
318 | return; | 351 | return; |
319 | if (!test_bit(syscall_nr, enabled_exit_syscalls)) | 352 | if (!test_bit(syscall_nr, enabled_exit_syscalls)) |
@@ -502,7 +535,7 @@ static void perf_syscall_enter(void *ignore, struct pt_regs *regs, long id) | |||
502 | int rctx; | 535 | int rctx; |
503 | int size; | 536 | int size; |
504 | 537 | ||
505 | syscall_nr = syscall_get_nr(current, regs); | 538 | syscall_nr = trace_get_syscall_nr(current, regs); |
506 | if (syscall_nr < 0) | 539 | if (syscall_nr < 0) |
507 | return; | 540 | return; |
508 | if (!test_bit(syscall_nr, enabled_perf_enter_syscalls)) | 541 | if (!test_bit(syscall_nr, enabled_perf_enter_syscalls)) |
@@ -578,7 +611,7 @@ static void perf_syscall_exit(void *ignore, struct pt_regs *regs, long ret) | |||
578 | int rctx; | 611 | int rctx; |
579 | int size; | 612 | int size; |
580 | 613 | ||
581 | syscall_nr = syscall_get_nr(current, regs); | 614 | syscall_nr = trace_get_syscall_nr(current, regs); |
582 | if (syscall_nr < 0) | 615 | if (syscall_nr < 0) |
583 | return; | 616 | return; |
584 | if (!test_bit(syscall_nr, enabled_perf_exit_syscalls)) | 617 | if (!test_bit(syscall_nr, enabled_perf_exit_syscalls)) |