Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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 **)&param = 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, &param);
^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 **)&param = 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, &param);
^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) }