aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--kernel/trace/trace_syscalls.c51
1 files changed, 28 insertions, 23 deletions
diff --git a/kernel/trace/trace_syscalls.c b/kernel/trace/trace_syscalls.c
index f130dacfeef4..d10daf0922b5 100644
--- a/kernel/trace/trace_syscalls.c
+++ b/kernel/trace/trace_syscalls.c
@@ -90,26 +90,39 @@ print_syscall_exit(struct trace_iterator *iter, int flags)
90 return TRACE_TYPE_HANDLED; 90 return TRACE_TYPE_HANDLED;
91} 91}
92 92
93extern char *__bad_type_size(void);
94
95#define SYSCALL_FIELD(type, name) \
96 sizeof(type) != sizeof(trace.name) ? \
97 __bad_type_size() : \
98 #type, #name, offsetof(typeof(trace), name), sizeof(trace.name)
99
93int ftrace_format_syscall(struct ftrace_event_call *call, struct trace_seq *s) 100int ftrace_format_syscall(struct ftrace_event_call *call, struct trace_seq *s)
94{ 101{
95 int i; 102 int i;
96 int nr; 103 int nr;
97 int ret = 0; 104 int ret;
98 struct syscall_metadata *entry; 105 struct syscall_metadata *entry;
99 int offset = sizeof(struct trace_entry); 106 struct syscall_trace_enter trace;
107 int offset = offsetof(struct syscall_trace_enter, args);
100 108
101 nr = syscall_name_to_nr((char *)call->data); 109 nr = syscall_name_to_nr(call->data);
102 entry = syscall_nr_to_meta(nr); 110 entry = syscall_nr_to_meta(nr);
103 111
104 if (!entry) 112 if (!entry)
105 return ret; 113 return 0;
114
115 ret = trace_seq_printf(s, "\tfield:%s %s;\toffset:%zu;\tsize:%zu;\n",
116 SYSCALL_FIELD(int, nr));
117 if (!ret)
118 return 0;
106 119
107 for (i = 0; i < entry->nb_args; i++) { 120 for (i = 0; i < entry->nb_args; i++) {
108 ret = trace_seq_printf(s, "\tfield:%s %s;", entry->types[i], 121 ret = trace_seq_printf(s, "\tfield:%s %s;", entry->types[i],
109 entry->args[i]); 122 entry->args[i]);
110 if (!ret) 123 if (!ret)
111 return 0; 124 return 0;
112 ret = trace_seq_printf(s, "\toffset:%d;\tsize:%lu;\n", offset, 125 ret = trace_seq_printf(s, "\toffset:%d;\tsize:%zu;\n", offset,
113 sizeof(unsigned long)); 126 sizeof(unsigned long));
114 if (!ret) 127 if (!ret)
115 return 0; 128 return 0;
@@ -118,7 +131,7 @@ int ftrace_format_syscall(struct ftrace_event_call *call, struct trace_seq *s)
118 131
119 trace_seq_printf(s, "\nprint fmt: \""); 132 trace_seq_printf(s, "\nprint fmt: \"");
120 for (i = 0; i < entry->nb_args; i++) { 133 for (i = 0; i < entry->nb_args; i++) {
121 ret = trace_seq_printf(s, "%s: 0x%%0%lulx%s", entry->args[i], 134 ret = trace_seq_printf(s, "%s: 0x%%0%zulx%s", entry->args[i],
122 sizeof(unsigned long), 135 sizeof(unsigned long),
123 i == entry->nb_args - 1 ? "\", " : ", "); 136 i == entry->nb_args - 1 ? "\", " : ", ");
124 if (!ret) 137 if (!ret)
@@ -287,16 +300,6 @@ struct trace_event event_syscall_exit = {
287 300
288#ifdef CONFIG_EVENT_PROFILE 301#ifdef CONFIG_EVENT_PROFILE
289 302
290struct syscall_enter_record {
291 struct trace_entry entry;
292 unsigned long args[0];
293};
294
295struct syscall_exit_record {
296 struct trace_entry entry;
297 unsigned long ret;
298};
299
300static DECLARE_BITMAP(enabled_prof_enter_syscalls, FTRACE_SYSCALL_MAX); 303static DECLARE_BITMAP(enabled_prof_enter_syscalls, FTRACE_SYSCALL_MAX);
301static DECLARE_BITMAP(enabled_prof_exit_syscalls, FTRACE_SYSCALL_MAX); 304static DECLARE_BITMAP(enabled_prof_exit_syscalls, FTRACE_SYSCALL_MAX);
302static int sys_prof_refcount_enter; 305static int sys_prof_refcount_enter;
@@ -304,7 +307,7 @@ static int sys_prof_refcount_exit;
304 307
305static void prof_syscall_enter(struct pt_regs *regs, long id) 308static void prof_syscall_enter(struct pt_regs *regs, long id)
306{ 309{
307 struct syscall_enter_record *rec; 310 struct syscall_trace_enter *rec;
308 struct syscall_metadata *sys_data; 311 struct syscall_metadata *sys_data;
309 int syscall_nr; 312 int syscall_nr;
310 int size; 313 int size;
@@ -328,9 +331,10 @@ static void prof_syscall_enter(struct pt_regs *regs, long id)
328 /* zero the dead bytes from align to not leak stack to user */ 331 /* zero the dead bytes from align to not leak stack to user */
329 *(u64 *)(&raw_data[size - sizeof(u64)]) = 0ULL; 332 *(u64 *)(&raw_data[size - sizeof(u64)]) = 0ULL;
330 333
331 rec = (struct syscall_enter_record *) raw_data; 334 rec = (struct syscall_trace_enter *) raw_data;
332 tracing_generic_entry_update(&rec->entry, 0, 0); 335 tracing_generic_entry_update(&rec->ent, 0, 0);
333 rec->entry.type = sys_data->enter_id; 336 rec->ent.type = sys_data->enter_id;
337 rec->nr = syscall_nr;
334 syscall_get_arguments(current, regs, 0, sys_data->nb_args, 338 syscall_get_arguments(current, regs, 0, sys_data->nb_args,
335 (unsigned long *)&rec->args); 339 (unsigned long *)&rec->args);
336 perf_tpcounter_event(sys_data->enter_id, 0, 1, rec, size); 340 perf_tpcounter_event(sys_data->enter_id, 0, 1, rec, size);
@@ -379,7 +383,7 @@ void unreg_prof_syscall_enter(char *name)
379static void prof_syscall_exit(struct pt_regs *regs, long ret) 383static void prof_syscall_exit(struct pt_regs *regs, long ret)
380{ 384{
381 struct syscall_metadata *sys_data; 385 struct syscall_metadata *sys_data;
382 struct syscall_exit_record rec; 386 struct syscall_trace_exit rec;
383 int syscall_nr; 387 int syscall_nr;
384 388
385 syscall_nr = syscall_get_nr(current, regs); 389 syscall_nr = syscall_get_nr(current, regs);
@@ -390,8 +394,9 @@ static void prof_syscall_exit(struct pt_regs *regs, long ret)
390 if (!sys_data) 394 if (!sys_data)
391 return; 395 return;
392 396
393 tracing_generic_entry_update(&rec.entry, 0, 0); 397 tracing_generic_entry_update(&rec.ent, 0, 0);
394 rec.entry.type = sys_data->exit_id; 398 rec.ent.type = sys_data->exit_id;
399 rec.nr = syscall_nr;
395 rec.ret = syscall_get_return_value(current, regs); 400 rec.ret = syscall_get_return_value(current, regs);
396 401
397 perf_tpcounter_event(sys_data->exit_id, 0, 1, &rec, sizeof(rec)); 402 perf_tpcounter_event(sys_data->exit_id, 0, 1, &rec, sizeof(rec));