Lines Matching +full:static +full:- +full:trace +full:- +full:id
1 // SPDX-License-Identifier: GPL-2.0
2 #include <trace/syscall.h>
3 #include <trace/events/syscalls.h>
14 #include "trace.h"
16 static DEFINE_MUTEX(syscall_trace_lock);
18 static int syscall_enter_register(struct trace_event_call *event,
20 static int syscall_exit_register(struct trace_event_call *event,
23 static struct list_head *
26 struct syscall_metadata *entry = call->data; in syscall_get_enter_fields()
28 return &entry->enter_fields; in syscall_get_enter_fields()
34 static DEFINE_XARRAY(syscalls_metadata_sparse);
35 static struct syscall_metadata **syscalls_metadata;
38 static inline bool arch_syscall_match_sym_name(const char *sym, const char *name) in arch_syscall_match_sym_name()
66 static int
70 return -1; in trace_get_syscall_nr()
75 static inline int
82 static __init struct syscall_metadata *
98 if ((*start)->name && arch_syscall_match_sym_name(str, (*start)->name)) in find_syscall_meta()
104 static struct syscall_metadata *syscall_nr_to_meta(int nr) in syscall_nr_to_meta()
123 return entry->name; in get_syscall_name()
126 static enum print_line_t
130 struct trace_array *tr = iter->tr; in print_syscall_enter()
131 struct trace_seq *s = &iter->seq; in print_syscall_enter()
132 struct trace_entry *ent = iter->ent; in print_syscall_enter()
133 struct syscall_trace_enter *trace; in print_syscall_enter() local
137 trace = (typeof(trace))ent; in print_syscall_enter()
138 syscall = trace->nr; in print_syscall_enter()
144 if (entry->enter_event->event.type != ent->type) { in print_syscall_enter()
149 trace_seq_printf(s, "%s(", entry->name); in print_syscall_enter()
151 for (i = 0; i < entry->nb_args; i++) { in print_syscall_enter()
157 if (tr && tr->trace_flags & TRACE_ITER_VERBOSE) in print_syscall_enter()
158 trace_seq_printf(s, "%s ", entry->types[i]); in print_syscall_enter()
161 trace_seq_printf(s, "%s: %lx%s", entry->args[i], in print_syscall_enter()
162 trace->args[i], in print_syscall_enter()
163 i == entry->nb_args - 1 ? "" : ", "); in print_syscall_enter()
173 static enum print_line_t
177 struct trace_seq *s = &iter->seq; in print_syscall_exit()
178 struct trace_entry *ent = iter->ent; in print_syscall_exit()
179 struct syscall_trace_exit *trace; in print_syscall_exit() local
183 trace = (typeof(trace))ent; in print_syscall_exit()
184 syscall = trace->nr; in print_syscall_exit()
192 if (entry->exit_event->event.type != ent->type) { in print_syscall_exit()
197 trace_seq_printf(s, "%s -> 0x%lx\n", entry->name, in print_syscall_exit()
198 trace->ret); in print_syscall_exit()
209 static int __init
216 #define LEN_OR_ZERO (len ? len - pos : 0) in __set_enter_print_fmt()
219 for (i = 0; i < entry->nb_args; i++) { in __set_enter_print_fmt()
221 entry->args[i], sizeof(unsigned long), in __set_enter_print_fmt()
222 i == entry->nb_args - 1 ? "" : ", "); in __set_enter_print_fmt()
226 for (i = 0; i < entry->nb_args; i++) { in __set_enter_print_fmt()
228 ", ((unsigned long)(REC->%s))", entry->args[i]); in __set_enter_print_fmt()
237 static int __init set_syscall_print_fmt(struct trace_event_call *call) in set_syscall_print_fmt()
241 struct syscall_metadata *entry = call->data; in set_syscall_print_fmt()
243 if (entry->enter_event != call) { in set_syscall_print_fmt()
244 call->print_fmt = "\"0x%lx\", REC->ret"; in set_syscall_print_fmt()
253 return -ENOMEM; in set_syscall_print_fmt()
257 call->print_fmt = print_fmt; in set_syscall_print_fmt()
262 static void __init free_syscall_print_fmt(struct trace_event_call *call) in free_syscall_print_fmt()
264 struct syscall_metadata *entry = call->data; in free_syscall_print_fmt()
266 if (entry->enter_event == call) in free_syscall_print_fmt()
267 kfree(call->print_fmt); in free_syscall_print_fmt()
270 static int __init syscall_enter_define_fields(struct trace_event_call *call) in syscall_enter_define_fields()
272 struct syscall_trace_enter trace; in syscall_enter_define_fields() local
273 struct syscall_metadata *meta = call->data; in syscall_enter_define_fields()
274 int offset = offsetof(typeof(trace), args); in syscall_enter_define_fields()
278 for (i = 0; i < meta->nb_args; i++) { in syscall_enter_define_fields()
279 ret = trace_define_field(call, meta->types[i], in syscall_enter_define_fields()
280 meta->args[i], offset, in syscall_enter_define_fields()
291 static void ftrace_syscall_enter(void *data, struct pt_regs *regs, long id) in ftrace_syscall_enter() argument
304 * buffer and per-cpu data require preemption to be disabled. in ftrace_syscall_enter()
314 trace_file = rcu_dereference_sched(tr->enter_syscall_files[syscall_nr]); in ftrace_syscall_enter()
325 size = sizeof(*entry) + sizeof(unsigned long) * sys_data->nb_args; in ftrace_syscall_enter()
332 entry->nr = syscall_nr; in ftrace_syscall_enter()
334 memcpy(entry->args, args, sizeof(unsigned long) * sys_data->nb_args); in ftrace_syscall_enter()
339 static void ftrace_syscall_exit(void *data, struct pt_regs *regs, long ret) in ftrace_syscall_exit()
350 * buffer and per-cpu data require preemption to be disabled. in ftrace_syscall_exit()
360 trace_file = rcu_dereference_sched(tr->exit_syscall_files[syscall_nr]); in ftrace_syscall_exit()
376 entry->nr = syscall_nr; in ftrace_syscall_exit()
377 entry->ret = syscall_get_return_value(current, regs); in ftrace_syscall_exit()
382 static int reg_event_syscall_enter(struct trace_event_file *file, in reg_event_syscall_enter()
385 struct trace_array *tr = file->tr; in reg_event_syscall_enter()
389 num = ((struct syscall_metadata *)call->data)->syscall_nr; in reg_event_syscall_enter()
391 return -ENOSYS; in reg_event_syscall_enter()
393 if (!tr->sys_refcount_enter) in reg_event_syscall_enter()
396 rcu_assign_pointer(tr->enter_syscall_files[num], file); in reg_event_syscall_enter()
397 tr->sys_refcount_enter++; in reg_event_syscall_enter()
403 static void unreg_event_syscall_enter(struct trace_event_file *file, in unreg_event_syscall_enter()
406 struct trace_array *tr = file->tr; in unreg_event_syscall_enter()
409 num = ((struct syscall_metadata *)call->data)->syscall_nr; in unreg_event_syscall_enter()
413 tr->sys_refcount_enter--; in unreg_event_syscall_enter()
414 RCU_INIT_POINTER(tr->enter_syscall_files[num], NULL); in unreg_event_syscall_enter()
415 if (!tr->sys_refcount_enter) in unreg_event_syscall_enter()
420 static int reg_event_syscall_exit(struct trace_event_file *file, in reg_event_syscall_exit()
423 struct trace_array *tr = file->tr; in reg_event_syscall_exit()
427 num = ((struct syscall_metadata *)call->data)->syscall_nr; in reg_event_syscall_exit()
429 return -ENOSYS; in reg_event_syscall_exit()
431 if (!tr->sys_refcount_exit) in reg_event_syscall_exit()
434 rcu_assign_pointer(tr->exit_syscall_files[num], file); in reg_event_syscall_exit()
435 tr->sys_refcount_exit++; in reg_event_syscall_exit()
441 static void unreg_event_syscall_exit(struct trace_event_file *file, in unreg_event_syscall_exit()
444 struct trace_array *tr = file->tr; in unreg_event_syscall_exit()
447 num = ((struct syscall_metadata *)call->data)->syscall_nr; in unreg_event_syscall_exit()
451 tr->sys_refcount_exit--; in unreg_event_syscall_exit()
452 RCU_INIT_POINTER(tr->exit_syscall_files[num], NULL); in unreg_event_syscall_exit()
453 if (!tr->sys_refcount_exit) in unreg_event_syscall_exit()
458 static int __init init_syscall_trace(struct trace_event_call *call) in init_syscall_trace()
460 int id; in init_syscall_trace() local
463 num = ((struct syscall_metadata *)call->data)->syscall_nr; in init_syscall_trace()
466 ((struct syscall_metadata *)call->data)->name); in init_syscall_trace()
467 return -ENOSYS; in init_syscall_trace()
471 return -ENOMEM; in init_syscall_trace()
473 id = trace_event_raw_init(call); in init_syscall_trace()
475 if (id < 0) { in init_syscall_trace()
477 return id; in init_syscall_trace()
480 return id; in init_syscall_trace()
483 static struct trace_event_fields __refdata syscall_enter_fields_array[] = {
491 .trace = print_syscall_enter,
495 .trace = print_syscall_exit,
546 meta->syscall_nr = i; in init_ftrace_syscalls()
562 static DECLARE_BITMAP(enabled_perf_enter_syscalls, NR_syscalls);
563 static DECLARE_BITMAP(enabled_perf_exit_syscalls, NR_syscalls);
564 static int sys_perf_refcount_enter;
565 static int sys_perf_refcount_exit;
567 static int perf_call_bpf_enter(struct trace_event_call *call, struct pt_regs *regs, in perf_call_bpf_enter()
583 param.syscall_nr = rec->nr; in perf_call_bpf_enter()
584 for (i = 0; i < sys_data->nb_args; i++) in perf_call_bpf_enter()
585 param.args[i] = rec->args[i]; in perf_call_bpf_enter()
589 static void perf_syscall_enter(void *ignore, struct pt_regs *regs, long id) in perf_syscall_enter() argument
603 * buffer and per-cpu data require preemption to be disabled. in perf_syscall_enter()
618 head = this_cpu_ptr(sys_data->enter_event->perf_events); in perf_syscall_enter()
619 valid_prog_array = bpf_prog_array_valid(sys_data->enter_event); in perf_syscall_enter()
624 size = sizeof(unsigned long) * sys_data->nb_args + sizeof(*rec); in perf_syscall_enter()
626 size -= sizeof(u32); in perf_syscall_enter()
632 rec->nr = syscall_nr; in perf_syscall_enter()
634 memcpy(&rec->args, args, sizeof(unsigned long) * sys_data->nb_args); in perf_syscall_enter()
637 !perf_call_bpf_enter(sys_data->enter_event, fake_regs, sys_data, rec)) || in perf_syscall_enter()
644 sys_data->enter_event->event.type, 1, regs, in perf_syscall_enter()
648 static int perf_sysenter_enable(struct trace_event_call *call) in perf_sysenter_enable()
653 num = ((struct syscall_metadata *)call->data)->syscall_nr; in perf_sysenter_enable()
659 pr_info("event trace: Could not activate syscall entry trace point"); in perf_sysenter_enable()
668 static void perf_sysenter_disable(struct trace_event_call *call) in perf_sysenter_disable()
672 num = ((struct syscall_metadata *)call->data)->syscall_nr; in perf_sysenter_disable()
675 sys_perf_refcount_enter--; in perf_sysenter_disable()
682 static int perf_call_bpf_exit(struct trace_event_call *call, struct pt_regs *regs, in perf_call_bpf_exit()
694 param.syscall_nr = rec->nr; in perf_call_bpf_exit()
695 param.ret = rec->ret; in perf_call_bpf_exit()
699 static void perf_syscall_exit(void *ignore, struct pt_regs *regs, long ret) in perf_syscall_exit()
712 * buffer and per-cpu data require preemption to be disabled. in perf_syscall_exit()
727 head = this_cpu_ptr(sys_data->exit_event->perf_events); in perf_syscall_exit()
728 valid_prog_array = bpf_prog_array_valid(sys_data->exit_event); in perf_syscall_exit()
734 size -= sizeof(u32); in perf_syscall_exit()
740 rec->nr = syscall_nr; in perf_syscall_exit()
741 rec->ret = syscall_get_return_value(current, regs); in perf_syscall_exit()
744 !perf_call_bpf_exit(sys_data->exit_event, fake_regs, rec)) || in perf_syscall_exit()
750 perf_trace_buf_submit(rec, size, rctx, sys_data->exit_event->event.type, in perf_syscall_exit()
754 static int perf_sysexit_enable(struct trace_event_call *call) in perf_sysexit_enable()
759 num = ((struct syscall_metadata *)call->data)->syscall_nr; in perf_sysexit_enable()
765 pr_info("event trace: Could not activate syscall exit trace point"); in perf_sysexit_enable()
774 static void perf_sysexit_disable(struct trace_event_call *call) in perf_sysexit_disable()
778 num = ((struct syscall_metadata *)call->data)->syscall_nr; in perf_sysexit_disable()
781 sys_perf_refcount_exit--; in perf_sysexit_disable()
790 static int syscall_enter_register(struct trace_event_call *event, in syscall_enter_register()
818 static int syscall_exit_register(struct trace_event_call *event, in syscall_exit_register()