Refactoring: event structures
[lttng-modules.git] / src / lttng-syscalls.c
CommitLineData
b7cdc182 1/* SPDX-License-Identifier: (GPL-2.0-only or LGPL-2.1-only)
9f36eaed 2 *
259b6cb3
MD
3 * lttng-syscalls.c
4 *
2faf7d1b 5 * LTTng syscall probes.
259b6cb3 6 *
886d51a3 7 * Copyright (C) 2010-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
259b6cb3
MD
8 */
9
10#include <linux/module.h>
11#include <linux/slab.h>
6333ace3 12#include <linux/compat.h>
abc0446a 13#include <linux/err.h>
80f87dd2 14#include <linux/bitmap.h>
7ca580f8
MD
15#include <linux/in.h>
16#include <linux/in6.h>
2d2464bd 17#include <linux/seq_file.h>
d4291869 18#include <linux/stringify.h>
082d4946
MD
19#include <linux/file.h>
20#include <linux/anon_inodes.h>
c8dfb724 21#include <linux/fcntl.h>
3cf55950 22#include <linux/mman.h>
259b6cb3
MD
23#include <asm/ptrace.h>
24#include <asm/syscall.h>
25
a071f25d 26#include <lttng/bitfield.h>
241ae9a8
MD
27#include <wrapper/tracepoint.h>
28#include <wrapper/file.h>
29#include <wrapper/rcu.h>
1b7b9c65 30#include <wrapper/syscall.h>
2df37e95 31#include <lttng/events.h>
8a8ac9a8 32#include <lttng/utils.h>
259b6cb3 33
6333ace3 34#ifndef CONFIG_COMPAT
bfa949bf
MD
35# ifndef is_compat_task
36# define is_compat_task() (0)
37# endif
6333ace3
MD
38#endif
39
1aa3298b
MD
40/* in_compat_syscall appears in kernel 4.6. */
41#ifndef in_compat_syscall
42 #define in_compat_syscall() is_compat_task()
43#endif
44
5b7ac358
MD
45enum sc_type {
46 SC_TYPE_ENTRY,
47 SC_TYPE_EXIT,
48 SC_TYPE_COMPAT_ENTRY,
49 SC_TYPE_COMPAT_EXIT,
50};
51
d4291869
MD
52#define SYSCALL_ENTRY_TOK syscall_entry_
53#define COMPAT_SYSCALL_ENTRY_TOK compat_syscall_entry_
54#define SYSCALL_EXIT_TOK syscall_exit_
55#define COMPAT_SYSCALL_EXIT_TOK compat_syscall_exit_
56
57#define SYSCALL_ENTRY_STR __stringify(SYSCALL_ENTRY_TOK)
58#define COMPAT_SYSCALL_ENTRY_STR __stringify(COMPAT_SYSCALL_ENTRY_TOK)
59#define SYSCALL_EXIT_STR __stringify(SYSCALL_EXIT_TOK)
60#define COMPAT_SYSCALL_EXIT_STR __stringify(COMPAT_SYSCALL_EXIT_TOK)
5b7ac358 61
a93244f8 62static
2d6d88c6 63void syscall_entry_event_probe(void *__data, struct pt_regs *regs, long id);
5b7ac358 64static
2d6d88c6 65void syscall_exit_event_probe(void *__data, struct pt_regs *regs, long ret);
259b6cb3 66
8a8ac9a8
FD
67static
68void syscall_entry_event_notifier_probe(void *__data, struct pt_regs *regs,
69 long id);
70static
71void syscall_exit_event_notifier_probe(void *__data, struct pt_regs *regs,
72 long ret);
73
3a523f5b
MD
74/*
75 * Forward declarations for old kernels.
76 */
77struct mmsghdr;
78struct rlimit64;
79struct oldold_utsname;
80struct old_utsname;
81struct sel_arg_struct;
82struct mmap_arg_struct;
c0b71117 83struct file_handle;
a292e6f1 84struct user_msghdr;
3a523f5b 85
9eb15e8b
MJ
86/*
87 * Forward declaration for kernels >= 5.6
88 */
89struct timex;
edfdcb68
MJ
90struct timeval;
91struct itimerval;
92struct itimerspec;
93
5f4c791e 94#if (LTTNG_LINUX_VERSION_CODE >= LTTNG_KERNEL_VERSION(5,6,0))
edfdcb68
MJ
95typedef __kernel_old_time_t time_t;
96#endif
9eb15e8b 97
80f87dd2
MD
98#ifdef IA32_NR_syscalls
99#define NR_compat_syscalls IA32_NR_syscalls
100#else
101#define NR_compat_syscalls NR_syscalls
102#endif
103
259b6cb3
MD
104/*
105 * Create LTTng tracepoint probes.
106 */
107#define LTTNG_PACKAGE_BUILD
108#define CREATE_TRACE_POINTS
2655f9ad 109#define TP_MODULE_NOINIT
c075712b 110#define TRACE_INCLUDE_PATH instrumentation/syscalls/headers
259b6cb3 111
a93244f8
MD
112#define PARAMS(args...) args
113
5b7ac358 114/* Handle unknown syscalls */
72a52753 115#undef TRACE_SYSTEM
5b7ac358 116#define TRACE_SYSTEM syscalls_unknown
241ae9a8 117#include <instrumentation/syscalls/headers/syscalls_unknown.h>
5b7ac358
MD
118#undef TRACE_SYSTEM
119
fc4f7161
MD
120#define SC_ENTER
121
fc4f7161
MD
122#undef sc_exit
123#define sc_exit(...)
b75d00c4
MD
124#undef sc_in
125#define sc_in(...) __VA_ARGS__
126#undef sc_out
127#define sc_out(...)
128#undef sc_inout
129#define sc_inout(...) __VA_ARGS__
5b7ac358
MD
130
131/* Hijack probe callback for system call enter */
a93244f8 132#undef TP_PROBE_CB
2d6d88c6 133#define TP_PROBE_CB(_template) &syscall_entry_event_probe
57ede728 134#define SC_LTTNG_TRACEPOINT_EVENT(_name, _proto, _args, _fields) \
d4291869 135 LTTNG_TRACEPOINT_EVENT(syscall_entry_##_name, PARAMS(_proto), PARAMS(_args), \
57ede728 136 PARAMS(_fields))
265822ae 137#define SC_LTTNG_TRACEPOINT_EVENT_CODE(_name, _proto, _args, _locvar, _code_pre, _fields, _code_post) \
d4291869 138 LTTNG_TRACEPOINT_EVENT_CODE(syscall_entry_##_name, PARAMS(_proto), PARAMS(_args), \
265822ae
MD
139 PARAMS(_locvar), PARAMS(_code_pre), \
140 PARAMS(_fields), PARAMS(_code_post))
57ede728
MD
141#define SC_LTTNG_TRACEPOINT_EVENT_CLASS_NOARGS(_name, _fields) \
142 LTTNG_TRACEPOINT_EVENT_CLASS_NOARGS(syscall_entry_##_name, PARAMS(_fields))
cb3ef14c 143#define SC_LTTNG_TRACEPOINT_EVENT_INSTANCE_NOARGS(_template, _name) \
d4291869 144 LTTNG_TRACEPOINT_EVENT_INSTANCE_NOARGS(syscall_entry_##_template, syscall_entry_##_name)
141ddf28
MD
145/* Enumerations only defined at first inclusion. */
146#define SC_LTTNG_TRACEPOINT_ENUM(_name, _values) \
147 LTTNG_TRACEPOINT_ENUM(_name, PARAMS(_values))
a93244f8 148#undef TRACE_SYSTEM
d4291869 149#define TRACE_SYSTEM syscall_entry_integers
5b7ac358 150#define TRACE_INCLUDE_FILE syscalls_integers
241ae9a8 151#include <instrumentation/syscalls/headers/syscalls_integers.h>
5b7ac358 152#undef TRACE_INCLUDE_FILE
a93244f8 153#undef TRACE_SYSTEM
d4291869 154#define TRACE_SYSTEM syscall_entry_pointers
5b7ac358 155#define TRACE_INCLUDE_FILE syscalls_pointers
241ae9a8 156#include <instrumentation/syscalls/headers/syscalls_pointers.h>
5b7ac358 157#undef TRACE_INCLUDE_FILE
a93244f8 158#undef TRACE_SYSTEM
141ddf28 159#undef SC_LTTNG_TRACEPOINT_ENUM
cb3ef14c
MD
160#undef SC_LTTNG_TRACEPOINT_EVENT_CODE
161#undef SC_LTTNG_TRACEPOINT_EVENT
162#undef SC_LTTNG_TRACEPOINT_EVENT_CLASS_NOARGS
163#undef SC_LTTNG_TRACEPOINT_EVENT_INSTANCE_NOARGS
5b7ac358 164#undef TP_PROBE_CB
3bc29f0a
MD
165#undef _TRACE_SYSCALLS_INTEGERS_H
166#undef _TRACE_SYSCALLS_POINTERS_H
5b7ac358
MD
167
168/* Hijack probe callback for compat system call enter */
2d6d88c6 169#define TP_PROBE_CB(_template) &syscall_entry_event_probe
771af27e 170#define LTTNG_SC_COMPAT
57ede728 171#define SC_LTTNG_TRACEPOINT_EVENT(_name, _proto, _args, _fields) \
d4291869 172 LTTNG_TRACEPOINT_EVENT(compat_syscall_entry_##_name, PARAMS(_proto), PARAMS(_args), \
57ede728 173 PARAMS(_fields))
265822ae 174#define SC_LTTNG_TRACEPOINT_EVENT_CODE(_name, _proto, _args, _locvar, _code_pre, _fields, _code_post) \
d4291869 175 LTTNG_TRACEPOINT_EVENT_CODE(compat_syscall_entry_##_name, PARAMS(_proto), PARAMS(_args), \
265822ae 176 PARAMS(_locvar), PARAMS(_code_pre), PARAMS(_fields), PARAMS(_code_post))
57ede728
MD
177#define SC_LTTNG_TRACEPOINT_EVENT_CLASS_NOARGS(_name, _fields) \
178 LTTNG_TRACEPOINT_EVENT_CLASS_NOARGS(compat_syscall_entry_##_name, PARAMS(_fields))
cb3ef14c 179#define SC_LTTNG_TRACEPOINT_EVENT_INSTANCE_NOARGS(_template, _name) \
d4291869
MD
180 LTTNG_TRACEPOINT_EVENT_INSTANCE_NOARGS(compat_syscall_entry_##_template, \
181 compat_syscall_entry_##_name)
141ddf28
MD
182/* Enumerations only defined at inital inclusion (not here). */
183#define SC_LTTNG_TRACEPOINT_ENUM(_name, _values)
d4291869 184#define TRACE_SYSTEM compat_syscall_entry_integers
5b7ac358 185#define TRACE_INCLUDE_FILE compat_syscalls_integers
241ae9a8 186#include <instrumentation/syscalls/headers/compat_syscalls_integers.h>
5b7ac358
MD
187#undef TRACE_INCLUDE_FILE
188#undef TRACE_SYSTEM
d4291869 189#define TRACE_SYSTEM compat_syscall_entry_pointers
5b7ac358 190#define TRACE_INCLUDE_FILE compat_syscalls_pointers
241ae9a8 191#include <instrumentation/syscalls/headers/compat_syscalls_pointers.h>
5b7ac358
MD
192#undef TRACE_INCLUDE_FILE
193#undef TRACE_SYSTEM
141ddf28 194#undef SC_LTTNG_TRACEPOINT_ENUM
cb3ef14c
MD
195#undef SC_LTTNG_TRACEPOINT_EVENT_CODE
196#undef SC_LTTNG_TRACEPOINT_EVENT
197#undef SC_LTTNG_TRACEPOINT_EVENT_CLASS_NOARGS
198#undef SC_LTTNG_TRACEPOINT_EVENT_INSTANCE_NOARGS
5b7ac358 199#undef TP_PROBE_CB
3bc29f0a
MD
200#undef _TRACE_SYSCALLS_INTEGERS_H
201#undef _TRACE_SYSCALLS_POINTERS_H
771af27e 202#undef LTTNG_SC_COMPAT
5b7ac358 203
fc4f7161
MD
204#undef SC_ENTER
205
206#define SC_EXIT
207
fc4f7161
MD
208#undef sc_exit
209#define sc_exit(...) __VA_ARGS__
b75d00c4
MD
210#undef sc_in
211#define sc_in(...)
212#undef sc_out
213#define sc_out(...) __VA_ARGS__
214#undef sc_inout
215#define sc_inout(...) __VA_ARGS__
5b7ac358
MD
216
217/* Hijack probe callback for system call exit */
2d6d88c6 218#define TP_PROBE_CB(_template) &syscall_exit_event_probe
57ede728 219#define SC_LTTNG_TRACEPOINT_EVENT(_name, _proto, _args, _fields) \
3bc29f0a 220 LTTNG_TRACEPOINT_EVENT(syscall_exit_##_name, PARAMS(_proto), PARAMS(_args), \
57ede728 221 PARAMS(_fields))
265822ae 222#define SC_LTTNG_TRACEPOINT_EVENT_CODE(_name, _proto, _args, _locvar, _code_pre, _fields, _code_post) \
3bc29f0a 223 LTTNG_TRACEPOINT_EVENT_CODE(syscall_exit_##_name, PARAMS(_proto), PARAMS(_args), \
265822ae 224 PARAMS(_locvar), PARAMS(_code_pre), PARAMS(_fields), PARAMS(_code_post))
57ede728
MD
225#define SC_LTTNG_TRACEPOINT_EVENT_CLASS_NOARGS(_name, _fields) \
226 LTTNG_TRACEPOINT_EVENT_CLASS_NOARGS(syscall_exit_##_name, PARAMS(_fields))
cb3ef14c
MD
227#define SC_LTTNG_TRACEPOINT_EVENT_INSTANCE_NOARGS(_template, _name) \
228 LTTNG_TRACEPOINT_EVENT_INSTANCE_NOARGS(syscall_exit_##_template, \
5b7ac358 229 syscall_exit_##_name)
141ddf28
MD
230/* Enumerations only defined at inital inclusion (not here). */
231#define SC_LTTNG_TRACEPOINT_ENUM(_name, _values)
5b7ac358
MD
232#define TRACE_SYSTEM syscall_exit_integers
233#define TRACE_INCLUDE_FILE syscalls_integers
241ae9a8 234#include <instrumentation/syscalls/headers/syscalls_integers.h>
5b7ac358
MD
235#undef TRACE_INCLUDE_FILE
236#undef TRACE_SYSTEM
237#define TRACE_SYSTEM syscall_exit_pointers
238#define TRACE_INCLUDE_FILE syscalls_pointers
241ae9a8 239#include <instrumentation/syscalls/headers/syscalls_pointers.h>
5b7ac358
MD
240#undef TRACE_INCLUDE_FILE
241#undef TRACE_SYSTEM
141ddf28 242#undef SC_LTTNG_TRACEPOINT_ENUM
cb3ef14c
MD
243#undef SC_LTTNG_TRACEPOINT_EVENT_CODE
244#undef SC_LTTNG_TRACEPOINT_EVENT
245#undef SC_LTTNG_TRACEPOINT_EVENT_CLASS_NOARGS
246#undef SC_LTTNG_TRACEPOINT_EVENT_INSTANCE_NOARGS
5b7ac358 247#undef TP_PROBE_CB
3bc29f0a
MD
248#undef _TRACE_SYSCALLS_INTEGERS_H
249#undef _TRACE_SYSCALLS_POINTERS_H
5b7ac358
MD
250
251
252/* Hijack probe callback for compat system call exit */
2d6d88c6 253#define TP_PROBE_CB(_template) &syscall_exit_event_probe
771af27e 254#define LTTNG_SC_COMPAT
57ede728 255#define SC_LTTNG_TRACEPOINT_EVENT(_name, _proto, _args, _fields) \
3bc29f0a 256 LTTNG_TRACEPOINT_EVENT(compat_syscall_exit_##_name, PARAMS(_proto), PARAMS(_args), \
57ede728 257 PARAMS(_fields))
265822ae 258#define SC_LTTNG_TRACEPOINT_EVENT_CODE(_name, _proto, _args, _locvar, _code_pre, _fields, _code_post) \
3bc29f0a 259 LTTNG_TRACEPOINT_EVENT_CODE(compat_syscall_exit_##_name, PARAMS(_proto), PARAMS(_args), \
265822ae 260 PARAMS(_locvar), PARAMS(_code_pre), PARAMS(_fields), PARAMS(_code_post))
57ede728
MD
261#define SC_LTTNG_TRACEPOINT_EVENT_CLASS_NOARGS(_name, _fields) \
262 LTTNG_TRACEPOINT_EVENT_CLASS_NOARGS(compat_syscall_exit_##_name, PARAMS(_fields))
cb3ef14c 263#define SC_LTTNG_TRACEPOINT_EVENT_INSTANCE_NOARGS(_template, _name) \
3bc29f0a 264 LTTNG_TRACEPOINT_EVENT_INSTANCE_NOARGS(compat_syscall_exit_##_template, \
5b7ac358 265 compat_syscall_exit_##_name)
141ddf28
MD
266/* Enumerations only defined at inital inclusion (not here). */
267#define SC_LTTNG_TRACEPOINT_ENUM(_name, _values)
5b7ac358
MD
268#define TRACE_SYSTEM compat_syscall_exit_integers
269#define TRACE_INCLUDE_FILE compat_syscalls_integers
241ae9a8 270#include <instrumentation/syscalls/headers/compat_syscalls_integers.h>
5b7ac358 271#undef TRACE_INCLUDE_FILE
a93244f8 272#undef TRACE_SYSTEM
5b7ac358
MD
273#define TRACE_SYSTEM compat_syscall_exit_pointers
274#define TRACE_INCLUDE_FILE compat_syscalls_pointers
241ae9a8 275#include <instrumentation/syscalls/headers/compat_syscalls_pointers.h>
5b7ac358 276#undef TRACE_INCLUDE_FILE
a93244f8 277#undef TRACE_SYSTEM
141ddf28 278#undef SC_LTTNG_TRACEPOINT_ENUM
cb3ef14c
MD
279#undef SC_LTTNG_TRACEPOINT_EVENT_CODE
280#undef SC_LTTNG_TRACEPOINT_EVENT
281#undef SC_LTTNG_TRACEPOINT_EVENT_CLASS_NOARGS
282#undef SC_LTTNG_TRACEPOINT_EVENT_INSTANCE_NOARGS
a93244f8 283#undef TP_PROBE_CB
3bc29f0a
MD
284#undef _TRACE_SYSCALLS_INTEGERS_H
285#undef _TRACE_SYSCALLS_POINTERS_H
771af27e 286#undef LTTNG_SC_COMPAT
5b7ac358 287
fc4f7161 288#undef SC_EXIT
259b6cb3 289
2655f9ad 290#undef TP_MODULE_NOINIT
259b6cb3
MD
291#undef LTTNG_PACKAGE_BUILD
292#undef CREATE_TRACE_POINTS
293
a93244f8 294struct trace_syscall_entry {
2d6d88c6 295 void *event_func;
8a8ac9a8 296 void *event_notifier_func;
437d5aa5
MD
297 const struct lttng_kernel_event_desc *desc;
298 const struct lttng_kernel_event_field **fields;
a93244f8
MD
299 unsigned int nrargs;
300};
301
302#define CREATE_SYSCALL_TABLE
303
fc4f7161
MD
304#define SC_ENTER
305
306#undef sc_exit
307#define sc_exit(...)
308
259b6cb3 309#undef TRACE_SYSCALL_TABLE
f7bdf4db 310#define TRACE_SYSCALL_TABLE(_template, _name, _nr, _nrargs) \
259b6cb3 311 [ _nr ] = { \
2d6d88c6 312 .event_func = __event_probe__syscall_entry_##_template, \
8a8ac9a8 313 .event_notifier_func = __event_notifier_probe__syscall_entry_##_template, \
259b6cb3 314 .nrargs = (_nrargs), \
d4291869
MD
315 .fields = __event_fields___syscall_entry_##_template, \
316 .desc = &__event_desc___syscall_entry_##_name, \
259b6cb3
MD
317 },
318
2d6d88c6 319/* Event syscall enter tracing table */
49c50022 320static const struct trace_syscall_entry sc_table[] = {
241ae9a8
MD
321#include <instrumentation/syscalls/headers/syscalls_integers.h>
322#include <instrumentation/syscalls/headers/syscalls_pointers.h>
259b6cb3
MD
323};
324
a93244f8
MD
325#undef TRACE_SYSCALL_TABLE
326#define TRACE_SYSCALL_TABLE(_template, _name, _nr, _nrargs) \
327 [ _nr ] = { \
2d6d88c6 328 .event_func = __event_probe__compat_syscall_entry_##_template, \
8a8ac9a8 329 .event_notifier_func = __event_notifier_probe__compat_syscall_entry_##_template, \
a93244f8 330 .nrargs = (_nrargs), \
d4291869
MD
331 .fields = __event_fields___compat_syscall_entry_##_template, \
332 .desc = &__event_desc___compat_syscall_entry_##_name, \
a93244f8
MD
333 },
334
2d6d88c6 335/* Event compat syscall enter table */
a93244f8 336const struct trace_syscall_entry compat_sc_table[] = {
241ae9a8
MD
337#include <instrumentation/syscalls/headers/compat_syscalls_integers.h>
338#include <instrumentation/syscalls/headers/compat_syscalls_pointers.h>
a93244f8 339};
259b6cb3 340
fc4f7161
MD
341#undef SC_ENTER
342
343#define SC_EXIT
344
345#undef sc_exit
346#define sc_exit(...) __VA_ARGS__
347
5b7ac358
MD
348#undef TRACE_SYSCALL_TABLE
349#define TRACE_SYSCALL_TABLE(_template, _name, _nr, _nrargs) \
350 [ _nr ] = { \
2d6d88c6 351 .event_func = __event_probe__syscall_exit_##_template, \
8a8ac9a8 352 .event_notifier_func = __event_notifier_probe__syscall_exit_##_template, \
5b7ac358
MD
353 .nrargs = (_nrargs), \
354 .fields = __event_fields___syscall_exit_##_template, \
355 .desc = &__event_desc___syscall_exit_##_name, \
356 },
357
2d6d88c6 358/* Event syscall exit table */
5b7ac358 359static const struct trace_syscall_entry sc_exit_table[] = {
241ae9a8
MD
360#include <instrumentation/syscalls/headers/syscalls_integers.h>
361#include <instrumentation/syscalls/headers/syscalls_pointers.h>
5b7ac358
MD
362};
363
364#undef TRACE_SYSCALL_TABLE
365#define TRACE_SYSCALL_TABLE(_template, _name, _nr, _nrargs) \
366 [ _nr ] = { \
2d6d88c6 367 .event_func = __event_probe__compat_syscall_exit_##_template, \
8a8ac9a8 368 .event_notifier_func = __event_notifier_probe__compat_syscall_exit_##_template, \
5b7ac358
MD
369 .nrargs = (_nrargs), \
370 .fields = __event_fields___compat_syscall_exit_##_template, \
371 .desc = &__event_desc___compat_syscall_exit_##_name, \
372 },
373
2d6d88c6 374/* Event compat syscall exit table */
5b7ac358 375const struct trace_syscall_entry compat_sc_exit_table[] = {
241ae9a8
MD
376#include <instrumentation/syscalls/headers/compat_syscalls_integers.h>
377#include <instrumentation/syscalls/headers/compat_syscalls_pointers.h>
5b7ac358
MD
378};
379
fc4f7161
MD
380#undef SC_EXIT
381
a93244f8 382#undef CREATE_SYSCALL_TABLE
2faf7d1b 383
80f87dd2 384struct lttng_syscall_filter {
badfe9f5
MD
385 DECLARE_BITMAP(sc_entry, NR_syscalls);
386 DECLARE_BITMAP(sc_exit, NR_syscalls);
387 DECLARE_BITMAP(sc_compat_entry, NR_compat_syscalls);
388 DECLARE_BITMAP(sc_compat_exit, NR_compat_syscalls);
80f87dd2
MD
389};
390
3b82c4e1 391static void syscall_entry_event_unknown(struct hlist_head *unknown_action_list_head,
8a8ac9a8 392 struct pt_regs *regs, long id)
f405cfce 393{
1b7b9c65 394 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
a67ba386 395 struct lttng_kernel_event_common_private *event_priv;
f405cfce 396
1b7b9c65 397 lttng_syscall_get_arguments(current, regs, args);
a67ba386
MD
398 lttng_hlist_for_each_entry_rcu(event_priv, unknown_action_list_head, u.syscall.node) {
399 struct lttng_kernel_event_recorder_private *event_recorder_priv =
400 container_of(event_priv, struct lttng_kernel_event_recorder_private, parent);
401 struct lttng_kernel_event_recorder *event_recorder = event_recorder_priv->pub;
402
3b82c4e1 403 if (unlikely(in_compat_syscall()))
a67ba386 404 __event_probe__compat_syscall_entry_unknown(event_recorder, id, args);
3b82c4e1 405 else
a67ba386 406 __event_probe__syscall_entry_unknown(event_recorder, id, args);
3b82c4e1 407 }
f405cfce
MD
408}
409
8a8ac9a8
FD
410static void syscall_entry_event_notifier_unknown(
411 struct hlist_head *unknown_dispatch_list_head,
412 struct pt_regs *regs, long id)
413{
414 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
a67ba386 415 struct lttng_kernel_event_common_private *event_priv;
8a8ac9a8
FD
416
417 lttng_syscall_get_arguments(current, regs, args);
a67ba386
MD
418 lttng_hlist_for_each_entry_rcu(event_priv, unknown_dispatch_list_head, u.syscall.node) {
419 struct lttng_kernel_event_notifier_private *event_notifier_priv =
420 container_of(event_priv, struct lttng_kernel_event_notifier_private, parent);
421 struct lttng_kernel_event_notifier *event_notifier = event_notifier_priv->pub;
422
8a8ac9a8 423 if (unlikely(in_compat_syscall()))
a67ba386 424 __event_notifier_probe__compat_syscall_entry_unknown(event_notifier, id, args);
8a8ac9a8 425 else
a67ba386 426 __event_notifier_probe__syscall_entry_unknown(event_notifier, id, args);
8a8ac9a8
FD
427 }
428}
429
430static void syscall_exit_event_notifier_unknown(
431 struct hlist_head *unknown_dispatch_list_head,
432 struct pt_regs *regs, long id, long ret)
433{
434 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
a67ba386 435 struct lttng_kernel_event_common_private *event_priv;
8a8ac9a8
FD
436
437 lttng_syscall_get_arguments(current, regs, args);
a67ba386
MD
438 lttng_hlist_for_each_entry_rcu(event_priv, unknown_dispatch_list_head, u.syscall.node) {
439 struct lttng_kernel_event_notifier_private *event_notifier_priv =
440 container_of(event_priv, struct lttng_kernel_event_notifier_private, parent);
441 struct lttng_kernel_event_notifier *event_notifier = event_notifier_priv->pub;
442
8a8ac9a8 443 if (unlikely(in_compat_syscall()))
a67ba386 444 __event_notifier_probe__compat_syscall_exit_unknown(event_notifier, id, ret, args);
8a8ac9a8 445 else
a67ba386 446 __event_notifier_probe__syscall_exit_unknown(event_notifier, id, ret, args);
8a8ac9a8
FD
447 }
448}
449
63aa9160 450static __always_inline
3b82c4e1
MD
451void syscall_entry_call_func(struct hlist_head *action_list,
452 void *func, unsigned int nrargs,
63aa9160 453 struct pt_regs *regs)
259b6cb3 454{
a67ba386 455 struct lttng_kernel_event_common_private *event_priv;
3b82c4e1 456
63aa9160 457 switch (nrargs) {
259b6cb3
MD
458 case 0:
459 {
63aa9160 460 void (*fptr)(void *__data) = func;
259b6cb3 461
a67ba386
MD
462 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node) {
463 struct lttng_kernel_event_recorder_private *event_recorder_priv =
464 container_of(event_priv, struct lttng_kernel_event_recorder_private, parent);
465 struct lttng_kernel_event_recorder *event_recorder = event_recorder_priv->pub;
466
467 fptr(event_recorder);
468 }
259b6cb3
MD
469 break;
470 }
471 case 1:
472 {
63aa9160 473 void (*fptr)(void *__data, unsigned long arg0) = func;
1b7b9c65 474 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
259b6cb3 475
1b7b9c65 476 lttng_syscall_get_arguments(current, regs, args);
a67ba386
MD
477 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node) {
478 struct lttng_kernel_event_recorder_private *event_recorder_priv =
479 container_of(event_priv, struct lttng_kernel_event_recorder_private, parent);
480 struct lttng_kernel_event_recorder *event_recorder = event_recorder_priv->pub;
481
482 fptr(event_recorder, args[0]);
483 }
259b6cb3
MD
484 break;
485 }
486 case 2:
487 {
488 void (*fptr)(void *__data,
489 unsigned long arg0,
63aa9160 490 unsigned long arg1) = func;
1b7b9c65 491 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
259b6cb3 492
1b7b9c65 493 lttng_syscall_get_arguments(current, regs, args);
a67ba386
MD
494 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node) {
495 struct lttng_kernel_event_recorder_private *event_recorder_priv =
496 container_of(event_priv, struct lttng_kernel_event_recorder_private, parent);
497 struct lttng_kernel_event_recorder *event_recorder = event_recorder_priv->pub;
498
499 fptr(event_recorder, args[0], args[1]);
500 }
259b6cb3
MD
501 break;
502 }
503 case 3:
504 {
505 void (*fptr)(void *__data,
506 unsigned long arg0,
507 unsigned long arg1,
63aa9160 508 unsigned long arg2) = func;
1b7b9c65 509 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
259b6cb3 510
1b7b9c65 511 lttng_syscall_get_arguments(current, regs, args);
a67ba386
MD
512 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node) {
513 struct lttng_kernel_event_recorder_private *event_recorder_priv =
514 container_of(event_priv, struct lttng_kernel_event_recorder_private, parent);
515 struct lttng_kernel_event_recorder *event_recorder = event_recorder_priv->pub;
516
517 fptr(event_recorder, args[0], args[1], args[2]);
518 }
259b6cb3
MD
519 break;
520 }
521 case 4:
522 {
523 void (*fptr)(void *__data,
524 unsigned long arg0,
525 unsigned long arg1,
526 unsigned long arg2,
63aa9160 527 unsigned long arg3) = func;
1b7b9c65 528 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
259b6cb3 529
1b7b9c65 530 lttng_syscall_get_arguments(current, regs, args);
a67ba386
MD
531 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node) {
532 struct lttng_kernel_event_recorder_private *event_recorder_priv =
533 container_of(event_priv, struct lttng_kernel_event_recorder_private, parent);
534 struct lttng_kernel_event_recorder *event_recorder = event_recorder_priv->pub;
535
536 fptr(event_recorder, args[0], args[1], args[2], args[3]);
537 }
259b6cb3
MD
538 break;
539 }
540 case 5:
541 {
542 void (*fptr)(void *__data,
543 unsigned long arg0,
544 unsigned long arg1,
545 unsigned long arg2,
546 unsigned long arg3,
63aa9160 547 unsigned long arg4) = func;
1b7b9c65 548 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
259b6cb3 549
1b7b9c65 550 lttng_syscall_get_arguments(current, regs, args);
a67ba386
MD
551 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node) {
552 struct lttng_kernel_event_recorder_private *event_recorder_priv =
553 container_of(event_priv, struct lttng_kernel_event_recorder_private, parent);
554 struct lttng_kernel_event_recorder *event_recorder = event_recorder_priv->pub;
555
556 fptr(event_recorder, args[0], args[1], args[2], args[3], args[4]);
557 }
259b6cb3
MD
558 break;
559 }
560 case 6:
561 {
562 void (*fptr)(void *__data,
563 unsigned long arg0,
564 unsigned long arg1,
565 unsigned long arg2,
566 unsigned long arg3,
567 unsigned long arg4,
63aa9160 568 unsigned long arg5) = func;
1b7b9c65 569 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
259b6cb3 570
1b7b9c65 571 lttng_syscall_get_arguments(current, regs, args);
a67ba386
MD
572 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node) {
573 struct lttng_kernel_event_recorder_private *event_recorder_priv =
574 container_of(event_priv, struct lttng_kernel_event_recorder_private, parent);
575 struct lttng_kernel_event_recorder *event_recorder = event_recorder_priv->pub;
576
577 fptr(event_recorder, args[0], args[1], args[2],
3b82c4e1 578 args[3], args[4], args[5]);
a67ba386 579 }
259b6cb3
MD
580 break;
581 }
582 default:
583 break;
584 }
585}
586
8a8ac9a8
FD
587static __always_inline
588void syscall_entry_event_notifier_call_func(struct hlist_head *dispatch_list,
589 void *func, unsigned int nrargs, struct pt_regs *regs)
590{
a67ba386 591 struct lttng_kernel_event_common_private *event_priv;
8a8ac9a8
FD
592
593 switch (nrargs) {
594 case 0:
595 {
596 void (*fptr)(void *__data) = func;
597
a67ba386
MD
598 lttng_hlist_for_each_entry_rcu(event_priv, dispatch_list, u.syscall.node) {
599 struct lttng_kernel_event_notifier_private *event_notifier_priv =
600 container_of(event_priv, struct lttng_kernel_event_notifier_private, parent);
601 struct lttng_kernel_event_notifier *event_notifier = event_notifier_priv->pub;
602
603 fptr(event_notifier);
604 }
8a8ac9a8
FD
605 break;
606 }
607 case 1:
608 {
609 void (*fptr)(void *__data, unsigned long arg0) = func;
610 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
611
612 lttng_syscall_get_arguments(current, regs, args);
a67ba386
MD
613 lttng_hlist_for_each_entry_rcu(event_priv, dispatch_list, u.syscall.node) {
614 struct lttng_kernel_event_notifier_private *event_notifier_priv =
615 container_of(event_priv, struct lttng_kernel_event_notifier_private, parent);
616 struct lttng_kernel_event_notifier *event_notifier = event_notifier_priv->pub;
617
618 fptr(event_notifier, args[0]);
619 }
8a8ac9a8
FD
620 break;
621 }
622 case 2:
623 {
624 void (*fptr)(void *__data,
625 unsigned long arg0,
626 unsigned long arg1) = func;
627 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
628
629 lttng_syscall_get_arguments(current, regs, args);
a67ba386
MD
630 lttng_hlist_for_each_entry_rcu(event_priv, dispatch_list, u.syscall.node) {
631 struct lttng_kernel_event_notifier_private *event_notifier_priv =
632 container_of(event_priv, struct lttng_kernel_event_notifier_private, parent);
633 struct lttng_kernel_event_notifier *event_notifier = event_notifier_priv->pub;
634
635 fptr(event_notifier, args[0], args[1]);
636 }
8a8ac9a8
FD
637 break;
638 }
639 case 3:
640 {
641 void (*fptr)(void *__data,
642 unsigned long arg0,
643 unsigned long arg1,
644 unsigned long arg2) = func;
645 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
646
647 lttng_syscall_get_arguments(current, regs, args);
a67ba386
MD
648 lttng_hlist_for_each_entry_rcu(event_priv, dispatch_list, u.syscall.node) {
649 struct lttng_kernel_event_notifier_private *event_notifier_priv =
650 container_of(event_priv, struct lttng_kernel_event_notifier_private, parent);
651 struct lttng_kernel_event_notifier *event_notifier = event_notifier_priv->pub;
652
653 fptr(event_notifier, args[0], args[1], args[2]);
654 }
8a8ac9a8
FD
655 break;
656 }
657 case 4:
658 {
659 void (*fptr)(void *__data,
660 unsigned long arg0,
661 unsigned long arg1,
662 unsigned long arg2,
663 unsigned long arg3) = func;
664 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
665
666 lttng_syscall_get_arguments(current, regs, args);
a67ba386
MD
667 lttng_hlist_for_each_entry_rcu(event_priv, dispatch_list, u.syscall.node) {
668 struct lttng_kernel_event_notifier_private *event_notifier_priv =
669 container_of(event_priv, struct lttng_kernel_event_notifier_private, parent);
670 struct lttng_kernel_event_notifier *event_notifier = event_notifier_priv->pub;
671
672 fptr(event_notifier, args[0], args[1], args[2], args[3]);
673 }
8a8ac9a8
FD
674 break;
675 }
676 case 5:
677 {
678 void (*fptr)(void *__data,
679 unsigned long arg0,
680 unsigned long arg1,
681 unsigned long arg2,
682 unsigned long arg3,
683 unsigned long arg4) = func;
684 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
685
686 lttng_syscall_get_arguments(current, regs, args);
a67ba386
MD
687 lttng_hlist_for_each_entry_rcu(event_priv, dispatch_list, u.syscall.node) {
688 struct lttng_kernel_event_notifier_private *event_notifier_priv =
689 container_of(event_priv, struct lttng_kernel_event_notifier_private, parent);
690 struct lttng_kernel_event_notifier *event_notifier = event_notifier_priv->pub;
691
692 fptr(event_notifier, args[0], args[1], args[2], args[3], args[4]);
693 }
8a8ac9a8
FD
694 break;
695 }
696 case 6:
697 {
698 void (*fptr)(void *__data,
699 unsigned long arg0,
700 unsigned long arg1,
701 unsigned long arg2,
702 unsigned long arg3,
703 unsigned long arg4,
704 unsigned long arg5) = func;
705 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
706
707 lttng_syscall_get_arguments(current, regs, args);
a67ba386
MD
708 lttng_hlist_for_each_entry_rcu(event_priv, dispatch_list, u.syscall.node) {
709 struct lttng_kernel_event_notifier_private *event_notifier_priv =
710 container_of(event_priv, struct lttng_kernel_event_notifier_private, parent);
711 struct lttng_kernel_event_notifier *event_notifier = event_notifier_priv->pub;
712
713 fptr(event_notifier, args[0], args[1], args[2], args[3], args[4], args[5]);
714 }
8a8ac9a8
FD
715 break;
716 }
717 default:
718 break;
719 }
720}
721
63aa9160
FD
722void syscall_entry_event_probe(void *__data, struct pt_regs *regs, long id)
723{
724 struct lttng_channel *chan = __data;
3b82c4e1 725 struct hlist_head *action_list, *unknown_action_list;
63aa9160
FD
726 const struct trace_syscall_entry *table, *entry;
727 size_t table_len;
728
729 if (unlikely(in_compat_syscall())) {
730 struct lttng_syscall_filter *filter = chan->sc_filter;
731
732 if (id < 0 || id >= NR_compat_syscalls
3b82c4e1 733 || (!READ_ONCE(chan->syscall_all_entry) && !test_bit(id, filter->sc_compat_entry))) {
63aa9160
FD
734 /* System call filtered out. */
735 return;
736 }
737 table = compat_sc_table;
738 table_len = ARRAY_SIZE(compat_sc_table);
3b82c4e1 739 unknown_action_list = &chan->sc_compat_unknown;
63aa9160
FD
740 } else {
741 struct lttng_syscall_filter *filter = chan->sc_filter;
742
743 if (id < 0 || id >= NR_syscalls
3b82c4e1 744 || (!READ_ONCE(chan->syscall_all_entry) && !test_bit(id, filter->sc_entry))) {
63aa9160
FD
745 /* System call filtered out. */
746 return;
747 }
748 table = sc_table;
749 table_len = ARRAY_SIZE(sc_table);
3b82c4e1 750 unknown_action_list = &chan->sc_unknown;
63aa9160
FD
751 }
752 if (unlikely(id < 0 || id >= table_len)) {
3b82c4e1 753 syscall_entry_event_unknown(unknown_action_list, regs, id);
63aa9160
FD
754 return;
755 }
3b82c4e1
MD
756
757 entry = &table[id];
758 if (!entry->event_func) {
759 syscall_entry_event_unknown(unknown_action_list, regs, id);
63aa9160
FD
760 return;
761 }
3b82c4e1
MD
762
763 if (unlikely(in_compat_syscall())) {
764 action_list = &chan->compat_sc_table[id];
765 } else {
766 action_list = &chan->sc_table[id];
767 }
768 if (unlikely(hlist_empty(action_list)))
769 return;
770
771 syscall_entry_call_func(action_list, entry->event_func, entry->nrargs, regs);
63aa9160
FD
772}
773
8a8ac9a8
FD
774void syscall_entry_event_notifier_probe(void *__data, struct pt_regs *regs,
775 long id)
776{
777 struct lttng_event_notifier_group *group = __data;
778 const struct trace_syscall_entry *table, *entry;
779 struct hlist_head *dispatch_list, *unknown_dispatch_list;
780 size_t table_len;
781
782 if (unlikely(in_compat_syscall())) {
783 struct lttng_syscall_filter *filter = group->sc_filter;
784
785 if (id < 0 || id >= NR_compat_syscalls
786 || (!READ_ONCE(group->syscall_all_entry) &&
787 !test_bit(id, filter->sc_compat_entry))) {
788 /* System call filtered out. */
789 return;
790 }
791 table = compat_sc_table;
792 table_len = ARRAY_SIZE(compat_sc_table);
793 unknown_dispatch_list = &group->event_notifier_compat_unknown_syscall_dispatch;
794 } else {
795 struct lttng_syscall_filter *filter = group->sc_filter;
796
797 if (id < 0 || id >= NR_syscalls
798 || (!READ_ONCE(group->syscall_all_entry) &&
799 !test_bit(id, filter->sc_entry))) {
800 /* System call filtered out. */
801 return;
802 }
803 table = sc_table;
804 table_len = ARRAY_SIZE(sc_table);
805 unknown_dispatch_list = &group->event_notifier_unknown_syscall_dispatch;
806 }
807 /* Check if the syscall id is out of bound. */
808 if (unlikely(id < 0 || id >= table_len)) {
809 syscall_entry_event_notifier_unknown(unknown_dispatch_list,
810 regs, id);
811 return;
812 }
813
814 entry = &table[id];
815 if (!entry->event_notifier_func) {
816 syscall_entry_event_notifier_unknown(unknown_dispatch_list,
817 regs, id);
818 return;
819 }
820
821 if (unlikely(in_compat_syscall())) {
822 dispatch_list = &group->event_notifier_compat_syscall_dispatch[id];
823 } else {
824 dispatch_list = &group->event_notifier_syscall_dispatch[id];
825 }
826 if (unlikely(hlist_empty(dispatch_list)))
827 return;
828
829 syscall_entry_event_notifier_call_func(dispatch_list,
830 entry->event_notifier_func, entry->nrargs, regs);
831}
832
3b82c4e1 833static void syscall_exit_event_unknown(struct hlist_head *unknown_action_list_head,
8a8ac9a8 834 struct pt_regs *regs, long id, long ret)
5b7ac358 835{
1b7b9c65 836 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
a67ba386 837 struct lttng_kernel_event_common_private *event_priv;
5b7ac358 838
1b7b9c65 839 lttng_syscall_get_arguments(current, regs, args);
a67ba386
MD
840 lttng_hlist_for_each_entry_rcu(event_priv, unknown_action_list_head, u.syscall.node) {
841 struct lttng_kernel_event_recorder_private *event_recorder_priv =
842 container_of(event_priv, struct lttng_kernel_event_recorder_private, parent);
843 struct lttng_kernel_event_recorder *event_recorder = event_recorder_priv->pub;
844
3b82c4e1 845 if (unlikely(in_compat_syscall()))
a67ba386 846 __event_probe__compat_syscall_exit_unknown(event_recorder, id, ret,
3b82c4e1
MD
847 args);
848 else
a67ba386 849 __event_probe__syscall_exit_unknown(event_recorder, id, ret, args);
3b82c4e1 850 }
5b7ac358
MD
851}
852
3b82c4e1
MD
853static __always_inline
854void syscall_exit_call_func(struct hlist_head *action_list,
855 void *func, unsigned int nrargs,
856 struct pt_regs *regs, long ret)
5b7ac358 857{
a67ba386 858 struct lttng_kernel_event_common_private *event_priv;
badfe9f5 859
3b82c4e1 860 switch (nrargs) {
5b7ac358
MD
861 case 0:
862 {
3b82c4e1 863 void (*fptr)(void *__data, long ret) = func;
5b7ac358 864
a67ba386
MD
865 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node) {
866 struct lttng_kernel_event_recorder_private *event_recorder_priv =
867 container_of(event_priv, struct lttng_kernel_event_recorder_private, parent);
868 struct lttng_kernel_event_recorder *event_recorder = event_recorder_priv->pub;
869
870 fptr(event_recorder, ret);
871 }
5b7ac358
MD
872 break;
873 }
874 case 1:
875 {
876 void (*fptr)(void *__data,
fc4f7161 877 long ret,
3b82c4e1 878 unsigned long arg0) = func;
1b7b9c65 879 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
5b7ac358 880
1b7b9c65 881 lttng_syscall_get_arguments(current, regs, args);
a67ba386
MD
882 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node) {
883 struct lttng_kernel_event_recorder_private *event_recorder_priv =
884 container_of(event_priv, struct lttng_kernel_event_recorder_private, parent);
885 struct lttng_kernel_event_recorder *event_recorder = event_recorder_priv->pub;
886
887 fptr(event_recorder, ret, args[0]);
888 }
5b7ac358
MD
889 break;
890 }
891 case 2:
892 {
893 void (*fptr)(void *__data,
fc4f7161 894 long ret,
5b7ac358 895 unsigned long arg0,
3b82c4e1 896 unsigned long arg1) = func;
1b7b9c65 897 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
5b7ac358 898
1b7b9c65 899 lttng_syscall_get_arguments(current, regs, args);
a67ba386
MD
900 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node) {
901 struct lttng_kernel_event_recorder_private *event_recorder_priv =
902 container_of(event_priv, struct lttng_kernel_event_recorder_private, parent);
903 struct lttng_kernel_event_recorder *event_recorder = event_recorder_priv->pub;
904
905 fptr(event_recorder, ret, args[0], args[1]);
906 }
5b7ac358
MD
907 break;
908 }
909 case 3:
910 {
911 void (*fptr)(void *__data,
fc4f7161 912 long ret,
5b7ac358
MD
913 unsigned long arg0,
914 unsigned long arg1,
3b82c4e1 915 unsigned long arg2) = func;
1b7b9c65 916 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
5b7ac358 917
1b7b9c65 918 lttng_syscall_get_arguments(current, regs, args);
a67ba386
MD
919 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node) {
920 struct lttng_kernel_event_recorder_private *event_recorder_priv =
921 container_of(event_priv, struct lttng_kernel_event_recorder_private, parent);
922 struct lttng_kernel_event_recorder *event_recorder = event_recorder_priv->pub;
923
924 fptr(event_recorder, ret, args[0], args[1], args[2]);
925 }
5b7ac358
MD
926 break;
927 }
928 case 4:
929 {
930 void (*fptr)(void *__data,
fc4f7161 931 long ret,
5b7ac358
MD
932 unsigned long arg0,
933 unsigned long arg1,
934 unsigned long arg2,
3b82c4e1 935 unsigned long arg3) = func;
1b7b9c65 936 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
5b7ac358 937
1b7b9c65 938 lttng_syscall_get_arguments(current, regs, args);
a67ba386
MD
939 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node) {
940 struct lttng_kernel_event_recorder_private *event_recorder_priv =
941 container_of(event_priv, struct lttng_kernel_event_recorder_private, parent);
942 struct lttng_kernel_event_recorder *event_recorder = event_recorder_priv->pub;
943
944 fptr(event_recorder, ret, args[0], args[1], args[2], args[3]);
945 }
5b7ac358
MD
946 break;
947 }
948 case 5:
949 {
950 void (*fptr)(void *__data,
fc4f7161 951 long ret,
5b7ac358
MD
952 unsigned long arg0,
953 unsigned long arg1,
954 unsigned long arg2,
955 unsigned long arg3,
3b82c4e1 956 unsigned long arg4) = func;
1b7b9c65 957 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
5b7ac358 958
1b7b9c65 959 lttng_syscall_get_arguments(current, regs, args);
a67ba386
MD
960 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node) {
961 struct lttng_kernel_event_recorder_private *event_recorder_priv =
962 container_of(event_priv, struct lttng_kernel_event_recorder_private, parent);
963 struct lttng_kernel_event_recorder *event_recorder = event_recorder_priv->pub;
964
965 fptr(event_recorder, ret, args[0], args[1], args[2], args[3], args[4]);
966 }
5b7ac358
MD
967 break;
968 }
969 case 6:
970 {
971 void (*fptr)(void *__data,
fc4f7161 972 long ret,
5b7ac358
MD
973 unsigned long arg0,
974 unsigned long arg1,
975 unsigned long arg2,
976 unsigned long arg3,
977 unsigned long arg4,
3b82c4e1 978 unsigned long arg5) = func;
1b7b9c65 979 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
5b7ac358 980
1b7b9c65 981 lttng_syscall_get_arguments(current, regs, args);
a67ba386
MD
982 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node) {
983 struct lttng_kernel_event_recorder_private *event_recorder_priv =
984 container_of(event_priv, struct lttng_kernel_event_recorder_private, parent);
985 struct lttng_kernel_event_recorder *event_recorder = event_recorder_priv->pub;
986
987 fptr(event_recorder, ret, args[0], args[1], args[2],
3b82c4e1 988 args[3], args[4], args[5]);
a67ba386 989 }
5b7ac358
MD
990 break;
991 }
992 default:
993 break;
994 }
995}
996
3b82c4e1
MD
997void syscall_exit_event_probe(void *__data, struct pt_regs *regs, long ret)
998{
999 struct lttng_channel *chan = __data;
1000 struct hlist_head *action_list, *unknown_action_list;
1001 const struct trace_syscall_entry *table, *entry;
1002 size_t table_len;
1003 long id;
1004
1005 id = syscall_get_nr(current, regs);
1006
1007 if (unlikely(in_compat_syscall())) {
1008 struct lttng_syscall_filter *filter = chan->sc_filter;
1009
1010 if (id < 0 || id >= NR_compat_syscalls
1011 || (!READ_ONCE(chan->syscall_all_exit) && !test_bit(id, filter->sc_compat_exit))) {
1012 /* System call filtered out. */
1013 return;
1014 }
1015 table = compat_sc_exit_table;
1016 table_len = ARRAY_SIZE(compat_sc_exit_table);
1017 unknown_action_list = &chan->compat_sc_exit_unknown;
1018 } else {
1019 struct lttng_syscall_filter *filter = chan->sc_filter;
1020
1021 if (id < 0 || id >= NR_syscalls
1022 || (!READ_ONCE(chan->syscall_all_exit) && !test_bit(id, filter->sc_exit))) {
1023 /* System call filtered out. */
1024 return;
1025 }
1026 table = sc_exit_table;
1027 table_len = ARRAY_SIZE(sc_exit_table);
1028 unknown_action_list = &chan->sc_exit_unknown;
1029 }
1030 if (unlikely(id < 0 || id >= table_len)) {
1031 syscall_exit_event_unknown(unknown_action_list, regs, id, ret);
1032 return;
1033 }
1034
1035 entry = &table[id];
1036 if (!entry->event_func) {
1037 syscall_exit_event_unknown(unknown_action_list, regs, id, ret);
1038 return;
1039 }
1040
1041 if (unlikely(in_compat_syscall())) {
1042 action_list = &chan->compat_sc_exit_table[id];
1043 } else {
1044 action_list = &chan->sc_exit_table[id];
1045 }
1046 if (unlikely(hlist_empty(action_list)))
1047 return;
1048
1049 syscall_exit_call_func(action_list, entry->event_func, entry->nrargs,
1050 regs, ret);
1051}
1052
8a8ac9a8
FD
1053static __always_inline
1054void syscall_exit_event_notifier_call_func(struct hlist_head *dispatch_list,
1055 void *func, unsigned int nrargs, struct pt_regs *regs, long ret)
1056{
a67ba386 1057 struct lttng_kernel_event_common_private *event_priv;
8a8ac9a8
FD
1058
1059 switch (nrargs) {
1060 case 0:
1061 {
1062 void (*fptr)(void *__data, long ret) = func;
1063
a67ba386
MD
1064 lttng_hlist_for_each_entry_rcu(event_priv, dispatch_list, u.syscall.node) {
1065 struct lttng_kernel_event_notifier_private *event_notifier_priv =
1066 container_of(event_priv, struct lttng_kernel_event_notifier_private, parent);
1067 struct lttng_kernel_event_notifier *event_notifier = event_notifier_priv->pub;
1068
1069 fptr(event_notifier, ret);
1070 }
8a8ac9a8
FD
1071 break;
1072 }
1073 case 1:
1074 {
1075 void (*fptr)(void *__data, long ret, unsigned long arg0) = func;
1076 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
1077
1078 lttng_syscall_get_arguments(current, regs, args);
a67ba386
MD
1079 lttng_hlist_for_each_entry_rcu(event_priv, dispatch_list, u.syscall.node) {
1080 struct lttng_kernel_event_notifier_private *event_notifier_priv =
1081 container_of(event_priv, struct lttng_kernel_event_notifier_private, parent);
1082 struct lttng_kernel_event_notifier *event_notifier = event_notifier_priv->pub;
1083
1084 fptr(event_notifier, ret, args[0]);
1085 }
8a8ac9a8
FD
1086 break;
1087 }
1088 case 2:
1089 {
1090 void (*fptr)(void *__data,
1091 long ret,
1092 unsigned long arg0,
1093 unsigned long arg1) = func;
1094 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
1095
1096 lttng_syscall_get_arguments(current, regs, args);
a67ba386
MD
1097 lttng_hlist_for_each_entry_rcu(event_priv, dispatch_list, u.syscall.node) {
1098 struct lttng_kernel_event_notifier_private *event_notifier_priv =
1099 container_of(event_priv, struct lttng_kernel_event_notifier_private, parent);
1100 struct lttng_kernel_event_notifier *event_notifier = event_notifier_priv->pub;
1101
1102 fptr(event_notifier, ret, args[0], args[1]);
1103 }
8a8ac9a8
FD
1104 break;
1105 }
1106 case 3:
1107 {
1108 void (*fptr)(void *__data,
1109 long ret,
1110 unsigned long arg0,
1111 unsigned long arg1,
1112 unsigned long arg2) = func;
1113 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
1114
1115 lttng_syscall_get_arguments(current, regs, args);
a67ba386
MD
1116 lttng_hlist_for_each_entry_rcu(event_priv, dispatch_list, u.syscall.node) {
1117 struct lttng_kernel_event_notifier_private *event_notifier_priv =
1118 container_of(event_priv, struct lttng_kernel_event_notifier_private, parent);
1119 struct lttng_kernel_event_notifier *event_notifier = event_notifier_priv->pub;
1120
1121 fptr(event_notifier, ret, args[0], args[1], args[2]);
1122 }
8a8ac9a8
FD
1123 break;
1124 }
1125 case 4:
1126 {
1127 void (*fptr)(void *__data,
1128 long ret,
1129 unsigned long arg0,
1130 unsigned long arg1,
1131 unsigned long arg2,
1132 unsigned long arg3) = func;
1133 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
1134
1135 lttng_syscall_get_arguments(current, regs, args);
a67ba386
MD
1136 lttng_hlist_for_each_entry_rcu(event_priv, dispatch_list, u.syscall.node) {
1137 struct lttng_kernel_event_notifier_private *event_notifier_priv =
1138 container_of(event_priv, struct lttng_kernel_event_notifier_private, parent);
1139 struct lttng_kernel_event_notifier *event_notifier = event_notifier_priv->pub;
1140
1141 fptr(event_notifier, ret, args[0], args[1], args[2], args[3]);
1142 }
8a8ac9a8
FD
1143 break;
1144 }
1145 case 5:
1146 {
1147 void (*fptr)(void *__data,
1148 long ret,
1149 unsigned long arg0,
1150 unsigned long arg1,
1151 unsigned long arg2,
1152 unsigned long arg3,
1153 unsigned long arg4) = func;
1154 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
1155
1156 lttng_syscall_get_arguments(current, regs, args);
a67ba386
MD
1157 lttng_hlist_for_each_entry_rcu(event_priv, dispatch_list, u.syscall.node) {
1158 struct lttng_kernel_event_notifier_private *event_notifier_priv =
1159 container_of(event_priv, struct lttng_kernel_event_notifier_private, parent);
1160 struct lttng_kernel_event_notifier *event_notifier = event_notifier_priv->pub;
1161
1162 fptr(event_notifier, ret, args[0], args[1], args[2], args[3], args[4]);
1163 }
8a8ac9a8
FD
1164 break;
1165 }
1166 case 6:
1167 {
1168 void (*fptr)(void *__data,
1169 long ret,
1170 unsigned long arg0,
1171 unsigned long arg1,
1172 unsigned long arg2,
1173 unsigned long arg3,
1174 unsigned long arg4,
1175 unsigned long arg5) = func;
1176 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
1177
1178 lttng_syscall_get_arguments(current, regs, args);
a67ba386
MD
1179 lttng_hlist_for_each_entry_rcu(event_priv, dispatch_list, u.syscall.node) {
1180 struct lttng_kernel_event_notifier_private *event_notifier_priv =
1181 container_of(event_priv, struct lttng_kernel_event_notifier_private, parent);
1182 struct lttng_kernel_event_notifier *event_notifier = event_notifier_priv->pub;
1183
1184 fptr(event_notifier, ret, args[0], args[1], args[2], args[3], args[4], args[5]);
1185 }
8a8ac9a8
FD
1186 break;
1187 }
1188 default:
1189 break;
1190 }
1191}
1192
1193static
1194void syscall_exit_event_notifier_probe(void *__data, struct pt_regs *regs,
1195 long ret)
1196{
1197 struct lttng_event_notifier_group *group = __data;
1198 const struct trace_syscall_entry *table, *entry;
1199 struct hlist_head *dispatch_list, *unknown_dispatch_list;
1200 size_t table_len;
1201 long id;
1202
1203 id = syscall_get_nr(current, regs);
1204
1205 if (unlikely(in_compat_syscall())) {
1206 struct lttng_syscall_filter *filter = group->sc_filter;
1207
1208 if (id < 0 || id >= NR_compat_syscalls
1209 || (!READ_ONCE(group->syscall_all_exit) &&
1210 !test_bit(id, filter->sc_compat_exit))) {
1211 /* System call filtered out. */
1212 return;
1213 }
1214 table = compat_sc_exit_table;
1215 table_len = ARRAY_SIZE(compat_sc_exit_table);
1216 unknown_dispatch_list = &group->event_notifier_exit_compat_unknown_syscall_dispatch;
1217 } else {
1218 struct lttng_syscall_filter *filter = group->sc_filter;
1219
1220 if (id < 0 || id >= NR_syscalls
1221 || (!READ_ONCE(group->syscall_all_exit) &&
1222 !test_bit(id, filter->sc_exit))) {
1223 /* System call filtered out. */
1224 return;
1225 }
1226 table = sc_exit_table;
1227 table_len = ARRAY_SIZE(sc_exit_table);
1228 unknown_dispatch_list = &group->event_notifier_exit_unknown_syscall_dispatch;
1229 }
1230 /* Check if the syscall id is out of bound. */
1231 if (unlikely(id < 0 || id >= table_len)) {
1232 syscall_exit_event_notifier_unknown(unknown_dispatch_list,
1233 regs, id, ret);
1234 return;
1235 }
1236
1237 entry = &table[id];
1238 if (!entry->event_notifier_func) {
1239 syscall_entry_event_notifier_unknown(unknown_dispatch_list,
1240 regs, id);
1241 return;
1242 }
1243
1244 if (unlikely(in_compat_syscall())) {
1245 dispatch_list = &group->event_notifier_exit_compat_syscall_dispatch[id];
1246 } else {
1247 dispatch_list = &group->event_notifier_exit_syscall_dispatch[id];
1248 }
1249 if (unlikely(hlist_empty(dispatch_list)))
1250 return;
1251
1252 syscall_exit_event_notifier_call_func(dispatch_list,
1253 entry->event_notifier_func, entry->nrargs, regs, ret);
1254}
33a39a3c
MD
1255/*
1256 * noinline to diminish caller stack size.
1257 * Should be called with sessions lock held.
1258 */
49c50022 1259static
3b82c4e1
MD
1260int lttng_create_syscall_event_if_missing(const struct trace_syscall_entry *table, size_t table_len,
1261 struct hlist_head *chan_table, struct lttng_event_enabler *event_enabler,
a67ba386 1262 enum sc_type type)
259b6cb3 1263{
3b82c4e1
MD
1264 struct lttng_channel *chan = event_enabler->chan;
1265 struct lttng_session *session = chan->session;
259b6cb3 1266 unsigned int i;
49c50022 1267
3b82c4e1 1268 /* Allocate events for each syscall matching enabler, insert into table */
49c50022 1269 for (i = 0; i < table_len; i++) {
437d5aa5 1270 const struct lttng_kernel_event_desc *desc = table[i].desc;
606828e4 1271 struct lttng_kernel_abi_event ev;
a67ba386
MD
1272 struct lttng_kernel_event_recorder_private *event_recorder_priv;
1273 struct lttng_kernel_event_recorder *event_recorder;
3b82c4e1
MD
1274 struct hlist_head *head;
1275 bool found = false;
49c50022
MD
1276
1277 if (!desc) {
1278 /* Unknown syscall */
1279 continue;
1280 }
3b82c4e1
MD
1281 if (lttng_desc_match_enabler(desc,
1282 lttng_event_enabler_as_enabler(event_enabler)) <= 0)
1283 continue;
49c50022 1284 /*
3b82c4e1 1285 * Check if already created.
49c50022 1286 */
3b82c4e1
MD
1287 head = utils_borrow_hash_table_bucket(
1288 session->events_ht.table, LTTNG_EVENT_HT_SIZE,
437d5aa5 1289 desc->event_name);
a67ba386
MD
1290 lttng_hlist_for_each_entry(event_recorder_priv, head, hlist) {
1291 if (event_recorder_priv->parent.desc == desc
1292 && event_recorder_priv->pub->chan == event_enabler->chan)
3b82c4e1
MD
1293 found = true;
1294 }
1295 if (found)
49c50022 1296 continue;
3b82c4e1
MD
1297
1298 /* We need to create an event for this syscall/enabler. */
49c50022 1299 memset(&ev, 0, sizeof(ev));
5b7ac358
MD
1300 switch (type) {
1301 case SC_TYPE_ENTRY:
606828e4
MD
1302 ev.u.syscall.entryexit = LTTNG_KERNEL_ABI_SYSCALL_ENTRY;
1303 ev.u.syscall.abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_NATIVE;
5b7ac358
MD
1304 break;
1305 case SC_TYPE_EXIT:
606828e4
MD
1306 ev.u.syscall.entryexit = LTTNG_KERNEL_ABI_SYSCALL_EXIT;
1307 ev.u.syscall.abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_NATIVE;
5b7ac358
MD
1308 break;
1309 case SC_TYPE_COMPAT_ENTRY:
606828e4
MD
1310 ev.u.syscall.entryexit = LTTNG_KERNEL_ABI_SYSCALL_ENTRY;
1311 ev.u.syscall.abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_COMPAT;
5b7ac358
MD
1312 break;
1313 case SC_TYPE_COMPAT_EXIT:
606828e4
MD
1314 ev.u.syscall.entryexit = LTTNG_KERNEL_ABI_SYSCALL_EXIT;
1315 ev.u.syscall.abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_COMPAT;
5b7ac358
MD
1316 break;
1317 }
606828e4
MD
1318 strncpy(ev.name, desc->event_name, LTTNG_KERNEL_ABI_SYM_NAME_LEN - 1);
1319 ev.name[LTTNG_KERNEL_ABI_SYM_NAME_LEN - 1] = '\0';
1320 ev.instrumentation = LTTNG_KERNEL_ABI_SYSCALL;
a67ba386
MD
1321 event_recorder = _lttng_kernel_event_recorder_create(chan, &ev, desc, ev.instrumentation);
1322 WARN_ON_ONCE(!event_recorder);
1323 if (IS_ERR(event_recorder)) {
49c50022
MD
1324 /*
1325 * If something goes wrong in event registration
1326 * after the first one, we have no choice but to
1327 * leave the previous events in there, until
1328 * deleted by session teardown.
1329 */
a67ba386 1330 return PTR_ERR(event_recorder);
49c50022 1331 }
a67ba386 1332 hlist_add_head(&event_recorder->priv->parent.u.syscall.node, &chan_table[i]);
49c50022
MD
1333 }
1334 return 0;
1335}
1336
33a39a3c
MD
1337/*
1338 * Should be called with sessions lock held.
1339 */
a67ba386 1340int lttng_syscalls_register_event(struct lttng_event_enabler *event_enabler)
49c50022 1341{
3b82c4e1 1342 struct lttng_channel *chan = event_enabler->chan;
606828e4 1343 struct lttng_kernel_abi_event ev;
259b6cb3
MD
1344 int ret;
1345
263b6c88 1346 wrapper_vmalloc_sync_mappings();
259b6cb3
MD
1347
1348 if (!chan->sc_table) {
1349 /* create syscall table mapping syscall to events */
a67ba386 1350 chan->sc_table = kzalloc(sizeof(struct lttng_kernel_event_recorder *)
259b6cb3
MD
1351 * ARRAY_SIZE(sc_table), GFP_KERNEL);
1352 if (!chan->sc_table)
1353 return -ENOMEM;
1354 }
5b7ac358
MD
1355 if (!chan->sc_exit_table) {
1356 /* create syscall table mapping syscall to events */
a67ba386 1357 chan->sc_exit_table = kzalloc(sizeof(struct lttng_kernel_event_recorder *)
5b7ac358
MD
1358 * ARRAY_SIZE(sc_exit_table), GFP_KERNEL);
1359 if (!chan->sc_exit_table)
1360 return -ENOMEM;
1361 }
1362
259b6cb3 1363
49c50022
MD
1364#ifdef CONFIG_COMPAT
1365 if (!chan->compat_sc_table) {
1366 /* create syscall table mapping compat syscall to events */
a67ba386 1367 chan->compat_sc_table = kzalloc(sizeof(struct lttng_kernel_event_recorder *)
a93244f8 1368 * ARRAY_SIZE(compat_sc_table), GFP_KERNEL);
49c50022
MD
1369 if (!chan->compat_sc_table)
1370 return -ENOMEM;
1371 }
5b7ac358
MD
1372
1373 if (!chan->compat_sc_exit_table) {
1374 /* create syscall table mapping compat syscall to events */
a67ba386 1375 chan->compat_sc_exit_table = kzalloc(sizeof(struct lttng_kernel_event_recorder *)
5b7ac358
MD
1376 * ARRAY_SIZE(compat_sc_exit_table), GFP_KERNEL);
1377 if (!chan->compat_sc_exit_table)
1378 return -ENOMEM;
1379 }
49c50022 1380#endif
3b82c4e1 1381 if (hlist_empty(&chan->sc_unknown)) {
437d5aa5 1382 const struct lttng_kernel_event_desc *desc =
d4291869 1383 &__event_desc___syscall_entry_unknown;
a67ba386 1384 struct lttng_kernel_event_recorder *event_recorder;
2f804c0a 1385
f405cfce 1386 memset(&ev, 0, sizeof(ev));
606828e4
MD
1387 strncpy(ev.name, desc->event_name, LTTNG_KERNEL_ABI_SYM_NAME_LEN);
1388 ev.name[LTTNG_KERNEL_ABI_SYM_NAME_LEN - 1] = '\0';
1389 ev.instrumentation = LTTNG_KERNEL_ABI_SYSCALL;
1390 ev.u.syscall.entryexit = LTTNG_KERNEL_ABI_SYSCALL_ENTRY;
1391 ev.u.syscall.abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_NATIVE;
a67ba386 1392 event_recorder = _lttng_kernel_event_recorder_create(chan, &ev, desc,
3b82c4e1 1393 ev.instrumentation);
a67ba386
MD
1394 WARN_ON_ONCE(!event_recorder);
1395 if (IS_ERR(event_recorder)) {
1396 return PTR_ERR(event_recorder);
f405cfce 1397 }
a67ba386 1398 hlist_add_head(&event_recorder->priv->parent.u.syscall.node, &chan->sc_unknown);
f405cfce
MD
1399 }
1400
3b82c4e1 1401 if (hlist_empty(&chan->sc_compat_unknown)) {
437d5aa5 1402 const struct lttng_kernel_event_desc *desc =
d4291869 1403 &__event_desc___compat_syscall_entry_unknown;
a67ba386 1404 struct lttng_kernel_event_recorder *event_recorder;
b76dc1a0
MD
1405
1406 memset(&ev, 0, sizeof(ev));
606828e4
MD
1407 strncpy(ev.name, desc->event_name, LTTNG_KERNEL_ABI_SYM_NAME_LEN);
1408 ev.name[LTTNG_KERNEL_ABI_SYM_NAME_LEN - 1] = '\0';
1409 ev.instrumentation = LTTNG_KERNEL_ABI_SYSCALL;
1410 ev.u.syscall.entryexit = LTTNG_KERNEL_ABI_SYSCALL_ENTRY;
1411 ev.u.syscall.abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_COMPAT;
a67ba386 1412 event_recorder = _lttng_kernel_event_recorder_create(chan, &ev, desc,
3b82c4e1 1413 ev.instrumentation);
a67ba386
MD
1414 WARN_ON_ONCE(!event_recorder);
1415 if (IS_ERR(event_recorder)) {
1416 return PTR_ERR(event_recorder);
b76dc1a0 1417 }
a67ba386 1418 hlist_add_head(&event_recorder->priv->parent.u.syscall.node, &chan->sc_compat_unknown);
b76dc1a0
MD
1419 }
1420
3b82c4e1 1421 if (hlist_empty(&chan->compat_sc_exit_unknown)) {
437d5aa5 1422 const struct lttng_kernel_event_desc *desc =
5b7ac358 1423 &__event_desc___compat_syscall_exit_unknown;
a67ba386 1424 struct lttng_kernel_event_recorder *event_recorder;
2f804c0a
MD
1425
1426 memset(&ev, 0, sizeof(ev));
606828e4
MD
1427 strncpy(ev.name, desc->event_name, LTTNG_KERNEL_ABI_SYM_NAME_LEN);
1428 ev.name[LTTNG_KERNEL_ABI_SYM_NAME_LEN - 1] = '\0';
1429 ev.instrumentation = LTTNG_KERNEL_ABI_SYSCALL;
1430 ev.u.syscall.entryexit = LTTNG_KERNEL_ABI_SYSCALL_EXIT;
1431 ev.u.syscall.abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_COMPAT;
a67ba386 1432 event_recorder = _lttng_kernel_event_recorder_create(chan, &ev, desc,
3b82c4e1 1433 ev.instrumentation);
a67ba386
MD
1434 WARN_ON_ONCE(!event_recorder);
1435 if (IS_ERR(event_recorder)) {
1436 return PTR_ERR(event_recorder);
5b7ac358 1437 }
a67ba386 1438 hlist_add_head(&event_recorder->priv->parent.u.syscall.node, &chan->compat_sc_exit_unknown);
5b7ac358
MD
1439 }
1440
3b82c4e1 1441 if (hlist_empty(&chan->sc_exit_unknown)) {
437d5aa5 1442 const struct lttng_kernel_event_desc *desc =
5b7ac358 1443 &__event_desc___syscall_exit_unknown;
a67ba386 1444 struct lttng_kernel_event_recorder *event_recorder;
5b7ac358
MD
1445
1446 memset(&ev, 0, sizeof(ev));
606828e4
MD
1447 strncpy(ev.name, desc->event_name, LTTNG_KERNEL_ABI_SYM_NAME_LEN);
1448 ev.name[LTTNG_KERNEL_ABI_SYM_NAME_LEN - 1] = '\0';
1449 ev.instrumentation = LTTNG_KERNEL_ABI_SYSCALL;
1450 ev.u.syscall.entryexit = LTTNG_KERNEL_ABI_SYSCALL_EXIT;
1451 ev.u.syscall.abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_NATIVE;
a67ba386 1452 event_recorder = _lttng_kernel_event_recorder_create(chan, &ev, desc,
3b82c4e1 1453 ev.instrumentation);
a67ba386
MD
1454 WARN_ON_ONCE(!event_recorder);
1455 if (IS_ERR(event_recorder)) {
1456 return PTR_ERR(event_recorder);
2f804c0a 1457 }
a67ba386 1458 hlist_add_head(&event_recorder->priv->parent.u.syscall.node, &chan->sc_exit_unknown);
2f804c0a
MD
1459 }
1460
3b82c4e1 1461 ret = lttng_create_syscall_event_if_missing(sc_table, ARRAY_SIZE(sc_table),
a67ba386 1462 chan->sc_table, event_enabler, SC_TYPE_ENTRY);
5b7ac358
MD
1463 if (ret)
1464 return ret;
3b82c4e1 1465 ret = lttng_create_syscall_event_if_missing(sc_exit_table, ARRAY_SIZE(sc_exit_table),
a67ba386 1466 chan->sc_exit_table, event_enabler, SC_TYPE_EXIT);
49c50022
MD
1467 if (ret)
1468 return ret;
5b7ac358 1469
49c50022 1470#ifdef CONFIG_COMPAT
3b82c4e1 1471 ret = lttng_create_syscall_event_if_missing(compat_sc_table, ARRAY_SIZE(compat_sc_table),
a67ba386 1472 chan->compat_sc_table, event_enabler, SC_TYPE_COMPAT_ENTRY);
5b7ac358
MD
1473 if (ret)
1474 return ret;
3b82c4e1 1475 ret = lttng_create_syscall_event_if_missing(compat_sc_exit_table, ARRAY_SIZE(compat_sc_exit_table),
a67ba386 1476 chan->compat_sc_exit_table, event_enabler, SC_TYPE_COMPAT_EXIT);
49c50022
MD
1477 if (ret)
1478 return ret;
1479#endif
badfe9f5
MD
1480
1481 if (!chan->sc_filter) {
1482 chan->sc_filter = kzalloc(sizeof(struct lttng_syscall_filter),
1483 GFP_KERNEL);
1484 if (!chan->sc_filter)
1485 return -ENOMEM;
1486 }
1487
80f87dd2
MD
1488 if (!chan->sys_enter_registered) {
1489 ret = lttng_wrapper_tracepoint_probe_register("sys_enter",
2d6d88c6 1490 (void *) syscall_entry_event_probe, chan);
80f87dd2
MD
1491 if (ret)
1492 return ret;
1493 chan->sys_enter_registered = 1;
1494 }
63728b02
MD
1495 /*
1496 * We change the name of sys_exit tracepoint due to namespace
1497 * conflict with sys_exit syscall entry.
1498 */
80f87dd2
MD
1499 if (!chan->sys_exit_registered) {
1500 ret = lttng_wrapper_tracepoint_probe_register("sys_exit",
2d6d88c6 1501 (void *) syscall_exit_event_probe, chan);
80f87dd2
MD
1502 if (ret) {
1503 WARN_ON_ONCE(lttng_wrapper_tracepoint_probe_unregister("sys_enter",
2d6d88c6 1504 (void *) syscall_entry_event_probe, chan));
80f87dd2
MD
1505 return ret;
1506 }
1507 chan->sys_exit_registered = 1;
63728b02 1508 }
259b6cb3
MD
1509 return ret;
1510}
1511
1512/*
8a8ac9a8
FD
1513 * Should be called with sessions lock held.
1514 */
1515int lttng_syscalls_register_event_notifier(
a67ba386 1516 struct lttng_event_notifier_enabler *event_notifier_enabler)
8a8ac9a8
FD
1517{
1518 struct lttng_event_notifier_group *group = event_notifier_enabler->group;
1519 unsigned int i;
1520 int ret = 0;
1521
1522 wrapper_vmalloc_sync_mappings();
1523
1524 if (!group->event_notifier_syscall_dispatch) {
1525 group->event_notifier_syscall_dispatch =
1526 kzalloc(sizeof(struct hlist_head) * ARRAY_SIZE(sc_table),
1527 GFP_KERNEL);
1528 if (!group->event_notifier_syscall_dispatch)
1529 return -ENOMEM;
1530
1531 /* Initialize all list_head */
1532 for (i = 0; i < ARRAY_SIZE(sc_table); i++)
1533 INIT_HLIST_HEAD(&group->event_notifier_syscall_dispatch[i]);
1534
1535 /* Init the unknown syscall notifier list. */
1536 INIT_HLIST_HEAD(&group->event_notifier_unknown_syscall_dispatch);
1537 }
1538
1539 if (!group->event_notifier_exit_syscall_dispatch) {
1540 group->event_notifier_exit_syscall_dispatch =
1541 kzalloc(sizeof(struct hlist_head) * ARRAY_SIZE(sc_table),
1542 GFP_KERNEL);
1543 if (!group->event_notifier_exit_syscall_dispatch)
1544 return -ENOMEM;
1545
1546 /* Initialize all list_head */
1547 for (i = 0; i < ARRAY_SIZE(sc_table); i++)
1548 INIT_HLIST_HEAD(&group->event_notifier_exit_syscall_dispatch[i]);
1549
1550 /* Init the unknown exit syscall notifier list. */
1551 INIT_HLIST_HEAD(&group->event_notifier_exit_unknown_syscall_dispatch);
1552 }
1553
1554#ifdef CONFIG_COMPAT
1555 if (!group->event_notifier_compat_syscall_dispatch) {
1556 group->event_notifier_compat_syscall_dispatch =
1557 kzalloc(sizeof(struct hlist_head) * ARRAY_SIZE(compat_sc_table),
1558 GFP_KERNEL);
1559 if (!group->event_notifier_syscall_dispatch)
1560 return -ENOMEM;
1561
1562 /* Initialize all list_head */
1563 for (i = 0; i < ARRAY_SIZE(compat_sc_table); i++)
1564 INIT_HLIST_HEAD(&group->event_notifier_compat_syscall_dispatch[i]);
1565
1566 /* Init the unknown syscall notifier list. */
1567 INIT_HLIST_HEAD(&group->event_notifier_compat_unknown_syscall_dispatch);
1568 }
1569
1570 if (!group->event_notifier_exit_compat_syscall_dispatch) {
1571 group->event_notifier_exit_compat_syscall_dispatch =
1572 kzalloc(sizeof(struct hlist_head) * ARRAY_SIZE(compat_sc_exit_table),
1573 GFP_KERNEL);
1574 if (!group->event_notifier_exit_syscall_dispatch)
1575 return -ENOMEM;
1576
1577 /* Initialize all list_head */
1578 for (i = 0; i < ARRAY_SIZE(compat_sc_exit_table); i++)
1579 INIT_HLIST_HEAD(&group->event_notifier_exit_compat_syscall_dispatch[i]);
1580
1581 /* Init the unknown exit syscall notifier list. */
1582 INIT_HLIST_HEAD(&group->event_notifier_exit_compat_unknown_syscall_dispatch);
1583 }
1584#endif
1585
1586 if (!group->sc_filter) {
1587 group->sc_filter = kzalloc(sizeof(struct lttng_syscall_filter),
1588 GFP_KERNEL);
1589 if (!group->sc_filter)
1590 return -ENOMEM;
1591 }
1592
1593 if (!group->sys_enter_registered) {
1594 ret = lttng_wrapper_tracepoint_probe_register("sys_enter",
1595 (void *) syscall_entry_event_notifier_probe, group);
1596 if (ret)
1597 return ret;
1598 group->sys_enter_registered = 1;
1599 }
1600
1601 if (!group->sys_exit_registered) {
1602 ret = lttng_wrapper_tracepoint_probe_register("sys_exit",
1603 (void *) syscall_exit_event_notifier_probe, group);
1604 if (ret) {
1605 WARN_ON_ONCE(lttng_wrapper_tracepoint_probe_unregister("sys_enter",
1606 (void *) syscall_entry_event_notifier_probe, group));
1607 return ret;
1608 }
1609 group->sys_exit_registered = 1;
1610 }
1611
1612 return ret;
1613}
1614
1615static
1616int create_unknown_event_notifier(
1617 struct lttng_event_notifier_enabler *event_notifier_enabler,
1618 enum sc_type type)
1619{
a67ba386
MD
1620 struct lttng_kernel_event_notifier_private *event_notifier_priv;
1621 struct lttng_kernel_event_notifier *event_notifier;
437d5aa5 1622 const struct lttng_kernel_event_desc *desc;
8a8ac9a8 1623 struct lttng_event_notifier_group *group = event_notifier_enabler->group;
606828e4 1624 struct lttng_kernel_abi_event_notifier event_notifier_param;
8a8ac9a8 1625 uint64_t user_token = event_notifier_enabler->base.user_token;
99f52fcc 1626 uint64_t error_counter_index = event_notifier_enabler->error_counter_index;
8a8ac9a8
FD
1627 struct lttng_enabler *base_enabler = lttng_event_notifier_enabler_as_enabler(
1628 event_notifier_enabler);
1629 struct hlist_head *unknown_dispatch_list;
1630 int ret = 0;
1631 bool found = false;
606828e4
MD
1632 enum lttng_kernel_abi_syscall_abi abi;
1633 enum lttng_kernel_abi_syscall_entryexit entryexit;
8a8ac9a8
FD
1634 struct hlist_head *head;
1635
1636 switch (type) {
1637 case SC_TYPE_ENTRY:
1638 desc = &__event_desc___syscall_entry_unknown;
1639 unknown_dispatch_list = &group->event_notifier_unknown_syscall_dispatch;
606828e4
MD
1640 entryexit = LTTNG_KERNEL_ABI_SYSCALL_ENTRY;
1641 abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_NATIVE;
8a8ac9a8
FD
1642 break;
1643 case SC_TYPE_EXIT:
1644 desc = &__event_desc___syscall_exit_unknown;
1645 unknown_dispatch_list = &group->event_notifier_exit_unknown_syscall_dispatch;
606828e4
MD
1646 entryexit = LTTNG_KERNEL_ABI_SYSCALL_EXIT;
1647 abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_NATIVE;
8a8ac9a8
FD
1648 break;
1649 case SC_TYPE_COMPAT_ENTRY:
1650 desc = &__event_desc___compat_syscall_entry_unknown;
1651 unknown_dispatch_list = &group->event_notifier_compat_unknown_syscall_dispatch;
606828e4
MD
1652 entryexit = LTTNG_KERNEL_ABI_SYSCALL_ENTRY;
1653 abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_COMPAT;
8a8ac9a8
FD
1654 break;
1655 case SC_TYPE_COMPAT_EXIT:
1656 desc = &__event_desc___compat_syscall_exit_unknown;
1657 unknown_dispatch_list = &group->event_notifier_exit_compat_unknown_syscall_dispatch;
606828e4
MD
1658 entryexit = LTTNG_KERNEL_ABI_SYSCALL_EXIT;
1659 abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_COMPAT;
8a8ac9a8
FD
1660 break;
1661 default:
1662 BUG_ON(1);
1663 }
1664
1665 /*
1666 * Check if already created.
1667 */
1668 head = utils_borrow_hash_table_bucket(group->event_notifiers_ht.table,
437d5aa5 1669 LTTNG_EVENT_NOTIFIER_HT_SIZE, desc->event_name);
a67ba386
MD
1670 lttng_hlist_for_each_entry(event_notifier_priv, head, hlist) {
1671 if (event_notifier_priv->parent.desc == desc &&
1672 event_notifier_priv->parent.user_token == base_enabler->user_token)
8a8ac9a8
FD
1673 found = true;
1674 }
1675 if (found)
1676 goto end;
1677
1678 memset(&event_notifier_param, 0, sizeof(event_notifier_param));
437d5aa5 1679 strncat(event_notifier_param.event.name, desc->event_name,
606828e4 1680 LTTNG_KERNEL_ABI_SYM_NAME_LEN - strlen(event_notifier_param.event.name) - 1);
8a8ac9a8 1681
606828e4 1682 event_notifier_param.event.name[LTTNG_KERNEL_ABI_SYM_NAME_LEN - 1] = '\0';
8a8ac9a8 1683
606828e4 1684 event_notifier_param.event.instrumentation = LTTNG_KERNEL_ABI_SYSCALL;
8a8ac9a8
FD
1685 event_notifier_param.event.u.syscall.abi = abi;
1686 event_notifier_param.event.u.syscall.entryexit = entryexit;
1687
a67ba386
MD
1688 event_notifier = _lttng_event_notifier_create(desc, user_token,
1689 error_counter_index, group, &event_notifier_param,
8a8ac9a8 1690 event_notifier_param.event.instrumentation);
a67ba386 1691 if (IS_ERR(event_notifier)) {
8a8ac9a8 1692 printk(KERN_INFO "Unable to create unknown notifier %s\n",
437d5aa5 1693 desc->event_name);
8a8ac9a8
FD
1694 ret = -ENOMEM;
1695 goto end;
1696 }
1697
a67ba386 1698 hlist_add_head_rcu(&event_notifier->priv->parent.u.syscall.node, unknown_dispatch_list);
8a8ac9a8
FD
1699
1700end:
1701 return ret;
1702}
1703
1704static int create_matching_event_notifiers(
1705 struct lttng_event_notifier_enabler *event_notifier_enabler,
a67ba386 1706 const struct trace_syscall_entry *table,
8a8ac9a8
FD
1707 size_t table_len, enum sc_type type)
1708{
1709 struct lttng_event_notifier_group *group = event_notifier_enabler->group;
437d5aa5 1710 const struct lttng_kernel_event_desc *desc;
8a8ac9a8 1711 uint64_t user_token = event_notifier_enabler->base.user_token;
99f52fcc 1712 uint64_t error_counter_index = event_notifier_enabler->error_counter_index;
8a8ac9a8
FD
1713 unsigned int i;
1714 int ret = 0;
1715
1716 /* iterate over all syscall and create event_notifier that match */
1717 for (i = 0; i < table_len; i++) {
a67ba386
MD
1718 struct lttng_kernel_event_notifier_private *event_notifier_priv;
1719 struct lttng_kernel_event_notifier *event_notifier;
606828e4 1720 struct lttng_kernel_abi_event_notifier event_notifier_param;
8a8ac9a8
FD
1721 struct hlist_head *head;
1722 int found = 0;
1723
1724 desc = table[i].desc;
1725 if (!desc) {
1726 /* Unknown syscall */
1727 continue;
1728 }
1729
1730 if (!lttng_desc_match_enabler(desc,
1731 lttng_event_notifier_enabler_as_enabler(event_notifier_enabler)))
1732 continue;
1733
1734 /*
1735 * Check if already created.
1736 */
1737 head = utils_borrow_hash_table_bucket(group->event_notifiers_ht.table,
437d5aa5 1738 LTTNG_EVENT_NOTIFIER_HT_SIZE, desc->event_name);
a67ba386
MD
1739 lttng_hlist_for_each_entry(event_notifier_priv, head, hlist) {
1740 if (event_notifier_priv->parent.desc == desc
1741 && event_notifier_priv->parent.user_token == event_notifier_enabler->base.user_token)
8a8ac9a8
FD
1742 found = 1;
1743 }
1744 if (found)
1745 continue;
1746
1747 memset(&event_notifier_param, 0, sizeof(event_notifier_param));
1748 switch (type) {
1749 case SC_TYPE_ENTRY:
606828e4
MD
1750 event_notifier_param.event.u.syscall.entryexit = LTTNG_KERNEL_ABI_SYSCALL_ENTRY;
1751 event_notifier_param.event.u.syscall.abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_NATIVE;
8a8ac9a8
FD
1752 break;
1753 case SC_TYPE_EXIT:
606828e4
MD
1754 event_notifier_param.event.u.syscall.entryexit = LTTNG_KERNEL_ABI_SYSCALL_EXIT;
1755 event_notifier_param.event.u.syscall.abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_NATIVE;
8a8ac9a8
FD
1756 break;
1757 case SC_TYPE_COMPAT_ENTRY:
606828e4
MD
1758 event_notifier_param.event.u.syscall.entryexit = LTTNG_KERNEL_ABI_SYSCALL_ENTRY;
1759 event_notifier_param.event.u.syscall.abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_COMPAT;
8a8ac9a8
FD
1760 break;
1761 case SC_TYPE_COMPAT_EXIT:
606828e4
MD
1762 event_notifier_param.event.u.syscall.entryexit = LTTNG_KERNEL_ABI_SYSCALL_EXIT;
1763 event_notifier_param.event.u.syscall.abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_COMPAT;
8a8ac9a8
FD
1764 break;
1765 }
437d5aa5 1766 strncat(event_notifier_param.event.name, desc->event_name,
606828e4
MD
1767 LTTNG_KERNEL_ABI_SYM_NAME_LEN - strlen(event_notifier_param.event.name) - 1);
1768 event_notifier_param.event.name[LTTNG_KERNEL_ABI_SYM_NAME_LEN - 1] = '\0';
1769 event_notifier_param.event.instrumentation = LTTNG_KERNEL_ABI_SYSCALL;
8a8ac9a8 1770
99f52fcc
FD
1771 event_notifier = _lttng_event_notifier_create(desc, user_token,
1772 error_counter_index, group, &event_notifier_param,
a67ba386 1773 event_notifier_param.event.instrumentation);
8a8ac9a8
FD
1774 if (IS_ERR(event_notifier)) {
1775 printk(KERN_INFO "Unable to create event_notifier %s\n",
437d5aa5 1776 desc->event_name);
8a8ac9a8
FD
1777 ret = -ENOMEM;
1778 goto end;
1779 }
1780
a67ba386 1781 event_notifier->priv->parent.u.syscall.syscall_id = i;
8a8ac9a8
FD
1782 }
1783
1784end:
1785 return ret;
1786
1787}
1788
a67ba386
MD
1789int lttng_syscalls_create_matching_event_notifiers(
1790 struct lttng_event_notifier_enabler *event_notifier_enabler)
8a8ac9a8
FD
1791{
1792 int ret;
1793 struct lttng_enabler *base_enabler =
1794 lttng_event_notifier_enabler_as_enabler(event_notifier_enabler);
606828e4 1795 enum lttng_kernel_abi_syscall_entryexit entryexit =
8a8ac9a8
FD
1796 base_enabler->event_param.u.syscall.entryexit;
1797
606828e4 1798 if (entryexit == LTTNG_KERNEL_ABI_SYSCALL_ENTRY || entryexit == LTTNG_KERNEL_ABI_SYSCALL_ENTRYEXIT) {
8a8ac9a8 1799 ret = create_matching_event_notifiers(event_notifier_enabler,
a67ba386 1800 sc_table, ARRAY_SIZE(sc_table), SC_TYPE_ENTRY);
8a8ac9a8
FD
1801 if (ret)
1802 goto end;
1803
1804 ret = create_matching_event_notifiers(event_notifier_enabler,
a67ba386 1805 compat_sc_table, ARRAY_SIZE(compat_sc_table),
8a8ac9a8
FD
1806 SC_TYPE_COMPAT_ENTRY);
1807 if (ret)
1808 goto end;
1809
1810 ret = create_unknown_event_notifier(event_notifier_enabler,
1811 SC_TYPE_ENTRY);
1812 if (ret)
1813 goto end;
1814
1815 ret = create_unknown_event_notifier(event_notifier_enabler,
1816 SC_TYPE_COMPAT_ENTRY);
1817 if (ret)
1818 goto end;
1819 }
1820
606828e4 1821 if (entryexit == LTTNG_KERNEL_ABI_SYSCALL_EXIT || entryexit == LTTNG_KERNEL_ABI_SYSCALL_ENTRYEXIT) {
8a8ac9a8 1822 ret = create_matching_event_notifiers(event_notifier_enabler,
a67ba386 1823 sc_exit_table, ARRAY_SIZE(sc_exit_table),
8a8ac9a8
FD
1824 SC_TYPE_EXIT);
1825 if (ret)
1826 goto end;
1827
1828 ret = create_unknown_event_notifier(event_notifier_enabler,
1829 SC_TYPE_EXIT);
1830 if (ret)
1831 goto end;
1832
1833 ret = create_matching_event_notifiers(event_notifier_enabler,
a67ba386 1834 compat_sc_exit_table, ARRAY_SIZE(compat_sc_exit_table),
8a8ac9a8
FD
1835 SC_TYPE_COMPAT_EXIT);
1836 if (ret)
1837 goto end;
1838
1839 ret = create_unknown_event_notifier(event_notifier_enabler,
1840 SC_TYPE_COMPAT_EXIT);
1841 if (ret)
1842 goto end;
1843 }
1844
1845end:
1846 return ret;
1847}
1848
1849/*
1850 * Unregister the syscall event_notifier probes from the callsites.
259b6cb3 1851 */
3b82c4e1 1852int lttng_syscalls_unregister_event_notifier_group(
8a8ac9a8
FD
1853 struct lttng_event_notifier_group *event_notifier_group)
1854{
1855 int ret;
1856
1857 /*
1858 * Only register the event_notifier probe on the `sys_enter` callsite for now.
1859 * At the moment, we don't think it's desirable to have one fired
1860 * event_notifier for the entry and one for the exit of a syscall.
1861 */
1862 if (event_notifier_group->sys_enter_registered) {
1863 ret = lttng_wrapper_tracepoint_probe_unregister("sys_enter",
1864 (void *) syscall_entry_event_notifier_probe, event_notifier_group);
1865 if (ret)
1866 return ret;
1867 event_notifier_group->sys_enter_registered = 0;
1868 }
1869 if (event_notifier_group->sys_exit_registered) {
1870 ret = lttng_wrapper_tracepoint_probe_unregister("sys_exit",
1871 (void *) syscall_exit_event_notifier_probe, event_notifier_group);
1872 if (ret)
1873 return ret;
1874 event_notifier_group->sys_enter_registered = 0;
1875 }
1876
1877 kfree(event_notifier_group->event_notifier_syscall_dispatch);
1878 kfree(event_notifier_group->event_notifier_exit_syscall_dispatch);
1879#ifdef CONFIG_COMPAT
1880 kfree(event_notifier_group->event_notifier_compat_syscall_dispatch);
1881 kfree(event_notifier_group->event_notifier_exit_compat_syscall_dispatch);
1882#endif
1883 return 0;
1884}
1885
3b82c4e1 1886int lttng_syscalls_unregister_channel(struct lttng_channel *chan)
259b6cb3
MD
1887{
1888 int ret;
1889
1890 if (!chan->sc_table)
1891 return 0;
80f87dd2 1892 if (chan->sys_enter_registered) {
2d9cd7f3 1893 ret = lttng_wrapper_tracepoint_probe_unregister("sys_enter",
2d6d88c6 1894 (void *) syscall_entry_event_probe, chan);
80f87dd2
MD
1895 if (ret)
1896 return ret;
1897 chan->sys_enter_registered = 0;
1898 }
1899 if (chan->sys_exit_registered) {
2d9cd7f3 1900 ret = lttng_wrapper_tracepoint_probe_unregister("sys_exit",
2d6d88c6 1901 (void *) syscall_exit_event_probe, chan);
80f87dd2
MD
1902 if (ret)
1903 return ret;
1904 chan->sys_exit_registered = 0;
1905 }
badfe9f5
MD
1906 return 0;
1907}
1908
2d6d88c6 1909int lttng_syscalls_destroy_event(struct lttng_channel *chan)
badfe9f5 1910{
259b6cb3 1911 kfree(chan->sc_table);
5b7ac358 1912 kfree(chan->sc_exit_table);
49c50022
MD
1913#ifdef CONFIG_COMPAT
1914 kfree(chan->compat_sc_table);
5b7ac358 1915 kfree(chan->compat_sc_exit_table);
49c50022 1916#endif
80f87dd2
MD
1917 kfree(chan->sc_filter);
1918 return 0;
1919}
1920
1921static
1922int get_syscall_nr(const char *syscall_name)
1923{
1924 int syscall_nr = -1;
1925 int i;
1926
1927 for (i = 0; i < ARRAY_SIZE(sc_table); i++) {
1928 const struct trace_syscall_entry *entry;
5b7ac358 1929 const char *it_name;
80f87dd2
MD
1930
1931 entry = &sc_table[i];
1932 if (!entry->desc)
1933 continue;
437d5aa5 1934 it_name = entry->desc->event_name;
5b7ac358
MD
1935 it_name += strlen(SYSCALL_ENTRY_STR);
1936 if (!strcmp(syscall_name, it_name)) {
80f87dd2
MD
1937 syscall_nr = i;
1938 break;
1939 }
1940 }
1941 return syscall_nr;
1942}
1943
1944static
1945int get_compat_syscall_nr(const char *syscall_name)
1946{
1947 int syscall_nr = -1;
1948 int i;
1949
1950 for (i = 0; i < ARRAY_SIZE(compat_sc_table); i++) {
1951 const struct trace_syscall_entry *entry;
5b7ac358 1952 const char *it_name;
80f87dd2
MD
1953
1954 entry = &compat_sc_table[i];
1955 if (!entry->desc)
1956 continue;
437d5aa5 1957 it_name = entry->desc->event_name;
5b7ac358
MD
1958 it_name += strlen(COMPAT_SYSCALL_ENTRY_STR);
1959 if (!strcmp(syscall_name, it_name)) {
80f87dd2
MD
1960 syscall_nr = i;
1961 break;
1962 }
1963 }
1964 return syscall_nr;
1965}
1966
12e579db
MD
1967static
1968uint32_t get_sc_tables_len(void)
1969{
1970 return ARRAY_SIZE(sc_table) + ARRAY_SIZE(compat_sc_table);
1971}
1972
badfe9f5 1973static
ade8a729
FD
1974const char *get_syscall_name(const char *desc_name,
1975 enum lttng_syscall_abi abi,
1976 enum lttng_syscall_entryexit entryexit)
80f87dd2 1977{
badfe9f5 1978 size_t prefix_len = 0;
80f87dd2 1979
80f87dd2 1980
ade8a729 1981 switch (entryexit) {
badfe9f5 1982 case LTTNG_SYSCALL_ENTRY:
ade8a729 1983 switch (abi) {
badfe9f5
MD
1984 case LTTNG_SYSCALL_ABI_NATIVE:
1985 prefix_len = strlen(SYSCALL_ENTRY_STR);
1986 break;
1987 case LTTNG_SYSCALL_ABI_COMPAT:
1988 prefix_len = strlen(COMPAT_SYSCALL_ENTRY_STR);
1989 break;
80f87dd2 1990 }
badfe9f5
MD
1991 break;
1992 case LTTNG_SYSCALL_EXIT:
ade8a729 1993 switch (abi) {
badfe9f5
MD
1994 case LTTNG_SYSCALL_ABI_NATIVE:
1995 prefix_len = strlen(SYSCALL_EXIT_STR);
1996 break;
1997 case LTTNG_SYSCALL_ABI_COMPAT:
1998 prefix_len = strlen(COMPAT_SYSCALL_EXIT_STR);
1999 break;
80f87dd2 2000 }
badfe9f5 2001 break;
80f87dd2 2002 }
badfe9f5 2003 WARN_ON_ONCE(prefix_len == 0);
ade8a729 2004 return desc_name + prefix_len;
badfe9f5
MD
2005}
2006
ade8a729
FD
2007static
2008int lttng_syscall_filter_enable(
2009 struct lttng_syscall_filter *filter,
2010 const char *desc_name, enum lttng_syscall_abi abi,
2011 enum lttng_syscall_entryexit entryexit)
badfe9f5 2012{
badfe9f5
MD
2013 const char *syscall_name;
2014 unsigned long *bitmap;
2015 int syscall_nr;
2016
ade8a729 2017 syscall_name = get_syscall_name(desc_name, abi, entryexit);
badfe9f5 2018
ade8a729 2019 switch (abi) {
badfe9f5
MD
2020 case LTTNG_SYSCALL_ABI_NATIVE:
2021 syscall_nr = get_syscall_nr(syscall_name);
2022 break;
2023 case LTTNG_SYSCALL_ABI_COMPAT:
2024 syscall_nr = get_compat_syscall_nr(syscall_name);
2025 break;
2026 default:
2027 return -EINVAL;
80f87dd2 2028 }
badfe9f5
MD
2029 if (syscall_nr < 0)
2030 return -ENOENT;
2031
ade8a729 2032 switch (entryexit) {
badfe9f5 2033 case LTTNG_SYSCALL_ENTRY:
ade8a729 2034 switch (abi) {
badfe9f5
MD
2035 case LTTNG_SYSCALL_ABI_NATIVE:
2036 bitmap = filter->sc_entry;
2037 break;
2038 case LTTNG_SYSCALL_ABI_COMPAT:
2039 bitmap = filter->sc_compat_entry;
2040 break;
6d9694d8
MD
2041 default:
2042 return -EINVAL;
80f87dd2 2043 }
badfe9f5
MD
2044 break;
2045 case LTTNG_SYSCALL_EXIT:
ade8a729 2046 switch (abi) {
badfe9f5
MD
2047 case LTTNG_SYSCALL_ABI_NATIVE:
2048 bitmap = filter->sc_exit;
2049 break;
2050 case LTTNG_SYSCALL_ABI_COMPAT:
2051 bitmap = filter->sc_compat_exit;
2052 break;
6d9694d8
MD
2053 default:
2054 return -EINVAL;
80f87dd2 2055 }
badfe9f5
MD
2056 break;
2057 default:
2058 return -EINVAL;
80f87dd2 2059 }
badfe9f5
MD
2060 if (test_bit(syscall_nr, bitmap))
2061 return -EEXIST;
2062 bitmap_set(bitmap, syscall_nr, 1);
80f87dd2 2063 return 0;
80f87dd2
MD
2064}
2065
8a8ac9a8 2066int lttng_syscall_filter_enable_event_notifier(
a67ba386 2067 struct lttng_kernel_event_notifier *event_notifier)
8a8ac9a8 2068{
a67ba386
MD
2069 struct lttng_event_notifier_group *group = event_notifier->priv->group;
2070 unsigned int syscall_id = event_notifier->priv->parent.u.syscall.syscall_id;
8a8ac9a8
FD
2071 struct hlist_head *dispatch_list;
2072 int ret = 0;
2073
a67ba386 2074 WARN_ON_ONCE(event_notifier->priv->parent.instrumentation != LTTNG_KERNEL_ABI_SYSCALL);
8a8ac9a8
FD
2075
2076 ret = lttng_syscall_filter_enable(group->sc_filter,
a67ba386
MD
2077 event_notifier->priv->parent.desc->event_name,
2078 event_notifier->priv->parent.u.syscall.abi,
2079 event_notifier->priv->parent.u.syscall.entryexit);
8a8ac9a8
FD
2080 if (ret) {
2081 goto end;
2082 }
2083
a67ba386 2084 switch (event_notifier->priv->parent.u.syscall.entryexit) {
8a8ac9a8 2085 case LTTNG_SYSCALL_ENTRY:
a67ba386 2086 switch (event_notifier->priv->parent.u.syscall.abi) {
8a8ac9a8
FD
2087 case LTTNG_SYSCALL_ABI_NATIVE:
2088 dispatch_list = &group->event_notifier_syscall_dispatch[syscall_id];
2089 break;
2090 case LTTNG_SYSCALL_ABI_COMPAT:
2091 dispatch_list = &group->event_notifier_compat_syscall_dispatch[syscall_id];
2092 break;
6866b1c7
MJ
2093 default:
2094 ret = -EINVAL;
2095 goto end;
8a8ac9a8
FD
2096 }
2097 break;
2098 case LTTNG_SYSCALL_EXIT:
a67ba386 2099 switch (event_notifier->priv->parent.u.syscall.abi) {
8a8ac9a8
FD
2100 case LTTNG_SYSCALL_ABI_NATIVE:
2101 dispatch_list = &group->event_notifier_exit_syscall_dispatch[syscall_id];
2102 break;
2103 case LTTNG_SYSCALL_ABI_COMPAT:
2104 dispatch_list = &group->event_notifier_exit_compat_syscall_dispatch[syscall_id];
2105 break;
6866b1c7
MJ
2106 default:
2107 ret = -EINVAL;
2108 goto end;
8a8ac9a8
FD
2109 }
2110 break;
6866b1c7
MJ
2111 default:
2112 ret = -EINVAL;
2113 goto end;
8a8ac9a8
FD
2114 }
2115
a67ba386 2116 hlist_add_head_rcu(&event_notifier->priv->parent.u.syscall.node, dispatch_list);
8a8ac9a8
FD
2117
2118end:
2119 return ret ;
2120}
2121
ade8a729
FD
2122int lttng_syscall_filter_enable_event(
2123 struct lttng_channel *channel,
a67ba386 2124 struct lttng_kernel_event_recorder *event_recorder)
80f87dd2 2125{
a67ba386 2126 WARN_ON_ONCE(event_recorder->priv->parent.instrumentation != LTTNG_KERNEL_ABI_SYSCALL);
ade8a729
FD
2127
2128 return lttng_syscall_filter_enable(channel->sc_filter,
a67ba386
MD
2129 event_recorder->priv->parent.desc->event_name,
2130 event_recorder->priv->parent.u.syscall.abi,
2131 event_recorder->priv->parent.u.syscall.entryexit);
ade8a729
FD
2132}
2133
2134static
2135int lttng_syscall_filter_disable(
2136 struct lttng_syscall_filter *filter,
2137 const char *desc_name, enum lttng_syscall_abi abi,
2138 enum lttng_syscall_entryexit entryexit)
2139{
badfe9f5
MD
2140 const char *syscall_name;
2141 unsigned long *bitmap;
2142 int syscall_nr;
80f87dd2 2143
ade8a729 2144 syscall_name = get_syscall_name(desc_name, abi, entryexit);
80f87dd2 2145
ade8a729 2146 switch (abi) {
badfe9f5
MD
2147 case LTTNG_SYSCALL_ABI_NATIVE:
2148 syscall_nr = get_syscall_nr(syscall_name);
2149 break;
2150 case LTTNG_SYSCALL_ABI_COMPAT:
2151 syscall_nr = get_compat_syscall_nr(syscall_name);
2152 break;
2153 default:
2154 return -EINVAL;
80f87dd2 2155 }
badfe9f5
MD
2156 if (syscall_nr < 0)
2157 return -ENOENT;
80f87dd2 2158
ade8a729 2159 switch (entryexit) {
badfe9f5 2160 case LTTNG_SYSCALL_ENTRY:
ade8a729 2161 switch (abi) {
badfe9f5
MD
2162 case LTTNG_SYSCALL_ABI_NATIVE:
2163 bitmap = filter->sc_entry;
2164 break;
2165 case LTTNG_SYSCALL_ABI_COMPAT:
2166 bitmap = filter->sc_compat_entry;
2167 break;
6d9694d8
MD
2168 default:
2169 return -EINVAL;
80f87dd2 2170 }
badfe9f5
MD
2171 break;
2172 case LTTNG_SYSCALL_EXIT:
ade8a729 2173 switch (abi) {
badfe9f5
MD
2174 case LTTNG_SYSCALL_ABI_NATIVE:
2175 bitmap = filter->sc_exit;
2176 break;
2177 case LTTNG_SYSCALL_ABI_COMPAT:
2178 bitmap = filter->sc_compat_exit;
2179 break;
6d9694d8
MD
2180 default:
2181 return -EINVAL;
80f87dd2 2182 }
badfe9f5
MD
2183 break;
2184 default:
2185 return -EINVAL;
80f87dd2 2186 }
badfe9f5
MD
2187 if (!test_bit(syscall_nr, bitmap))
2188 return -EEXIST;
2189 bitmap_clear(bitmap, syscall_nr, 1);
80f87dd2 2190
badfe9f5 2191 return 0;
259b6cb3 2192}
2d2464bd 2193
8a8ac9a8 2194int lttng_syscall_filter_disable_event_notifier(
a67ba386 2195 struct lttng_kernel_event_notifier *event_notifier)
8a8ac9a8 2196{
a67ba386 2197 struct lttng_event_notifier_group *group = event_notifier->priv->group;
8a8ac9a8
FD
2198 int ret;
2199
a67ba386 2200 WARN_ON_ONCE(event_notifier->priv->parent.instrumentation != LTTNG_KERNEL_ABI_SYSCALL);
8a8ac9a8
FD
2201
2202 ret = lttng_syscall_filter_disable(group->sc_filter,
a67ba386
MD
2203 event_notifier->priv->parent.desc->event_name,
2204 event_notifier->priv->parent.u.syscall.abi,
2205 event_notifier->priv->parent.u.syscall.entryexit);
8a8ac9a8
FD
2206 WARN_ON_ONCE(ret != 0);
2207
a67ba386 2208 hlist_del_rcu(&event_notifier->priv->parent.u.syscall.node);
8a8ac9a8
FD
2209 return 0;
2210}
2211
ade8a729
FD
2212int lttng_syscall_filter_disable_event(
2213 struct lttng_channel *channel,
a67ba386 2214 struct lttng_kernel_event_recorder *event_recorder)
ade8a729
FD
2215{
2216 return lttng_syscall_filter_disable(channel->sc_filter,
a67ba386
MD
2217 event_recorder->priv->parent.desc->event_name,
2218 event_recorder->priv->parent.u.syscall.abi,
2219 event_recorder->priv->parent.u.syscall.entryexit);
ade8a729
FD
2220}
2221
2d2464bd
MD
2222static
2223const struct trace_syscall_entry *syscall_list_get_entry(loff_t *pos)
2224{
2225 const struct trace_syscall_entry *entry;
2226 int iter = 0;
2227
2228 for (entry = sc_table;
2229 entry < sc_table + ARRAY_SIZE(sc_table);
2230 entry++) {
2231 if (iter++ >= *pos)
2232 return entry;
2233 }
2234 for (entry = compat_sc_table;
2235 entry < compat_sc_table + ARRAY_SIZE(compat_sc_table);
2236 entry++) {
2237 if (iter++ >= *pos)
2238 return entry;
2239 }
2240 /* End of list */
2241 return NULL;
2242}
2243
2244static
2245void *syscall_list_start(struct seq_file *m, loff_t *pos)
2246{
2247 return (void *) syscall_list_get_entry(pos);
2248}
2249
2250static
2251void *syscall_list_next(struct seq_file *m, void *p, loff_t *ppos)
2252{
2253 (*ppos)++;
2254 return (void *) syscall_list_get_entry(ppos);
2255}
2256
2257static
2258void syscall_list_stop(struct seq_file *m, void *p)
2259{
2260}
2261
12e579db
MD
2262static
2263int get_sc_table(const struct trace_syscall_entry *entry,
2264 const struct trace_syscall_entry **table,
2265 unsigned int *bitness)
2266{
2267 if (entry >= sc_table && entry < sc_table + ARRAY_SIZE(sc_table)) {
2268 if (bitness)
2269 *bitness = BITS_PER_LONG;
2270 if (table)
2271 *table = sc_table;
2272 return 0;
2273 }
2274 if (!(entry >= compat_sc_table
2275 && entry < compat_sc_table + ARRAY_SIZE(compat_sc_table))) {
2276 return -EINVAL;
2277 }
2278 if (bitness)
2279 *bitness = 32;
2280 if (table)
2281 *table = compat_sc_table;
2282 return 0;
2283}
2284
2d2464bd
MD
2285static
2286int syscall_list_show(struct seq_file *m, void *p)
2287{
2288 const struct trace_syscall_entry *table, *entry = p;
2289 unsigned int bitness;
d4291869 2290 unsigned long index;
12e579db 2291 int ret;
d4291869 2292 const char *name;
2d2464bd 2293
12e579db
MD
2294 ret = get_sc_table(entry, &table, &bitness);
2295 if (ret)
2296 return ret;
f4855b46
MD
2297 if (!entry->desc)
2298 return 0;
d4291869
MD
2299 if (table == sc_table) {
2300 index = entry - table;
437d5aa5 2301 name = &entry->desc->event_name[strlen(SYSCALL_ENTRY_STR)];
d4291869
MD
2302 } else {
2303 index = (entry - table) + ARRAY_SIZE(sc_table);
437d5aa5 2304 name = &entry->desc->event_name[strlen(COMPAT_SYSCALL_ENTRY_STR)];
d4291869 2305 }
12e579db 2306 seq_printf(m, "syscall { index = %lu; name = %s; bitness = %u; };\n",
d4291869 2307 index, name, bitness);
2d2464bd
MD
2308 return 0;
2309}
2310
2311static
2312const struct seq_operations lttng_syscall_list_seq_ops = {
2313 .start = syscall_list_start,
2314 .next = syscall_list_next,
2315 .stop = syscall_list_stop,
2316 .show = syscall_list_show,
2317};
2318
2319static
2320int lttng_syscall_list_open(struct inode *inode, struct file *file)
2321{
2322 return seq_open(file, &lttng_syscall_list_seq_ops);
2323}
2324
2325const struct file_operations lttng_syscall_list_fops = {
2326 .owner = THIS_MODULE,
2327 .open = lttng_syscall_list_open,
2328 .read = seq_read,
2329 .llseek = seq_lseek,
2330 .release = seq_release,
2331};
12e579db 2332
badfe9f5
MD
2333/*
2334 * A syscall is enabled if it is traced for either entry or exit.
2335 */
12e579db 2336long lttng_channel_syscall_mask(struct lttng_channel *channel,
606828e4 2337 struct lttng_kernel_abi_syscall_mask __user *usyscall_mask)
12e579db
MD
2338{
2339 uint32_t len, sc_tables_len, bitmask_len;
2340 int ret = 0, bit;
2341 char *tmp_mask;
2342 struct lttng_syscall_filter *filter;
2343
2344 ret = get_user(len, &usyscall_mask->len);
2345 if (ret)
2346 return ret;
2347 sc_tables_len = get_sc_tables_len();
2348 bitmask_len = ALIGN(sc_tables_len, 8) >> 3;
2349 if (len < sc_tables_len) {
2350 return put_user(sc_tables_len, &usyscall_mask->len);
2351 }
2352 /* Array is large enough, we can copy array to user-space. */
2353 tmp_mask = kzalloc(bitmask_len, GFP_KERNEL);
2354 if (!tmp_mask)
2355 return -ENOMEM;
2356 filter = channel->sc_filter;
2357
2358 for (bit = 0; bit < ARRAY_SIZE(sc_table); bit++) {
e2129868 2359 char state;
2f25059d
MD
2360
2361 if (channel->sc_table) {
3b82c4e1
MD
2362 if (!(READ_ONCE(channel->syscall_all_entry)
2363 || READ_ONCE(channel->syscall_all_exit)) && filter)
badfe9f5
MD
2364 state = test_bit(bit, filter->sc_entry)
2365 || test_bit(bit, filter->sc_exit);
2f25059d
MD
2366 else
2367 state = 1;
2368 } else {
2369 state = 0;
2370 }
2371 bt_bitfield_write_be(tmp_mask, char, bit, 1, state);
12e579db
MD
2372 }
2373 for (; bit < sc_tables_len; bit++) {
e2129868 2374 char state;
2f25059d
MD
2375
2376 if (channel->compat_sc_table) {
3b82c4e1
MD
2377 if (!(READ_ONCE(channel->syscall_all_entry)
2378 || READ_ONCE(channel->syscall_all_exit)) && filter)
2f25059d 2379 state = test_bit(bit - ARRAY_SIZE(sc_table),
badfe9f5
MD
2380 filter->sc_compat_entry)
2381 || test_bit(bit - ARRAY_SIZE(sc_table),
2382 filter->sc_compat_exit);
2f25059d
MD
2383 else
2384 state = 1;
2385 } else {
2386 state = 0;
2387 }
2388 bt_bitfield_write_be(tmp_mask, char, bit, 1, state);
12e579db
MD
2389 }
2390 if (copy_to_user(usyscall_mask->mask, tmp_mask, bitmask_len))
2391 ret = -EFAULT;
2392 kfree(tmp_mask);
2393 return ret;
2394}
082d4946
MD
2395
2396int lttng_abi_syscall_list(void)
2397{
2398 struct file *syscall_list_file;
2399 int file_fd, ret;
2400
4ac10b76 2401 file_fd = lttng_get_unused_fd();
082d4946
MD
2402 if (file_fd < 0) {
2403 ret = file_fd;
2404 goto fd_error;
2405 }
2406
2407 syscall_list_file = anon_inode_getfile("[lttng_syscall_list]",
2408 &lttng_syscall_list_fops,
2409 NULL, O_RDWR);
2410 if (IS_ERR(syscall_list_file)) {
2411 ret = PTR_ERR(syscall_list_file);
2412 goto file_error;
2413 }
2414 ret = lttng_syscall_list_fops.open(NULL, syscall_list_file);
2415 if (ret < 0)
2416 goto open_error;
2417 fd_install(file_fd, syscall_list_file);
082d4946
MD
2418 return file_fd;
2419
2420open_error:
2421 fput(syscall_list_file);
2422file_error:
2423 put_unused_fd(file_fd);
2424fd_error:
2425 return ret;
2426}
This page took 0.207311 seconds and 4 git commands to generate.