Release 4.15 kernel/trace/trace_syscalls.c
// SPDX-License-Identifier: GPL-2.0
#include <trace/syscall.h>
#include <trace/events/syscalls.h>
#include <linux/syscalls.h>
#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/module.h> /* for MODULE_NAME_LEN via KSYM_SYMBOL_LEN */
#include <linux/ftrace.h>
#include <linux/perf_event.h>
#include <asm/syscall.h>
#include "trace_output.h"
#include "trace.h"
static DEFINE_MUTEX(syscall_trace_lock);
static int syscall_enter_register(struct trace_event_call *event,
enum trace_reg type, void *data);
static int syscall_exit_register(struct trace_event_call *event,
enum trace_reg type, void *data);
static struct list_head *
syscall_get_enter_fields(struct trace_event_call *call)
{
struct syscall_metadata *entry = call->data;
return &entry->enter_fields;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Steven Rostedt | 28 | 100.00% | 2 | 100.00% |
Total | 28 | 100.00% | 2 | 100.00% |
extern struct syscall_metadata *__start_syscalls_metadata[];
extern struct syscall_metadata *__stop_syscalls_metadata[];
static struct syscall_metadata **syscalls_metadata;
#ifndef ARCH_HAS_SYSCALL_MATCH_SYM_NAME
static inline bool arch_syscall_match_sym_name(const char *sym, const char *name)
{
/*
* Only compare after the "sys" prefix. Archs that use
* syscall wrappers may have syscalls symbols aliases prefixed
* with ".SyS" or ".sys" instead of "sys", leading to an unwanted
* mismatch.
*/
return !strcmp(sym + 3, name + 3);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Ian Munsie | 30 | 96.77% | 1 | 50.00% |
Jovi Zhangwei | 1 | 3.23% | 1 | 50.00% |
Total | 31 | 100.00% | 2 | 100.00% |
#endif
#ifdef ARCH_TRACE_IGNORE_COMPAT_SYSCALLS
/*
* Some architectures that allow for 32bit applications
* to run on a 64bit kernel, do not map the syscalls for
* the 32bit tasks the same as they do for 64bit tasks.
*
* *cough*x86*cough*
*
* In such a case, instead of reporting the wrong syscalls,
* simply ignore them.
*
* For an arch to ignore the compat syscalls it needs to
* define ARCH_TRACE_IGNORE_COMPAT_SYSCALLS as well as
* define the function arch_trace_is_compat_syscall() to let
* the tracing system know that it should ignore it.
*/
static int
trace_get_syscall_nr(struct task_struct *task, struct pt_regs *regs)
{
if (unlikely(arch_trace_is_compat_syscall(regs)))
return -1;
return syscall_get_nr(task, regs);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Steven Rostedt | 38 | 100.00% | 1 | 100.00% |
Total | 38 | 100.00% | 1 | 100.00% |
#else
static inline int
trace_get_syscall_nr(struct task_struct *task, struct pt_regs *regs)
{
return syscall_get_nr(task, regs);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Steven Rostedt | 25 | 100.00% | 1 | 100.00% |
Total | 25 | 100.00% | 1 | 100.00% |
#endif /* ARCH_TRACE_IGNORE_COMPAT_SYSCALLS */
static __init struct syscall_metadata *
find_syscall_meta(unsigned long syscall)
{
struct syscall_metadata **start;
struct syscall_metadata **stop;
char str[KSYM_SYMBOL_LEN];
start = __start_syscalls_metadata;
stop = __stop_syscalls_metadata;
kallsyms_lookup(syscall, NULL, NULL, NULL, str);
if (arch_syscall_match_sym_name(str, "sys_ni_syscall"))
return NULL;
for ( ; start < stop; start++) {
if ((*start)->name && arch_syscall_match_sym_name(str, (*start)->name))
return *start;
}
return NULL;
}
static
struct syscall_metadata *syscall_nr_to_meta(int nr)
{
if (!syscalls_metadata || nr >= NR_syscalls || nr < 0)
return NULL;
return syscalls_metadata[nr];
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Frédéric Weisbecker | 32 | 96.97% | 1 | 50.00% |
Steven Rostedt | 1 | 3.03% | 1 | 50.00% |
Total | 33 | 100.00% | 2 | 100.00% |
const char *get_syscall_name(int syscall)
{
struct syscall_metadata *entry;
entry = syscall_nr_to_meta(syscall);
if (!entry)
return NULL;
return entry->name;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Tom Zanussi | 35 | 100.00% | 1 | 100.00% |
Total | 35 | 100.00% | 1 | 100.00% |
static enum print_line_t
print_syscall_enter(struct trace_iterator *iter, int flags,
struct trace_event *event)
{
struct trace_array *tr = iter->tr;
struct trace_seq *s = &iter->seq;
struct trace_entry *ent = iter->ent;
struct syscall_trace_enter *trace;
struct syscall_metadata *entry;
int i, syscall;
trace = (typeof(trace))ent;
syscall = trace->nr;
entry = syscall_nr_to_meta(syscall);
if (!entry)
goto end;
if (entry->enter_event->event.type != ent->type) {
WARN_ON_ONCE(1);
goto end;
}
trace_seq_printf(s, "%s(", entry->name);
for (i = 0; i < entry->nb_args; i++) {
if (trace_seq_has_overflowed(s))
goto end;
/* parameter types */
if (tr->trace_flags & TRACE_ITER_VERBOSE)
trace_seq_printf(s, "%s ", entry->types[i]);
/* parameter values */
trace_seq_printf(s, "%s: %lx%s", entry->args[i],
trace->args[i],
i == entry->nb_args - 1 ? "" : ", ");
}
trace_seq_putc(s, ')');
end:
trace_seq_putc(s, '\n');
return trace_handle_return(s);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Frédéric Weisbecker | 159 | 67.66% | 1 | 10.00% |
Steven Rostedt | 33 | 14.04% | 4 | 40.00% |
Jason Baron | 25 | 10.64% | 1 | 10.00% |
Li Zefan | 15 | 6.38% | 2 | 20.00% |
Lai Jiangshan | 2 | 0.85% | 1 | 10.00% |
Fengguang Wu | 1 | 0.43% | 1 | 10.00% |
Total | 235 | 100.00% | 10 | 100.00% |
static enum print_line_t
print_syscall_exit(struct trace_iterator *iter, int flags,
struct trace_event *event)
{
struct trace_seq *s = &iter->seq;
struct trace_entry *ent = iter->ent;
struct syscall_trace_exit *trace;
int syscall;
struct syscall_metadata *entry;
trace = (typeof(trace))ent;
syscall = trace->nr;
entry = syscall_nr_to_meta(syscall);
if (!entry) {
trace_seq_putc(s, '\n');
goto out;
}
if (entry->exit_event->event.type != ent->type) {
WARN_ON_ONCE(1);
return TRACE_TYPE_UNHANDLED;
}
trace_seq_printf(s, "%s -> 0x%lx\n", entry->name,
trace->ret);
out:
return trace_handle_return(s);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Frédéric Weisbecker | 92 | 66.19% | 1 | 12.50% |
Jason Baron | 25 | 17.99% | 1 | 12.50% |
Steven Rostedt | 17 | 12.23% | 3 | 37.50% |
Lai Jiangshan | 2 | 1.44% | 1 | 12.50% |
Jovi Zhangwei | 2 | 1.44% | 1 | 12.50% |
Fengguang Wu | 1 | 0.72% | 1 | 12.50% |
Total | 139 | 100.00% | 8 | 100.00% |
extern char *__bad_type_size(void);
#define SYSCALL_FIELD(type, field, name) \
sizeof(type) != sizeof(trace.field) ? \
__bad_type_size() : \
#type, #name, offsetof(typeof(trace), field), \
sizeof(trace.field), is_signed_type(type)
static int __init
__set_enter_print_fmt(struct syscall_metadata *entry, char *buf, int len)
{
int i;
int pos = 0;
/* When len=0, we just calculate the needed length */
#define LEN_OR_ZERO (len ? len - pos : 0)
pos += snprintf(buf + pos, LEN_OR_ZERO, "\"");
for (i = 0; i < entry->nb_args; i++) {
pos += snprintf(buf + pos, LEN_OR_ZERO, "%s: 0x%%0%zulx%s",
entry->args[i], sizeof(unsigned long),
i == entry->nb_args - 1 ? "" : ", ");
}
pos += snprintf(buf + pos, LEN_OR_ZERO, "\"");
for (i = 0; i < entry->nb_args; i++) {
pos += snprintf(buf + pos, LEN_OR_ZERO,
", ((unsigned long)(REC->%s))", entry->args[i]);
}
#undef LEN_OR_ZERO
/* return the length of print_fmt */
return pos;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Lai Jiangshan | 156 | 99.36% | 1 | 50.00% |
Li Zefan | 1 | 0.64% | 1 | 50.00% |
Total | 157 | 100.00% | 2 | 100.00% |
static int __init set_syscall_print_fmt(struct trace_event_call *call)
{
char *print_fmt;
int len;
struct syscall_metadata *entry = call->data;
if (entry->enter_event != call) {
call->print_fmt = "\"0x%lx\", REC->ret";
return 0;
}
/* First: called with 0 length to calculate the needed length */
len = __set_enter_print_fmt(entry, NULL, 0);
print_fmt = kmalloc(len + 1, GFP_KERNEL);
if (!print_fmt)
return -ENOMEM;
/* Second: actually write the @print_fmt */
__set_enter_print_fmt(entry, print_fmt, len + 1);
call->print_fmt = print_fmt;
return 0;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Lai Jiangshan | 98 | 98.00% | 1 | 33.33% |
Steven Rostedt | 1 | 1.00% | 1 | 33.33% |
Li Zefan | 1 | 1.00% | 1 | 33.33% |
Total | 100 | 100.00% | 3 | 100.00% |
static void __init free_syscall_print_fmt(struct trace_event_call *call)
{
struct syscall_metadata *entry = call->data;
if (entry->enter_event == call)
kfree(call->print_fmt);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Lai Jiangshan | 34 | 94.44% | 1 | 33.33% |
Steven Rostedt | 1 | 2.78% | 1 | 33.33% |
Li Zefan | 1 | 2.78% | 1 | 33.33% |
Total | 36 | 100.00% | 3 | 100.00% |
static int __init syscall_enter_define_fields(struct trace_event_call *call)
{
struct syscall_trace_enter trace;
struct syscall_metadata *meta = call->data;
int ret;
int i;
int offset = offsetof(typeof(trace), args);
ret = trace_define_field(call, SYSCALL_FIELD(int, nr, __syscall_nr),
FILTER_OTHER);
if (ret)
return ret;
for (i = 0; i < meta->nb_args; i++) {
ret = trace_define_field(call, meta->types[i],
meta->args[i], offset,
sizeof(unsigned long), 0,
FILTER_OTHER);
offset += sizeof(unsigned long);
}
return ret;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Li Zefan | 101 | 77.69% | 3 | 37.50% |
Lai Jiangshan | 25 | 19.23% | 2 | 25.00% |
Taeung Song | 2 | 1.54% | 1 | 12.50% |
Steven Rostedt | 2 | 1.54% | 2 | 25.00% |
Total | 130 | 100.00% | 8 | 100.00% |
static int __init syscall_exit_define_fields(struct trace_event_call *call)
{
struct syscall_trace_exit trace;
int ret;
ret = trace_define_field(call, SYSCALL_FIELD(int, nr, __syscall_nr),
FILTER_OTHER);
if (ret)
return ret;
ret = trace_define_field(call, SYSCALL_FIELD(long, ret, ret),
FILTER_OTHER);
return ret;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Li Zefan | 34 | 52.31% | 3 | 37.50% |
Lai Jiangshan | 23 | 35.38% | 1 | 12.50% |
Taeung Song | 4 | 6.15% | 1 | 12.50% |
Tom Zanussi | 2 | 3.08% | 1 | 12.50% |
Steven Rostedt | 2 | 3.08% | 2 | 25.00% |
Total | 65 | 100.00% | 8 | 100.00% |
static void ftrace_syscall_enter(void *data, struct pt_regs *regs, long id)
{
struct trace_array *tr = data;
struct trace_event_file *trace_file;
struct syscall_trace_enter *entry;
struct syscall_metadata *sys_data;
struct ring_buffer_event *event;
struct ring_buffer *buffer;
unsigned long irq_flags;
int pc;
int syscall_nr;
int size;
syscall_nr = trace_get_syscall_nr(current, regs);
if (syscall_nr < 0 || syscall_nr >= NR_syscalls)
return;
/* Here we're inside tp handler's rcu_read_lock_sched (__DO_TRACE) */
trace_file = rcu_dereference_sched(tr->enter_syscall_files[syscall_nr]);
if (!trace_file)
return;
if (trace_trigger_soft_disabled(trace_file))
return;
sys_data = syscall_nr_to_meta(syscall_nr);
if (!sys_data)
return;
size = sizeof(*entry) + sizeof(unsigned long) * sys_data->nb_args;
local_save_flags(irq_flags);
pc = preempt_count();
buffer = tr->trace_buffer.buffer;
event = trace_buffer_lock_reserve(buffer,
sys_data->enter_event->event.type, size, irq_flags, pc);
if (!event)
return;
entry = ring_buffer_event_data(event);
entry->nr = syscall_nr;
syscall_get_arguments(current, regs, 0, sys_data->nb_args, entry->args);
event_trigger_unlock_commit(trace_file, buffer, event, entry,
irq_flags, pc);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Frédéric Weisbecker | 116 | 50.22% | 2 | 9.09% |
Steven Rostedt | 41 | 17.75% | 9 | 40.91% |
Tom Zanussi | 26 | 11.26% | 3 | 13.64% |
Jovi Zhangwei | 21 | 9.09% | 1 | 4.55% |
Jason Baron | 10 | 4.33% | 2 | 9.09% |
Hendrik Brueckner | 7 | 3.03% | 1 | 4.55% |
Rabin Vincent | 4 | 1.73% | 1 | 4.55% |
Li Zefan | 3 | 1.30% | 1 | 4.55% |
Lai Jiangshan | 2 | 0.87% | 1 | 4.55% |
Fengguang Wu | 1 | 0.43% | 1 | 4.55% |
Total | 231 | 100.00% | 22 | 100.00% |
static void ftrace_syscall_exit(void *data, struct pt_regs *regs, long ret)
{
struct trace_array *tr = data;
struct trace_event_file *trace_file;
struct syscall_trace_exit *entry;
struct syscall_metadata *sys_data;
struct ring_buffer_event *event;
struct ring_buffer *buffer;
unsigned long irq_flags;
int pc;
int syscall_nr;
syscall_nr = trace_get_syscall_nr(current, regs);
if (syscall_nr < 0 || syscall_nr >= NR_syscalls)
return;
/* Here we're inside tp handler's rcu_read_lock_sched (__DO_TRACE()) */
trace_file = rcu_dereference_sched(tr->exit_syscall_files[syscall_nr]);
if (!trace_file)
return;
if (trace_trigger_soft_disabled(trace_file))
return;
sys_data = syscall_nr_to_meta(syscall_nr);
if (!sys_data)
return;
local_save_flags(irq_flags);
pc = preempt_count();
buffer = tr->trace_buffer.buffer;
event = trace_buffer_lock_reserve(buffer,
sys_data->exit_event->event.type, sizeof(*entry),
irq_flags, pc);
if (!event)
return;
entry = ring_buffer_event_data(event);
entry->nr = syscall_nr;
entry->ret = syscall_get_return_value(current, regs);
event_trigger_unlock_commit(trace_file, buffer, event, entry,
irq_flags, pc);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Frédéric Weisbecker | 95 | 45.67% | 2 | 9.09% |
Steven Rostedt | 39 | 18.75% | 9 | 40.91% |
Tom Zanussi | 26 | 12.50% | 3 | 13.64% |
Jovi Zhangwei | 21 | 10.10% | 1 | 4.55% |
Jason Baron | 10 | 4.81% | 2 | 9.09% |
Hendrik Brueckner | 7 | 3.37% | 1 | 4.55% |
Rabin Vincent | 4 | 1.92% | 1 | 4.55% |
Li Zefan | 3 | 1.44% | 1 | 4.55% |
Lai Jiangshan | 2 | 0.96% | 1 | 4.55% |
Fengguang Wu | 1 | 0.48% | 1 | 4.55% |
Total | 208 | 100.00% | 22 | 100.00% |
static int reg_event_syscall_enter(struct trace_event_file *file,
struct trace_event_call *call)
{
struct trace_array *tr = file->tr;
int ret = 0;
int num;
num = ((struct syscall_metadata *)call->data)->syscall_nr;
if (WARN_ON_ONCE(num < 0 || num >= NR_syscalls))
return -ENOSYS;
mutex_lock(&syscall_trace_lock);
if (!tr->sys_refcount_enter)
ret = register_trace_sys_enter(ftrace_syscall_enter, tr);
if (!ret) {
rcu_assign_pointer(tr->enter_syscall_files[num], file);
tr->sys_refcount_enter++;
}
mutex_unlock(&syscall_trace_lock);
return ret;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Jason Baron | 60 | 50.00% | 2 | 12.50% |
Steven Rostedt | 23 | 19.17% | 4 | 25.00% |
Frédéric Weisbecker | 12 | 10.00% | 2 | 12.50% |
Tom Zanussi | 7 | 5.83% | 1 | 6.25% |
Lai Jiangshan | 7 | 5.83% | 2 | 12.50% |
Masami Hiramatsu | 5 | 4.17% | 1 | 6.25% |
Ian Munsie | 3 | 2.50% | 1 | 6.25% |
Li Zefan | 1 | 0.83% | 1 | 6.25% |
Josh Stone | 1 | 0.83% | 1 | 6.25% |
Fengguang Wu | 1 | 0.83% | 1 | 6.25% |
Total | 120 | 100.00% | 16 | 100.00% |
static void unreg_event_syscall_enter(struct trace_event_file *file,
struct trace_event_call *call)
{
struct trace_array *tr = file->tr;
int num;
num = ((struct syscall_metadata *)call->data)->syscall_nr;
if (WARN_ON_ONCE(num < 0 || num >= NR_syscalls))
return;
mutex_lock(&syscall_trace_lock);
tr->sys_refcount_enter--;
RCU_INIT_POINTER(tr->enter_syscall_files[num], NULL);
if (!tr->sys_refcount_enter)
unregister_trace_sys_enter(ftrace_syscall_enter, tr);
mutex_unlock(&syscall_trace_lock);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Jason Baron | 49 | 49.00% | 2 | 12.50% |
Steven Rostedt | 23 | 23.00% | 4 | 25.00% |
Lai Jiangshan | 7 | 7.00% | 2 | 12.50% |
Tom Zanussi | 6 | 6.00% | 1 | 6.25% |
Masami Hiramatsu | 5 | 5.00% | 1 | 6.25% |
Frédéric Weisbecker | 4 | 4.00% | 2 | 12.50% |
Ian Munsie | 3 | 3.00% | 1 | 6.25% |
Andreea-Cristina Bernat | 1 | 1.00% | 1 | 6.25% |
Fengguang Wu | 1 | 1.00% | 1 | 6.25% |
Josh Stone | 1 | 1.00% | 1 | 6.25% |
Total | 100 | 100.00% | 16 | 100.00% |
static int reg_event_syscall_exit(struct trace_event_file *file,
struct trace_event_call *call)
{
struct trace_array *tr = file->tr;
int ret = 0;
int num;
num = ((struct syscall_metadata *)call->data)->syscall_nr;
if (WARN_ON_ONCE(num < 0 || num >= NR_syscalls))
return -ENOSYS;
mutex_lock(&syscall_trace_lock);
if (!tr->sys_refcount_exit)
ret = register_trace_sys_exit(ftrace_syscall_exit, tr);
if (!ret) {
rcu_assign_pointer(tr->exit_syscall_files[num], file);
tr->sys_refcount_exit++;
}
mutex_unlock(&syscall_trace_lock);
return ret;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Jason Baron | 46 | 38.33% | 2 | 13.33% |
Steven Rostedt | 23 | 19.17% | 4 | 26.67% |
Frédéric Weisbecker | 23 | 19.17% | 1 | 6.67% |
Lai Jiangshan | 10 | 8.33% | 2 | 13.33% |
Tom Zanussi | 7 | 5.83% | 1 | 6.67% |
Masami Hiramatsu | 5 | 4.17% | 1 | 6.67% |
Ian Munsie | 3 | 2.50% | 1 | 6.67% |
Li Zefan | 1 | 0.83% | 1 | 6.67% |
Josh Stone | 1 | 0.83% | 1 | 6.67% |
Fengguang Wu | 1 | 0.83% | 1 | 6.67% |
Total | 120 | 100.00% | 15 | 100.00% |
static void unreg_event_syscall_exit(struct trace_event_file *file,
struct trace_event_call *call)
{
struct trace_array *tr = file->tr;
int num;
num = ((struct syscall_metadata *)call->data)->syscall_nr;
if (WARN_ON_ONCE(num < 0 || num >= NR_syscalls))
return;
mutex_lock(&syscall_trace_lock);
tr->sys_refcount_exit--;
RCU_INIT_POINTER(tr->exit_syscall_files[num], NULL);
if (!tr->sys_refcount_exit)
unregister_trace_sys_exit(ftrace_syscall_exit, tr);
mutex_unlock(&syscall_trace_lock);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Jason Baron | 36 | 36.00% | 2 | 13.33% |
Steven Rostedt | 23 | 23.00% | 4 | 26.67% |
Frédéric Weisbecker | 14 | 14.00% | 1 | 6.67% |
Lai Jiangshan | 10 | 10.00% | 2 | 13.33% |
Tom Zanussi | 6 | 6.00% | 1 | 6.67% |
Masami Hiramatsu | 5 | 5.00% | 1 | 6.67% |
Ian Munsie | 3 | 3.00% | 1 | 6.67% |
Fengguang Wu | 1 | 1.00% | 1 | 6.67% |
Josh Stone | 1 | 1.00% | 1 | 6.67% |
Andreea-Cristina Bernat | 1 | 1.00% | 1 | 6.67% |
Total | 100 | 100.00% | 15 | 100.00% |
static int __init init_syscall_trace(struct trace_event_call *call)
{
int id;
int num;
num = ((struct syscall_metadata *)call->data)->syscall_nr;
if (num < 0 || num >= NR_syscalls) {
pr_debug("syscall %s metadata not mapped, disabling ftrace event\n",
((struct syscall_metadata *)call->data)->name);
return -ENOSYS;
}
if (set_syscall_print_fmt(call) < 0)
return -ENOMEM;
id = trace_event_raw_init(call);
if (id < 0) {
free_syscall_print_fmt(call);
return id;
}
return id;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Ian Munsie | 52 | 49.06% | 1 | 14.29% |
Lai Jiangshan | 46 | 43.40% | 2 | 28.57% |
Steven Rostedt | 6 | 5.66% | 2 | 28.57% |
Li Zefan | 1 | 0.94% | 1 | 14.29% |
Vaibhav Nagarnaik | 1 | 0.94% | 1 | 14.29% |
Total | 106 | 100.00% | 7 | 100.00% |
struct trace_event_functions enter_syscall_print_funcs = {
.trace = print_syscall_enter,
};
struct trace_event_functions exit_syscall_print_funcs = {
.trace = print_syscall_exit,
};
struct trace_event_class __refdata event_class_syscall_enter = {
.system = "syscalls",
.reg = syscall_enter_register,
.define_fields = syscall_enter_define_fields,
.get_fields = syscall_get_enter_fields,
.raw_init = init_syscall_trace,
};
struct trace_event_class __refdata event_class_syscall_exit = {
.system = "syscalls",
.reg = syscall_exit_register,
.define_fields = syscall_exit_define_fields,
.fields = LIST_HEAD_INIT(event_class_syscall_exit.fields),
.raw_init = init_syscall_trace,
};
unsigned long __init __weak arch_syscall_addr(int nr)
{
return (unsigned long)sys_call_table[nr];
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Mike Frysinger | 20 | 95.24% | 1 | 50.00% |
Ian Munsie | 1 | 4.76% | 1 | 50.00% |
Total | 21 | 100.00% | 2 | 100.00% |
void __init init_ftrace_syscalls(void)
{
struct syscall_metadata *meta;
unsigned long addr;
int i;
syscalls_metadata = kcalloc(NR_syscalls, sizeof(*syscalls_metadata),
GFP_KERNEL);
if (!syscalls_metadata) {
WARN_ON(1);
return;
}
for (i = 0; i < NR_syscalls; i++) {
addr = arch_syscall_addr(i);
meta = find_syscall_meta(addr);
if (!meta)
continue;
meta->syscall_nr = i;
syscalls_metadata[i] = meta;
}
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Frédéric Weisbecker | 79 | 82.29% | 1 | 25.00% |
Lai Jiangshan | 12 | 12.50% | 1 | 25.00% |
Thomas Meyer | 3 | 3.12% | 1 | 25.00% |
Steven Rostedt | 2 | 2.08% | 1 | 25.00% |
Total | 96 | 100.00% | 4 | 100.00% |
#ifdef CONFIG_PERF_EVENTS
static DECLARE_BITMAP(enabled_perf_enter_syscalls, NR_syscalls);
static DECLARE_BITMAP(enabled_perf_exit_syscalls, NR_syscalls);
static int sys_perf_refcount_enter;
static int sys_perf_refcount_exit;
static int perf_call_bpf_enter(struct trace_event_call *call, struct pt_regs *regs,
struct syscall_metadata *sys_data,
struct syscall_trace_enter *rec)
{
struct syscall_tp_t {
unsigned long long regs;
unsigned long syscall_nr;
unsigned long args[SYSCALL_DEFINE_MAXARGS];
} param;
int i;
*(struct pt_regs **)¶m = regs;
param.syscall_nr = rec->nr;
for (i = 0; i < sys_data->nb_args; i++)
param.args[i] = rec->args[i];
return trace_call_bpf(call, ¶m);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Yonghong Song | 109 | 100.00% | 3 | 100.00% |
Total | 109 | 100.00% | 3 | 100.00% |
static void perf_syscall_enter(void *ignore, struct pt_regs *regs, long id)
{
struct syscall_metadata *sys_data;
struct syscall_trace_enter *rec;
struct hlist_head *head;
bool valid_prog_array;
int syscall_nr;
int rctx;
int size;
syscall_nr = trace_get_syscall_nr(current, regs);
if (syscall_nr < 0 || syscall_nr >= NR_syscalls)
return;
if (!test_bit(syscall_nr, enabled_perf_enter_syscalls))
return;
sys_data = syscall_nr_to_meta(syscall_nr);
if (!sys_data)
return;
head = this_cpu_ptr(sys_data->enter_event->perf_events);
valid_prog_array = bpf_prog_array_valid(sys_data->enter_event);
if (!valid_prog_array && hlist_empty(head))
return;
/* get the size after alignment with the u32 buffer size field */
size = sizeof(unsigned long) * sys_data->nb_args + sizeof(*rec);
size = ALIGN(size + sizeof(u32), sizeof(u64));
size -= sizeof(u32);
rec = perf_trace_buf_alloc(size, NULL, &rctx);
if (!rec)
return;
rec->nr = syscall_nr;
syscall_get_arguments(current, regs, 0, sys_data->nb_args,
(unsigned long *)&rec->args);
if ((valid_prog_array &&
!perf_call_bpf_enter(sys_data->enter_event, regs, sys_data, rec)) ||
hlist_empty(head)) {
perf_swevent_put_recursion_context(rctx);
return;
}
perf_trace_buf_submit(rec, size, rctx,
sys_data->enter_event->event.type, 1, regs,
head, NULL);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Frédéric Weisbecker | 92 | 34.33% | 5 | 22.73% |
Yonghong Song | 52 | 19.40% | 2 | 9.09% |
Jason Baron | 51 | 19.03% | 1 | 4.55% |
Oleg Nesterov | 15 | 5.60% | 1 | 4.55% |
Xiao Guangrong | 15 | 5.60% | 1 | 4.55% |
Peter Zijlstra | 10 | 3.73% | 5 | 22.73% |
Alexei Starovoitov | 8 | 2.99% | 1 | 4.55% |
Will Deacon | 7 | 2.61% | 1 | 4.55% |
Li Zefan | 7 | 2.61% | 1 | 4.55% |
Steven Rostedt | 5 | 1.87% | 2 | 9.09% |
Rabin Vincent | 4 | 1.49% | 1 | 4.55% |
Andrey Vagin | 2 | 0.75% | 1 | 4.55% |
Total | 268 | 100.00% | 22 | 100.00% |
static int perf_sysenter_enable(struct trace_event_call *call)
{
int ret = 0;
int num;
num = ((struct syscall_metadata *)call->data)->syscall_nr;
mutex_lock(&syscall_trace_lock);
if (!sys_perf_refcount_enter)
ret = register_trace_sys_enter(perf_syscall_enter, NULL);
if (ret) {
pr_info("event trace: Could not activate syscall entry trace point");
} else {
set_bit(num, enabled_perf_enter_syscalls);
sys_perf_refcount_enter++;
}
mutex_unlock(&syscall_trace_lock);
return ret;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Jason Baron | 62 | 71.26% | 1 | 12.50% |
Lai Jiangshan | 14 | 16.09% | 1 | 12.50% |
Frédéric Weisbecker | 5 | 5.75% | 1 | 12.50% |
Steven Rostedt | 3 | 3.45% | 2 | 25.00% |
Vaibhav Nagarnaik | 1 | 1.15% | 1 | 12.50% |
Colin Ian King | 1 | 1.15% | 1 | 12.50% |
Josh Stone | 1 | 1.15% | 1 | 12.50% |
Total | 87 | 100.00% | 8 | 100.00% |
static void perf_sysenter_disable(struct trace_event_call *call)
{
int num;
num = ((struct syscall_metadata *)call->data)->syscall_nr;
mutex_lock(&syscall_trace_lock);
sys_perf_refcount_enter--;
clear_bit(num, enabled_perf_enter_syscalls);
if (!sys_perf_refcount_enter)
unregister_trace_sys_enter(perf_syscall_enter, NULL);
mutex_unlock(&syscall_trace_lock);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Jason Baron | 39 | 61.90% | 1 | 14.29% |
Lai Jiangshan | 14 | 22.22% | 1 | 14.29% |
Frédéric Weisbecker | 5 | 7.94% | 1 | 14.29% |
Steven Rostedt | 3 | 4.76% | 2 | 28.57% |
Vaibhav Nagarnaik | 1 | 1.59% | 1 | 14.29% |
Josh Stone | 1 | 1.59% | 1 | 14.29% |
Total | 63 | 100.00% | 7 | 100.00% |
static int perf_call_bpf_exit(struct trace_event_call *call, struct pt_regs *regs,
struct syscall_trace_exit *rec)
{
struct syscall_tp_t {
unsigned long long regs;
unsigned long syscall_nr;
unsigned long ret;
} param;
*(struct pt_regs **)¶m = regs;
param.syscall_nr = rec->nr;
param.ret = rec->ret;
return trace_call_bpf(call, ¶m);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Yonghong Song | 77 | 100.00% | 2 | 100.00% |
Total | 77 | 100.00% | 2 | 100.00% |
static void perf_syscall_exit(void *ignore, struct pt_regs *regs, long ret)
{
struct syscall_metadata *sys_data;
struct syscall_trace_exit *rec;
struct hlist_head *head;
bool valid_prog_array;
int syscall_nr;
int rctx;
int size;
syscall_nr = trace_get_syscall_nr(current, regs);
if (syscall_nr < 0 || syscall_nr >= NR_syscalls)
return;
if (!test_bit(syscall_nr, enabled_perf_exit_syscalls))
return;
sys_data = syscall_nr_to_meta(syscall_nr);
if (!sys_data)
return;
head = this_cpu_ptr(sys_data->exit_event->perf_events);
valid_prog_array = bpf_prog_array_valid(sys_data->exit_event);
if (!valid_prog_array && hlist_empty(head))
return;
/* We can probably do that at build time */
size = ALIGN(sizeof(*rec) + sizeof(u32), sizeof(u64));
size -= sizeof(u32);
rec = perf_trace_buf_alloc(size, NULL, &rctx);
if (!rec)
return;
rec->nr = syscall_nr;
rec->ret = syscall_get_return_value(current, regs);
if ((valid_prog_array &&
!perf_call_bpf_exit(sys_data->exit_event, regs, rec)) ||
hlist_empty(head)) {
perf_swevent_put_recursion_context(rctx);
return;
}
perf_trace_buf_submit(rec, size, rctx, sys_data->exit_event->event.type,
1, regs, head, NULL);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Frédéric Weisbecker | 60 | 25.00% | 5 | 22.73% |
Jason Baron | 59 | 24.58% | 1 | 4.55% |
Yonghong Song | 50 | 20.83% | 2 | 9.09% |
Xiao Guangrong | 15 | 6.25% | 1 | 4.55% |
Oleg Nesterov | 15 | 6.25% | 1 | 4.55% |
Peter Zijlstra | 9 | 3.75% | 5 | 22.73% |
Alexei Starovoitov | 8 | 3.33% | 1 | 4.55% |
Will Deacon | 7 | 2.92% | 1 | 4.55% |
Li Zefan | 6 | 2.50% | 1 | 4.55% |
Steven Rostedt | 5 | 2.08% | 2 | 9.09% |
Rabin Vincent | 4 | 1.67% | 1 | 4.55% |
Andrey Vagin | 2 | 0.83% | 1 | 4.55% |
Total | 240 | 100.00% | 22 | 100.00% |
static int perf_sysexit_enable(struct trace_event_call *call)
{
int ret = 0;
int num;
num = ((struct syscall_metadata *)call->data)->syscall_nr;
mutex_lock(&syscall_trace_lock);
if (!sys_perf_refcount_exit)
ret = register_trace_sys_exit(perf_syscall_exit, NULL);
if (ret) {
pr_info("event trace: Could not activate syscall exit trace point");
} else {
set_bit(num, enabled_perf_exit_syscalls);
sys_perf_refcount_exit++;
}
mutex_unlock(&syscall_trace_lock);
return ret;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Jason Baron | 62 | 71.26% | 1 | 12.50% |
Lai Jiangshan | 14 | 16.09% | 1 | 12.50% |
Frédéric Weisbecker | 5 | 5.75% | 1 | 12.50% |
Steven Rostedt | 3 | 3.45% | 2 | 25.00% |
Josh Stone | 1 | 1.15% | 1 | 12.50% |
Colin Ian King | 1 | 1.15% | 1 | 12.50% |
Vaibhav Nagarnaik | 1 | 1.15% | 1 | 12.50% |
Total | 87 | 100.00% | 8 | 100.00% |
static void perf_sysexit_disable(struct trace_event_call *call)
{
int num;
num = ((struct syscall_metadata *)call->data)->syscall_nr;
mutex_lock(&syscall_trace_lock);
sys_perf_refcount_exit--;
clear_bit(num, enabled_perf_exit_syscalls);
if (!sys_perf_refcount_exit)
unregister_trace_sys_exit(perf_syscall_exit, NULL);
mutex_unlock(&syscall_trace_lock);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Jason Baron | 39 | 61.90% | 1 | 14.29% |
Lai Jiangshan | 14 | 22.22% | 1 | 14.29% |
Frédéric Weisbecker | 5 | 7.94% | 1 | 14.29% |
Steven Rostedt | 3 | 4.76% | 2 | 28.57% |
Vaibhav Nagarnaik | 1 | 1.59% | 1 | 14.29% |
Josh Stone | 1 | 1.59% | 1 | 14.29% |
Total | 63 | 100.00% | 7 | 100.00% |
#endif /* CONFIG_PERF_EVENTS */
static int syscall_enter_register(struct trace_event_call *event,
enum trace_reg type, void *data)
{
struct trace_event_file *file = data;
switch (type) {
case TRACE_REG_REGISTER:
return reg_event_syscall_enter(file, event);
case TRACE_REG_UNREGISTER:
unreg_event_syscall_enter(file, event);
return 0;
#ifdef CONFIG_PERF_EVENTS
case TRACE_REG_PERF_REGISTER:
return perf_sysenter_enable(event);
case TRACE_REG_PERF_UNREGISTER:
perf_sysenter_disable(event);
return 0;
case TRACE_REG_PERF_OPEN:
case TRACE_REG_PERF_CLOSE:
case TRACE_REG_PERF_ADD:
case TRACE_REG_PERF_DEL:
return 0;
#endif
}
return 0;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Steven Rostedt | 80 | 80.81% | 4 | 66.67% |
Jiri Olsa | 19 | 19.19% | 2 | 33.33% |
Total | 99 | 100.00% | 6 | 100.00% |
static int syscall_exit_register(struct trace_event_call *event,
enum trace_reg type, void *data)
{
struct trace_event_file *file = data;
switch (type) {
case TRACE_REG_REGISTER:
return reg_event_syscall_exit(file, event);
case TRACE_REG_UNREGISTER:
unreg_event_syscall_exit(file, event);
return 0;
#ifdef CONFIG_PERF_EVENTS
case TRACE_REG_PERF_REGISTER:
return perf_sysexit_enable(event);
case TRACE_REG_PERF_UNREGISTER:
perf_sysexit_disable(event);
return 0;
case TRACE_REG_PERF_OPEN:
case TRACE_REG_PERF_CLOSE:
case TRACE_REG_PERF_ADD:
case TRACE_REG_PERF_DEL:
return 0;
#endif
}
return 0;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Steven Rostedt | 80 | 80.81% | 4 | 66.67% |
Jiri Olsa | 19 | 19.19% | 2 | 33.33% |
Total | 99 | 100.00% | 6 | 100.00% |
Overall Contributors
Person | Tokens | Prop | Commits | CommitProp |
Frédéric Weisbecker | 892 | 24.12% | 10 | 10.87% |
Jason Baron | 608 | 16.44% | 4 | 4.35% |
Steven Rostedt | 582 | 15.74% | 18 | 19.57% |
Lai Jiangshan | 492 | 13.30% | 7 | 7.61% |
Yonghong Song | 288 | 7.79% | 3 | 3.26% |
Li Zefan | 196 | 5.30% | 10 | 10.87% |
Ian Munsie | 115 | 3.11% | 5 | 5.43% |
Tom Zanussi | 115 | 3.11% | 5 | 5.43% |
Vaibhav Nagarnaik | 92 | 2.49% | 1 | 1.09% |
Jiri Olsa | 46 | 1.24% | 2 | 2.17% |
Jovi Zhangwei | 45 | 1.22% | 3 | 3.26% |
Oleg Nesterov | 30 | 0.81% | 1 | 1.09% |
Xiao Guangrong | 30 | 0.81% | 1 | 1.09% |
Masami Hiramatsu | 20 | 0.54% | 1 | 1.09% |
Mike Frysinger | 20 | 0.54% | 1 | 1.09% |
Peter Zijlstra | 19 | 0.51% | 5 | 5.43% |
Alexei Starovoitov | 16 | 0.43% | 1 | 1.09% |
Rabin Vincent | 16 | 0.43% | 1 | 1.09% |
Hendrik Brueckner | 14 | 0.38% | 1 | 1.09% |
Will Deacon | 14 | 0.38% | 1 | 1.09% |
Josh Stone | 11 | 0.30% | 1 | 1.09% |
Taeung Song | 9 | 0.24% | 1 | 1.09% |
Fengguang Wu | 8 | 0.22% | 1 | 1.09% |
Andrey Vagin | 4 | 0.11% | 1 | 1.09% |
Paul Gortmaker | 4 | 0.11% | 1 | 1.09% |
Tejun Heo | 3 | 0.08% | 1 | 1.09% |
Thomas Meyer | 3 | 0.08% | 1 | 1.09% |
Colin Ian King | 2 | 0.05% | 1 | 1.09% |
Andreea-Cristina Bernat | 2 | 0.05% | 1 | 1.09% |
Greg Kroah-Hartman | 1 | 0.03% | 1 | 1.09% |
Ingo Molnar | 1 | 0.03% | 1 | 1.09% |
Total | 3698 | 100.00% | 92 | 100.00% |
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.