^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) #include <trace/syscall.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) #include <trace/events/syscalls.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) #include <linux/syscalls.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/module.h> /* for MODULE_NAME_LEN via KSYM_SYMBOL_LEN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/ftrace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/perf_event.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/xarray.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <asm/syscall.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include "trace_output.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include "trace.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) static DEFINE_MUTEX(syscall_trace_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) static int syscall_enter_register(struct trace_event_call *event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) enum trace_reg type, void *data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) static int syscall_exit_register(struct trace_event_call *event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) enum trace_reg type, void *data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) static struct list_head *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) syscall_get_enter_fields(struct trace_event_call *call)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) struct syscall_metadata *entry = call->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) return &entry->enter_fields;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) extern struct syscall_metadata *__start_syscalls_metadata[];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) extern struct syscall_metadata *__stop_syscalls_metadata[];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) static DEFINE_XARRAY(syscalls_metadata_sparse);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) static struct syscall_metadata **syscalls_metadata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #ifndef ARCH_HAS_SYSCALL_MATCH_SYM_NAME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) static inline bool arch_syscall_match_sym_name(const char *sym, const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) * Only compare after the "sys" prefix. Archs that use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) * syscall wrappers may have syscalls symbols aliases prefixed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) * with ".SyS" or ".sys" instead of "sys", leading to an unwanted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) * mismatch.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) return !strcmp(sym + 3, name + 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #ifdef ARCH_TRACE_IGNORE_COMPAT_SYSCALLS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) * Some architectures that allow for 32bit applications
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) * to run on a 64bit kernel, do not map the syscalls for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) * the 32bit tasks the same as they do for 64bit tasks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) * *cough*x86*cough*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) * In such a case, instead of reporting the wrong syscalls,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) * simply ignore them.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) * For an arch to ignore the compat syscalls it needs to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) * define ARCH_TRACE_IGNORE_COMPAT_SYSCALLS as well as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) * define the function arch_trace_is_compat_syscall() to let
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) * the tracing system know that it should ignore it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) trace_get_syscall_nr(struct task_struct *task, struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) if (unlikely(arch_trace_is_compat_syscall(regs)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) return syscall_get_nr(task, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) static inline int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) trace_get_syscall_nr(struct task_struct *task, struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) return syscall_get_nr(task, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #endif /* ARCH_TRACE_IGNORE_COMPAT_SYSCALLS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) static __init struct syscall_metadata *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) find_syscall_meta(unsigned long syscall)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) struct syscall_metadata **start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) struct syscall_metadata **stop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) char str[KSYM_SYMBOL_LEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) start = __start_syscalls_metadata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) stop = __stop_syscalls_metadata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) kallsyms_lookup(syscall, NULL, NULL, NULL, str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) if (arch_syscall_match_sym_name(str, "sys_ni_syscall"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) for ( ; start < stop; start++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) if ((*start)->name && arch_syscall_match_sym_name(str, (*start)->name))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) return *start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) static struct syscall_metadata *syscall_nr_to_meta(int nr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) if (IS_ENABLED(CONFIG_HAVE_SPARSE_SYSCALL_NR))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) return xa_load(&syscalls_metadata_sparse, (unsigned long)nr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) if (!syscalls_metadata || nr >= NR_syscalls || nr < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) return syscalls_metadata[nr];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) const char *get_syscall_name(int syscall)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) struct syscall_metadata *entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) entry = syscall_nr_to_meta(syscall);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) if (!entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) return entry->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) static enum print_line_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) print_syscall_enter(struct trace_iterator *iter, int flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) struct trace_event *event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) struct trace_array *tr = iter->tr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) struct trace_seq *s = &iter->seq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) struct trace_entry *ent = iter->ent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) struct syscall_trace_enter *trace;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) struct syscall_metadata *entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) int i, syscall;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) trace = (typeof(trace))ent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) syscall = trace->nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) entry = syscall_nr_to_meta(syscall);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) if (!entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) if (entry->enter_event->event.type != ent->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) WARN_ON_ONCE(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) trace_seq_printf(s, "%s(", entry->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) for (i = 0; i < entry->nb_args; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) if (trace_seq_has_overflowed(s))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) /* parameter types */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) if (tr->trace_flags & TRACE_ITER_VERBOSE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) trace_seq_printf(s, "%s ", entry->types[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) /* parameter values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) trace_seq_printf(s, "%s: %lx%s", entry->args[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) trace->args[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) i == entry->nb_args - 1 ? "" : ", ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) trace_seq_putc(s, ')');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) end:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) trace_seq_putc(s, '\n');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) return trace_handle_return(s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) static enum print_line_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) print_syscall_exit(struct trace_iterator *iter, int flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) struct trace_event *event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) struct trace_seq *s = &iter->seq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) struct trace_entry *ent = iter->ent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) struct syscall_trace_exit *trace;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) int syscall;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) struct syscall_metadata *entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) trace = (typeof(trace))ent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) syscall = trace->nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) entry = syscall_nr_to_meta(syscall);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) if (!entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) trace_seq_putc(s, '\n');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) if (entry->exit_event->event.type != ent->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) WARN_ON_ONCE(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) return TRACE_TYPE_UNHANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) trace_seq_printf(s, "%s -> 0x%lx\n", entry->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) trace->ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) return trace_handle_return(s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) extern char *__bad_type_size(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) #define SYSCALL_FIELD(_type, _name) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) .type = #_type, .name = #_name, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) .size = sizeof(_type), .align = __alignof__(_type), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) .is_signed = is_signed_type(_type), .filter_type = FILTER_OTHER }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) static int __init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) __set_enter_print_fmt(struct syscall_metadata *entry, char *buf, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) int pos = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) /* When len=0, we just calculate the needed length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) #define LEN_OR_ZERO (len ? len - pos : 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) pos += snprintf(buf + pos, LEN_OR_ZERO, "\"");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) for (i = 0; i < entry->nb_args; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) pos += snprintf(buf + pos, LEN_OR_ZERO, "%s: 0x%%0%zulx%s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) entry->args[i], sizeof(unsigned long),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) i == entry->nb_args - 1 ? "" : ", ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) pos += snprintf(buf + pos, LEN_OR_ZERO, "\"");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) for (i = 0; i < entry->nb_args; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) pos += snprintf(buf + pos, LEN_OR_ZERO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) ", ((unsigned long)(REC->%s))", entry->args[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) #undef LEN_OR_ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) /* return the length of print_fmt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) return pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) static int __init set_syscall_print_fmt(struct trace_event_call *call)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) char *print_fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) struct syscall_metadata *entry = call->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) if (entry->enter_event != call) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) call->print_fmt = "\"0x%lx\", REC->ret";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) /* First: called with 0 length to calculate the needed length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) len = __set_enter_print_fmt(entry, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) print_fmt = kmalloc(len + 1, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) if (!print_fmt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) /* Second: actually write the @print_fmt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) __set_enter_print_fmt(entry, print_fmt, len + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) call->print_fmt = print_fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) static void __init free_syscall_print_fmt(struct trace_event_call *call)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) struct syscall_metadata *entry = call->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) if (entry->enter_event == call)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) kfree(call->print_fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) static int __init syscall_enter_define_fields(struct trace_event_call *call)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) struct syscall_trace_enter trace;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) struct syscall_metadata *meta = call->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) int offset = offsetof(typeof(trace), args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) for (i = 0; i < meta->nb_args; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) ret = trace_define_field(call, meta->types[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) meta->args[i], offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) sizeof(unsigned long), 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) FILTER_OTHER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) offset += sizeof(unsigned long);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) static void ftrace_syscall_enter(void *data, struct pt_regs *regs, long id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) struct trace_array *tr = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) struct trace_event_file *trace_file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) struct syscall_trace_enter *entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) struct syscall_metadata *sys_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) struct ring_buffer_event *event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) struct trace_buffer *buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) unsigned long irq_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) unsigned long args[6];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) int pc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) int syscall_nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) int size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) syscall_nr = trace_get_syscall_nr(current, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) if (syscall_nr < 0 || syscall_nr >= NR_syscalls)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) /* Here we're inside tp handler's rcu_read_lock_sched (__DO_TRACE) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) trace_file = rcu_dereference_sched(tr->enter_syscall_files[syscall_nr]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) if (!trace_file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) if (trace_trigger_soft_disabled(trace_file))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) sys_data = syscall_nr_to_meta(syscall_nr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) if (!sys_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) size = sizeof(*entry) + sizeof(unsigned long) * sys_data->nb_args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) local_save_flags(irq_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) pc = preempt_count();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) buffer = tr->array_buffer.buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) event = trace_buffer_lock_reserve(buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) sys_data->enter_event->event.type, size, irq_flags, pc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) if (!event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) entry = ring_buffer_event_data(event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) entry->nr = syscall_nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) syscall_get_arguments(current, regs, args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) memcpy(entry->args, args, sizeof(unsigned long) * sys_data->nb_args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) event_trigger_unlock_commit(trace_file, buffer, event, entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) irq_flags, pc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) static void ftrace_syscall_exit(void *data, struct pt_regs *regs, long ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) struct trace_array *tr = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) struct trace_event_file *trace_file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) struct syscall_trace_exit *entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) struct syscall_metadata *sys_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) struct ring_buffer_event *event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) struct trace_buffer *buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) unsigned long irq_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) int pc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) int syscall_nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) syscall_nr = trace_get_syscall_nr(current, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) if (syscall_nr < 0 || syscall_nr >= NR_syscalls)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) /* Here we're inside tp handler's rcu_read_lock_sched (__DO_TRACE()) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) trace_file = rcu_dereference_sched(tr->exit_syscall_files[syscall_nr]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) if (!trace_file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) if (trace_trigger_soft_disabled(trace_file))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) sys_data = syscall_nr_to_meta(syscall_nr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) if (!sys_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) local_save_flags(irq_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) pc = preempt_count();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) buffer = tr->array_buffer.buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) event = trace_buffer_lock_reserve(buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) sys_data->exit_event->event.type, sizeof(*entry),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) irq_flags, pc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) if (!event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) entry = ring_buffer_event_data(event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) entry->nr = syscall_nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) entry->ret = syscall_get_return_value(current, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) event_trigger_unlock_commit(trace_file, buffer, event, entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) irq_flags, pc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) static int reg_event_syscall_enter(struct trace_event_file *file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) struct trace_event_call *call)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) struct trace_array *tr = file->tr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) int num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) num = ((struct syscall_metadata *)call->data)->syscall_nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) if (WARN_ON_ONCE(num < 0 || num >= NR_syscalls))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) return -ENOSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) mutex_lock(&syscall_trace_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) if (!tr->sys_refcount_enter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) ret = register_trace_sys_enter(ftrace_syscall_enter, tr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) if (!ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) rcu_assign_pointer(tr->enter_syscall_files[num], file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) tr->sys_refcount_enter++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) mutex_unlock(&syscall_trace_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) static void unreg_event_syscall_enter(struct trace_event_file *file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) struct trace_event_call *call)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) struct trace_array *tr = file->tr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) int num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) num = ((struct syscall_metadata *)call->data)->syscall_nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) if (WARN_ON_ONCE(num < 0 || num >= NR_syscalls))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) mutex_lock(&syscall_trace_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) tr->sys_refcount_enter--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) RCU_INIT_POINTER(tr->enter_syscall_files[num], NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) if (!tr->sys_refcount_enter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) unregister_trace_sys_enter(ftrace_syscall_enter, tr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) mutex_unlock(&syscall_trace_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) static int reg_event_syscall_exit(struct trace_event_file *file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) struct trace_event_call *call)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) struct trace_array *tr = file->tr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) int num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) num = ((struct syscall_metadata *)call->data)->syscall_nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) if (WARN_ON_ONCE(num < 0 || num >= NR_syscalls))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) return -ENOSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) mutex_lock(&syscall_trace_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) if (!tr->sys_refcount_exit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) ret = register_trace_sys_exit(ftrace_syscall_exit, tr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) if (!ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) rcu_assign_pointer(tr->exit_syscall_files[num], file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) tr->sys_refcount_exit++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) mutex_unlock(&syscall_trace_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) static void unreg_event_syscall_exit(struct trace_event_file *file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) struct trace_event_call *call)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) struct trace_array *tr = file->tr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) int num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) num = ((struct syscall_metadata *)call->data)->syscall_nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) if (WARN_ON_ONCE(num < 0 || num >= NR_syscalls))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) mutex_lock(&syscall_trace_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) tr->sys_refcount_exit--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) RCU_INIT_POINTER(tr->exit_syscall_files[num], NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) if (!tr->sys_refcount_exit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) unregister_trace_sys_exit(ftrace_syscall_exit, tr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) mutex_unlock(&syscall_trace_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) static int __init init_syscall_trace(struct trace_event_call *call)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) int id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) int num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) num = ((struct syscall_metadata *)call->data)->syscall_nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) if (num < 0 || num >= NR_syscalls) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) pr_debug("syscall %s metadata not mapped, disabling ftrace event\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) ((struct syscall_metadata *)call->data)->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) return -ENOSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) if (set_syscall_print_fmt(call) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) id = trace_event_raw_init(call);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) if (id < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) free_syscall_print_fmt(call);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) return id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) return id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) static struct trace_event_fields __refdata syscall_enter_fields_array[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) SYSCALL_FIELD(int, __syscall_nr),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) { .type = TRACE_FUNCTION_TYPE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) .define_fields = syscall_enter_define_fields },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) struct trace_event_functions enter_syscall_print_funcs = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) .trace = print_syscall_enter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) struct trace_event_functions exit_syscall_print_funcs = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) .trace = print_syscall_exit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) struct trace_event_class __refdata event_class_syscall_enter = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) .system = "syscalls",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) .reg = syscall_enter_register,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) .fields_array = syscall_enter_fields_array,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) .get_fields = syscall_get_enter_fields,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) .raw_init = init_syscall_trace,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) struct trace_event_class __refdata event_class_syscall_exit = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) .system = "syscalls",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) .reg = syscall_exit_register,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) .fields_array = (struct trace_event_fields[]){
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) SYSCALL_FIELD(int, __syscall_nr),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) SYSCALL_FIELD(long, ret),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) .fields = LIST_HEAD_INIT(event_class_syscall_exit.fields),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) .raw_init = init_syscall_trace,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) unsigned long __init __weak arch_syscall_addr(int nr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) return (unsigned long)sys_call_table[nr];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) void __init init_ftrace_syscalls(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) struct syscall_metadata *meta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) unsigned long addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) void *ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) if (!IS_ENABLED(CONFIG_HAVE_SPARSE_SYSCALL_NR)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) syscalls_metadata = kcalloc(NR_syscalls,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) sizeof(*syscalls_metadata),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) if (!syscalls_metadata) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) WARN_ON(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) for (i = 0; i < NR_syscalls; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) addr = arch_syscall_addr(i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) meta = find_syscall_meta(addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) if (!meta)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) meta->syscall_nr = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) if (!IS_ENABLED(CONFIG_HAVE_SPARSE_SYSCALL_NR)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) syscalls_metadata[i] = meta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) ret = xa_store(&syscalls_metadata_sparse, i, meta,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) WARN(xa_is_err(ret),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) "Syscall memory allocation failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) #ifdef CONFIG_PERF_EVENTS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) static DECLARE_BITMAP(enabled_perf_enter_syscalls, NR_syscalls);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) static DECLARE_BITMAP(enabled_perf_exit_syscalls, NR_syscalls);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) static int sys_perf_refcount_enter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) static int sys_perf_refcount_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) static int perf_call_bpf_enter(struct trace_event_call *call, struct pt_regs *regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) struct syscall_metadata *sys_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) struct syscall_trace_enter *rec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) struct syscall_tp_t {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) unsigned long long regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) unsigned long syscall_nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) unsigned long args[SYSCALL_DEFINE_MAXARGS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) } param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) *(struct pt_regs **)¶m = regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) param.syscall_nr = rec->nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) for (i = 0; i < sys_data->nb_args; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) param.args[i] = rec->args[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) return trace_call_bpf(call, ¶m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) static void perf_syscall_enter(void *ignore, struct pt_regs *regs, long id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) struct syscall_metadata *sys_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) struct syscall_trace_enter *rec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) struct hlist_head *head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) unsigned long args[6];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) bool valid_prog_array;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) int syscall_nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) int rctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) int size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) syscall_nr = trace_get_syscall_nr(current, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) if (syscall_nr < 0 || syscall_nr >= NR_syscalls)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) if (!test_bit(syscall_nr, enabled_perf_enter_syscalls))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) sys_data = syscall_nr_to_meta(syscall_nr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) if (!sys_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) head = this_cpu_ptr(sys_data->enter_event->perf_events);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) valid_prog_array = bpf_prog_array_valid(sys_data->enter_event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) if (!valid_prog_array && hlist_empty(head))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) /* get the size after alignment with the u32 buffer size field */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) size = sizeof(unsigned long) * sys_data->nb_args + sizeof(*rec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) size = ALIGN(size + sizeof(u32), sizeof(u64));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) size -= sizeof(u32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) rec = perf_trace_buf_alloc(size, NULL, &rctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) if (!rec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) rec->nr = syscall_nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) syscall_get_arguments(current, regs, args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) memcpy(&rec->args, args, sizeof(unsigned long) * sys_data->nb_args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) if ((valid_prog_array &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) !perf_call_bpf_enter(sys_data->enter_event, regs, sys_data, rec)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) hlist_empty(head)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) perf_swevent_put_recursion_context(rctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) perf_trace_buf_submit(rec, size, rctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) sys_data->enter_event->event.type, 1, regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) head, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) static int perf_sysenter_enable(struct trace_event_call *call)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) int num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) num = ((struct syscall_metadata *)call->data)->syscall_nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) mutex_lock(&syscall_trace_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) if (!sys_perf_refcount_enter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) ret = register_trace_sys_enter(perf_syscall_enter, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) pr_info("event trace: Could not activate syscall entry trace point");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) set_bit(num, enabled_perf_enter_syscalls);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) sys_perf_refcount_enter++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) mutex_unlock(&syscall_trace_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) static void perf_sysenter_disable(struct trace_event_call *call)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) int num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) num = ((struct syscall_metadata *)call->data)->syscall_nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) mutex_lock(&syscall_trace_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) sys_perf_refcount_enter--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) clear_bit(num, enabled_perf_enter_syscalls);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) if (!sys_perf_refcount_enter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) unregister_trace_sys_enter(perf_syscall_enter, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) mutex_unlock(&syscall_trace_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) static int perf_call_bpf_exit(struct trace_event_call *call, struct pt_regs *regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) struct syscall_trace_exit *rec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) struct syscall_tp_t {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) unsigned long long regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) unsigned long syscall_nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) unsigned long ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) } param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) *(struct pt_regs **)¶m = regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) param.syscall_nr = rec->nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) param.ret = rec->ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) return trace_call_bpf(call, ¶m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) static void perf_syscall_exit(void *ignore, struct pt_regs *regs, long ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) struct syscall_metadata *sys_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) struct syscall_trace_exit *rec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) struct hlist_head *head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) bool valid_prog_array;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) int syscall_nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) int rctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) int size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) syscall_nr = trace_get_syscall_nr(current, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) if (syscall_nr < 0 || syscall_nr >= NR_syscalls)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) if (!test_bit(syscall_nr, enabled_perf_exit_syscalls))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) sys_data = syscall_nr_to_meta(syscall_nr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) if (!sys_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) head = this_cpu_ptr(sys_data->exit_event->perf_events);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) valid_prog_array = bpf_prog_array_valid(sys_data->exit_event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) if (!valid_prog_array && hlist_empty(head))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) /* We can probably do that at build time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) size = ALIGN(sizeof(*rec) + sizeof(u32), sizeof(u64));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) size -= sizeof(u32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) rec = perf_trace_buf_alloc(size, NULL, &rctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) if (!rec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) rec->nr = syscall_nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) rec->ret = syscall_get_return_value(current, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) if ((valid_prog_array &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) !perf_call_bpf_exit(sys_data->exit_event, regs, rec)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) hlist_empty(head)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) perf_swevent_put_recursion_context(rctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) perf_trace_buf_submit(rec, size, rctx, sys_data->exit_event->event.type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) 1, regs, head, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) static int perf_sysexit_enable(struct trace_event_call *call)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) int num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) num = ((struct syscall_metadata *)call->data)->syscall_nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) mutex_lock(&syscall_trace_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) if (!sys_perf_refcount_exit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) ret = register_trace_sys_exit(perf_syscall_exit, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) pr_info("event trace: Could not activate syscall exit trace point");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) set_bit(num, enabled_perf_exit_syscalls);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) sys_perf_refcount_exit++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) mutex_unlock(&syscall_trace_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) static void perf_sysexit_disable(struct trace_event_call *call)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) int num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) num = ((struct syscall_metadata *)call->data)->syscall_nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) mutex_lock(&syscall_trace_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) sys_perf_refcount_exit--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) clear_bit(num, enabled_perf_exit_syscalls);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) if (!sys_perf_refcount_exit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) unregister_trace_sys_exit(perf_syscall_exit, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) mutex_unlock(&syscall_trace_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) #endif /* CONFIG_PERF_EVENTS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) static int syscall_enter_register(struct trace_event_call *event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) enum trace_reg type, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) struct trace_event_file *file = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) case TRACE_REG_REGISTER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) return reg_event_syscall_enter(file, event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) case TRACE_REG_UNREGISTER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) unreg_event_syscall_enter(file, event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) #ifdef CONFIG_PERF_EVENTS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) case TRACE_REG_PERF_REGISTER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) return perf_sysenter_enable(event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) case TRACE_REG_PERF_UNREGISTER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) perf_sysenter_disable(event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) case TRACE_REG_PERF_OPEN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) case TRACE_REG_PERF_CLOSE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) case TRACE_REG_PERF_ADD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) case TRACE_REG_PERF_DEL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) static int syscall_exit_register(struct trace_event_call *event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) enum trace_reg type, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) struct trace_event_file *file = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) case TRACE_REG_REGISTER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) return reg_event_syscall_exit(file, event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) case TRACE_REG_UNREGISTER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) unreg_event_syscall_exit(file, event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) #ifdef CONFIG_PERF_EVENTS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) case TRACE_REG_PERF_REGISTER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) return perf_sysexit_enable(event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) case TRACE_REG_PERF_UNREGISTER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) perf_sysexit_disable(event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) case TRACE_REG_PERF_OPEN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) case TRACE_REG_PERF_CLOSE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) case TRACE_REG_PERF_ADD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) case TRACE_REG_PERF_DEL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) }