Rename struct lttng_probe_ctx to struct lttng_kernel_probe_ctx
[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;
437d5aa5
MD
296 const struct lttng_kernel_event_desc *desc;
297 const struct lttng_kernel_event_field **fields;
a93244f8
MD
298 unsigned int nrargs;
299};
300
301#define CREATE_SYSCALL_TABLE
302
fc4f7161
MD
303#define SC_ENTER
304
305#undef sc_exit
306#define sc_exit(...)
307
259b6cb3 308#undef TRACE_SYSCALL_TABLE
f7bdf4db 309#define TRACE_SYSCALL_TABLE(_template, _name, _nr, _nrargs) \
259b6cb3 310 [ _nr ] = { \
2d6d88c6 311 .event_func = __event_probe__syscall_entry_##_template, \
259b6cb3 312 .nrargs = (_nrargs), \
d4291869
MD
313 .fields = __event_fields___syscall_entry_##_template, \
314 .desc = &__event_desc___syscall_entry_##_name, \
259b6cb3
MD
315 },
316
2d6d88c6 317/* Event syscall enter tracing table */
49c50022 318static const struct trace_syscall_entry sc_table[] = {
241ae9a8
MD
319#include <instrumentation/syscalls/headers/syscalls_integers.h>
320#include <instrumentation/syscalls/headers/syscalls_pointers.h>
259b6cb3
MD
321};
322
a93244f8
MD
323#undef TRACE_SYSCALL_TABLE
324#define TRACE_SYSCALL_TABLE(_template, _name, _nr, _nrargs) \
325 [ _nr ] = { \
2d6d88c6 326 .event_func = __event_probe__compat_syscall_entry_##_template, \
a93244f8 327 .nrargs = (_nrargs), \
d4291869
MD
328 .fields = __event_fields___compat_syscall_entry_##_template, \
329 .desc = &__event_desc___compat_syscall_entry_##_name, \
a93244f8
MD
330 },
331
2d6d88c6 332/* Event compat syscall enter table */
a93244f8 333const struct trace_syscall_entry compat_sc_table[] = {
241ae9a8
MD
334#include <instrumentation/syscalls/headers/compat_syscalls_integers.h>
335#include <instrumentation/syscalls/headers/compat_syscalls_pointers.h>
a93244f8 336};
259b6cb3 337
fc4f7161
MD
338#undef SC_ENTER
339
340#define SC_EXIT
341
342#undef sc_exit
343#define sc_exit(...) __VA_ARGS__
344
5b7ac358
MD
345#undef TRACE_SYSCALL_TABLE
346#define TRACE_SYSCALL_TABLE(_template, _name, _nr, _nrargs) \
347 [ _nr ] = { \
2d6d88c6 348 .event_func = __event_probe__syscall_exit_##_template, \
5b7ac358
MD
349 .nrargs = (_nrargs), \
350 .fields = __event_fields___syscall_exit_##_template, \
351 .desc = &__event_desc___syscall_exit_##_name, \
352 },
353
2d6d88c6 354/* Event syscall exit table */
5b7ac358 355static const struct trace_syscall_entry sc_exit_table[] = {
241ae9a8
MD
356#include <instrumentation/syscalls/headers/syscalls_integers.h>
357#include <instrumentation/syscalls/headers/syscalls_pointers.h>
5b7ac358
MD
358};
359
360#undef TRACE_SYSCALL_TABLE
361#define TRACE_SYSCALL_TABLE(_template, _name, _nr, _nrargs) \
362 [ _nr ] = { \
2d6d88c6 363 .event_func = __event_probe__compat_syscall_exit_##_template, \
5b7ac358
MD
364 .nrargs = (_nrargs), \
365 .fields = __event_fields___compat_syscall_exit_##_template, \
366 .desc = &__event_desc___compat_syscall_exit_##_name, \
367 },
368
2d6d88c6 369/* Event compat syscall exit table */
5b7ac358 370const struct trace_syscall_entry compat_sc_exit_table[] = {
241ae9a8
MD
371#include <instrumentation/syscalls/headers/compat_syscalls_integers.h>
372#include <instrumentation/syscalls/headers/compat_syscalls_pointers.h>
5b7ac358
MD
373};
374
fc4f7161
MD
375#undef SC_EXIT
376
a93244f8 377#undef CREATE_SYSCALL_TABLE
2faf7d1b 378
80f87dd2 379struct lttng_syscall_filter {
badfe9f5
MD
380 DECLARE_BITMAP(sc_entry, NR_syscalls);
381 DECLARE_BITMAP(sc_exit, NR_syscalls);
382 DECLARE_BITMAP(sc_compat_entry, NR_compat_syscalls);
383 DECLARE_BITMAP(sc_compat_exit, NR_compat_syscalls);
80f87dd2
MD
384};
385
3b82c4e1 386static void syscall_entry_event_unknown(struct hlist_head *unknown_action_list_head,
8a8ac9a8 387 struct pt_regs *regs, long id)
f405cfce 388{
1b7b9c65 389 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
a67ba386 390 struct lttng_kernel_event_common_private *event_priv;
f405cfce 391
1b7b9c65 392 lttng_syscall_get_arguments(current, regs, args);
a67ba386 393 lttng_hlist_for_each_entry_rcu(event_priv, unknown_action_list_head, u.syscall.node) {
8a8ac9a8 394 if (unlikely(in_compat_syscall()))
e2d5dbc7 395 __event_probe__compat_syscall_entry_unknown(event_priv->pub, id, args);
8a8ac9a8 396 else
e2d5dbc7 397 __event_probe__syscall_entry_unknown(event_priv->pub, id, args);
8a8ac9a8
FD
398 }
399}
400
63aa9160 401static __always_inline
e2d5dbc7 402void syscall_entry_event_call_func(struct hlist_head *action_list,
3b82c4e1 403 void *func, unsigned int nrargs,
63aa9160 404 struct pt_regs *regs)
259b6cb3 405{
a67ba386 406 struct lttng_kernel_event_common_private *event_priv;
3b82c4e1 407
63aa9160 408 switch (nrargs) {
259b6cb3
MD
409 case 0:
410 {
63aa9160 411 void (*fptr)(void *__data) = func;
259b6cb3 412
e2d5dbc7
MD
413 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node)
414 fptr(event_priv->pub);
259b6cb3
MD
415 break;
416 }
417 case 1:
418 {
63aa9160 419 void (*fptr)(void *__data, unsigned long arg0) = func;
1b7b9c65 420 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
259b6cb3 421
1b7b9c65 422 lttng_syscall_get_arguments(current, regs, args);
e2d5dbc7
MD
423 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node)
424 fptr(event_priv->pub, args[0]);
259b6cb3
MD
425 break;
426 }
427 case 2:
428 {
429 void (*fptr)(void *__data,
430 unsigned long arg0,
63aa9160 431 unsigned long arg1) = func;
1b7b9c65 432 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
259b6cb3 433
1b7b9c65 434 lttng_syscall_get_arguments(current, regs, args);
e2d5dbc7
MD
435 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node)
436 fptr(event_priv->pub, args[0], args[1]);
259b6cb3
MD
437 break;
438 }
439 case 3:
440 {
441 void (*fptr)(void *__data,
442 unsigned long arg0,
443 unsigned long arg1,
63aa9160 444 unsigned long arg2) = func;
1b7b9c65 445 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
259b6cb3 446
1b7b9c65 447 lttng_syscall_get_arguments(current, regs, args);
e2d5dbc7
MD
448 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node)
449 fptr(event_priv->pub, args[0], args[1], args[2]);
259b6cb3
MD
450 break;
451 }
452 case 4:
453 {
454 void (*fptr)(void *__data,
455 unsigned long arg0,
456 unsigned long arg1,
457 unsigned long arg2,
63aa9160 458 unsigned long arg3) = func;
1b7b9c65 459 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
259b6cb3 460
1b7b9c65 461 lttng_syscall_get_arguments(current, regs, args);
e2d5dbc7
MD
462 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node)
463 fptr(event_priv->pub, args[0], args[1], args[2], args[3]);
259b6cb3
MD
464 break;
465 }
466 case 5:
467 {
468 void (*fptr)(void *__data,
469 unsigned long arg0,
470 unsigned long arg1,
471 unsigned long arg2,
472 unsigned long arg3,
63aa9160 473 unsigned long arg4) = func;
1b7b9c65 474 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
259b6cb3 475
1b7b9c65 476 lttng_syscall_get_arguments(current, regs, args);
e2d5dbc7
MD
477 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node)
478 fptr(event_priv->pub, args[0], args[1], args[2], args[3], args[4]);
259b6cb3
MD
479 break;
480 }
481 case 6:
482 {
483 void (*fptr)(void *__data,
484 unsigned long arg0,
485 unsigned long arg1,
486 unsigned long arg2,
487 unsigned long arg3,
488 unsigned long arg4,
63aa9160 489 unsigned long arg5) = func;
1b7b9c65 490 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
259b6cb3 491
1b7b9c65 492 lttng_syscall_get_arguments(current, regs, args);
e2d5dbc7
MD
493 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node)
494 fptr(event_priv->pub, args[0], args[1], args[2],
3b82c4e1 495 args[3], args[4], args[5]);
8a8ac9a8
FD
496 break;
497 }
498 default:
499 break;
500 }
501}
502
63aa9160
FD
503void syscall_entry_event_probe(void *__data, struct pt_regs *regs, long id)
504{
505 struct lttng_channel *chan = __data;
3b82c4e1 506 struct hlist_head *action_list, *unknown_action_list;
63aa9160
FD
507 const struct trace_syscall_entry *table, *entry;
508 size_t table_len;
509
510 if (unlikely(in_compat_syscall())) {
511 struct lttng_syscall_filter *filter = chan->sc_filter;
512
513 if (id < 0 || id >= NR_compat_syscalls
3b82c4e1 514 || (!READ_ONCE(chan->syscall_all_entry) && !test_bit(id, filter->sc_compat_entry))) {
63aa9160
FD
515 /* System call filtered out. */
516 return;
517 }
518 table = compat_sc_table;
519 table_len = ARRAY_SIZE(compat_sc_table);
3b82c4e1 520 unknown_action_list = &chan->sc_compat_unknown;
63aa9160
FD
521 } else {
522 struct lttng_syscall_filter *filter = chan->sc_filter;
523
524 if (id < 0 || id >= NR_syscalls
3b82c4e1 525 || (!READ_ONCE(chan->syscall_all_entry) && !test_bit(id, filter->sc_entry))) {
63aa9160
FD
526 /* System call filtered out. */
527 return;
528 }
529 table = sc_table;
530 table_len = ARRAY_SIZE(sc_table);
3b82c4e1 531 unknown_action_list = &chan->sc_unknown;
63aa9160
FD
532 }
533 if (unlikely(id < 0 || id >= table_len)) {
3b82c4e1 534 syscall_entry_event_unknown(unknown_action_list, regs, id);
63aa9160
FD
535 return;
536 }
3b82c4e1
MD
537
538 entry = &table[id];
539 if (!entry->event_func) {
540 syscall_entry_event_unknown(unknown_action_list, regs, id);
63aa9160
FD
541 return;
542 }
3b82c4e1
MD
543
544 if (unlikely(in_compat_syscall())) {
545 action_list = &chan->compat_sc_table[id];
546 } else {
547 action_list = &chan->sc_table[id];
548 }
549 if (unlikely(hlist_empty(action_list)))
550 return;
551
e2d5dbc7 552 syscall_entry_event_call_func(action_list, entry->event_func, entry->nrargs, regs);
63aa9160
FD
553}
554
8a8ac9a8
FD
555void syscall_entry_event_notifier_probe(void *__data, struct pt_regs *regs,
556 long id)
557{
558 struct lttng_event_notifier_group *group = __data;
559 const struct trace_syscall_entry *table, *entry;
560 struct hlist_head *dispatch_list, *unknown_dispatch_list;
561 size_t table_len;
562
563 if (unlikely(in_compat_syscall())) {
564 struct lttng_syscall_filter *filter = group->sc_filter;
565
566 if (id < 0 || id >= NR_compat_syscalls
567 || (!READ_ONCE(group->syscall_all_entry) &&
568 !test_bit(id, filter->sc_compat_entry))) {
569 /* System call filtered out. */
570 return;
571 }
572 table = compat_sc_table;
573 table_len = ARRAY_SIZE(compat_sc_table);
574 unknown_dispatch_list = &group->event_notifier_compat_unknown_syscall_dispatch;
575 } else {
576 struct lttng_syscall_filter *filter = group->sc_filter;
577
578 if (id < 0 || id >= NR_syscalls
579 || (!READ_ONCE(group->syscall_all_entry) &&
580 !test_bit(id, filter->sc_entry))) {
581 /* System call filtered out. */
582 return;
583 }
584 table = sc_table;
585 table_len = ARRAY_SIZE(sc_table);
586 unknown_dispatch_list = &group->event_notifier_unknown_syscall_dispatch;
587 }
588 /* Check if the syscall id is out of bound. */
589 if (unlikely(id < 0 || id >= table_len)) {
e2d5dbc7 590 syscall_entry_event_unknown(unknown_dispatch_list,
8a8ac9a8
FD
591 regs, id);
592 return;
593 }
594
595 entry = &table[id];
e2d5dbc7
MD
596 if (!entry->event_func) {
597 syscall_entry_event_unknown(unknown_dispatch_list,
8a8ac9a8
FD
598 regs, id);
599 return;
600 }
601
602 if (unlikely(in_compat_syscall())) {
603 dispatch_list = &group->event_notifier_compat_syscall_dispatch[id];
604 } else {
605 dispatch_list = &group->event_notifier_syscall_dispatch[id];
606 }
607 if (unlikely(hlist_empty(dispatch_list)))
608 return;
609
e2d5dbc7
MD
610 syscall_entry_event_call_func(dispatch_list,
611 entry->event_func, entry->nrargs, regs);
8a8ac9a8
FD
612}
613
3b82c4e1 614static void syscall_exit_event_unknown(struct hlist_head *unknown_action_list_head,
8a8ac9a8 615 struct pt_regs *regs, long id, long ret)
5b7ac358 616{
1b7b9c65 617 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
a67ba386 618 struct lttng_kernel_event_common_private *event_priv;
5b7ac358 619
1b7b9c65 620 lttng_syscall_get_arguments(current, regs, args);
a67ba386 621 lttng_hlist_for_each_entry_rcu(event_priv, unknown_action_list_head, u.syscall.node) {
3b82c4e1 622 if (unlikely(in_compat_syscall()))
e2d5dbc7 623 __event_probe__compat_syscall_exit_unknown(event_priv->pub, id, ret,
3b82c4e1
MD
624 args);
625 else
e2d5dbc7 626 __event_probe__syscall_exit_unknown(event_priv->pub, id, ret, args);
3b82c4e1 627 }
5b7ac358
MD
628}
629
3b82c4e1 630static __always_inline
e2d5dbc7 631void syscall_exit_event_call_func(struct hlist_head *action_list,
3b82c4e1
MD
632 void *func, unsigned int nrargs,
633 struct pt_regs *regs, long ret)
5b7ac358 634{
a67ba386 635 struct lttng_kernel_event_common_private *event_priv;
badfe9f5 636
3b82c4e1 637 switch (nrargs) {
5b7ac358
MD
638 case 0:
639 {
3b82c4e1 640 void (*fptr)(void *__data, long ret) = func;
5b7ac358 641
e2d5dbc7
MD
642 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node)
643 fptr(event_priv->pub, ret);
5b7ac358
MD
644 break;
645 }
646 case 1:
647 {
648 void (*fptr)(void *__data,
fc4f7161 649 long ret,
3b82c4e1 650 unsigned long arg0) = func;
1b7b9c65 651 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
5b7ac358 652
1b7b9c65 653 lttng_syscall_get_arguments(current, regs, args);
e2d5dbc7
MD
654 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node)
655 fptr(event_priv->pub, ret, args[0]);
5b7ac358
MD
656 break;
657 }
658 case 2:
659 {
660 void (*fptr)(void *__data,
fc4f7161 661 long ret,
5b7ac358 662 unsigned long arg0,
3b82c4e1 663 unsigned long arg1) = func;
1b7b9c65 664 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
5b7ac358 665
1b7b9c65 666 lttng_syscall_get_arguments(current, regs, args);
e2d5dbc7
MD
667 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node)
668 fptr(event_priv->pub, ret, args[0], args[1]);
5b7ac358
MD
669 break;
670 }
671 case 3:
672 {
673 void (*fptr)(void *__data,
fc4f7161 674 long ret,
5b7ac358
MD
675 unsigned long arg0,
676 unsigned long arg1,
3b82c4e1 677 unsigned long arg2) = func;
1b7b9c65 678 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
5b7ac358 679
1b7b9c65 680 lttng_syscall_get_arguments(current, regs, args);
e2d5dbc7
MD
681 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node)
682 fptr(event_priv->pub, ret, args[0], args[1], args[2]);
5b7ac358
MD
683 break;
684 }
685 case 4:
686 {
687 void (*fptr)(void *__data,
fc4f7161 688 long ret,
5b7ac358
MD
689 unsigned long arg0,
690 unsigned long arg1,
691 unsigned long arg2,
3b82c4e1 692 unsigned long arg3) = func;
1b7b9c65 693 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
5b7ac358 694
1b7b9c65 695 lttng_syscall_get_arguments(current, regs, args);
e2d5dbc7
MD
696 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node)
697 fptr(event_priv->pub, ret, args[0], args[1], args[2], args[3]);
5b7ac358
MD
698 break;
699 }
700 case 5:
701 {
702 void (*fptr)(void *__data,
fc4f7161 703 long ret,
5b7ac358
MD
704 unsigned long arg0,
705 unsigned long arg1,
706 unsigned long arg2,
707 unsigned long arg3,
3b82c4e1 708 unsigned long arg4) = func;
1b7b9c65 709 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
5b7ac358 710
1b7b9c65 711 lttng_syscall_get_arguments(current, regs, args);
e2d5dbc7
MD
712 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node)
713 fptr(event_priv->pub, ret, args[0], args[1], args[2], args[3], args[4]);
5b7ac358
MD
714 break;
715 }
716 case 6:
717 {
718 void (*fptr)(void *__data,
fc4f7161 719 long ret,
5b7ac358
MD
720 unsigned long arg0,
721 unsigned long arg1,
722 unsigned long arg2,
723 unsigned long arg3,
724 unsigned long arg4,
3b82c4e1 725 unsigned long arg5) = func;
1b7b9c65 726 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
5b7ac358 727
1b7b9c65 728 lttng_syscall_get_arguments(current, regs, args);
e2d5dbc7
MD
729 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node)
730 fptr(event_priv->pub, ret, args[0], args[1], args[2],
3b82c4e1 731 args[3], args[4], args[5]);
5b7ac358
MD
732 break;
733 }
734 default:
735 break;
736 }
737}
738
3b82c4e1
MD
739void syscall_exit_event_probe(void *__data, struct pt_regs *regs, long ret)
740{
741 struct lttng_channel *chan = __data;
742 struct hlist_head *action_list, *unknown_action_list;
743 const struct trace_syscall_entry *table, *entry;
744 size_t table_len;
745 long id;
746
747 id = syscall_get_nr(current, regs);
748
749 if (unlikely(in_compat_syscall())) {
750 struct lttng_syscall_filter *filter = chan->sc_filter;
751
752 if (id < 0 || id >= NR_compat_syscalls
753 || (!READ_ONCE(chan->syscall_all_exit) && !test_bit(id, filter->sc_compat_exit))) {
754 /* System call filtered out. */
755 return;
756 }
757 table = compat_sc_exit_table;
758 table_len = ARRAY_SIZE(compat_sc_exit_table);
759 unknown_action_list = &chan->compat_sc_exit_unknown;
760 } else {
761 struct lttng_syscall_filter *filter = chan->sc_filter;
762
763 if (id < 0 || id >= NR_syscalls
764 || (!READ_ONCE(chan->syscall_all_exit) && !test_bit(id, filter->sc_exit))) {
765 /* System call filtered out. */
766 return;
767 }
768 table = sc_exit_table;
769 table_len = ARRAY_SIZE(sc_exit_table);
770 unknown_action_list = &chan->sc_exit_unknown;
771 }
772 if (unlikely(id < 0 || id >= table_len)) {
773 syscall_exit_event_unknown(unknown_action_list, regs, id, ret);
774 return;
775 }
776
777 entry = &table[id];
778 if (!entry->event_func) {
779 syscall_exit_event_unknown(unknown_action_list, regs, id, ret);
780 return;
781 }
782
783 if (unlikely(in_compat_syscall())) {
784 action_list = &chan->compat_sc_exit_table[id];
785 } else {
786 action_list = &chan->sc_exit_table[id];
787 }
788 if (unlikely(hlist_empty(action_list)))
789 return;
790
e2d5dbc7 791 syscall_exit_event_call_func(action_list, entry->event_func, entry->nrargs,
3b82c4e1
MD
792 regs, ret);
793}
794
8a8ac9a8
FD
795static
796void syscall_exit_event_notifier_probe(void *__data, struct pt_regs *regs,
797 long ret)
798{
799 struct lttng_event_notifier_group *group = __data;
800 const struct trace_syscall_entry *table, *entry;
801 struct hlist_head *dispatch_list, *unknown_dispatch_list;
802 size_t table_len;
803 long id;
804
805 id = syscall_get_nr(current, regs);
806
807 if (unlikely(in_compat_syscall())) {
808 struct lttng_syscall_filter *filter = group->sc_filter;
809
810 if (id < 0 || id >= NR_compat_syscalls
811 || (!READ_ONCE(group->syscall_all_exit) &&
812 !test_bit(id, filter->sc_compat_exit))) {
813 /* System call filtered out. */
814 return;
815 }
816 table = compat_sc_exit_table;
817 table_len = ARRAY_SIZE(compat_sc_exit_table);
818 unknown_dispatch_list = &group->event_notifier_exit_compat_unknown_syscall_dispatch;
819 } else {
820 struct lttng_syscall_filter *filter = group->sc_filter;
821
822 if (id < 0 || id >= NR_syscalls
823 || (!READ_ONCE(group->syscall_all_exit) &&
824 !test_bit(id, filter->sc_exit))) {
825 /* System call filtered out. */
826 return;
827 }
828 table = sc_exit_table;
829 table_len = ARRAY_SIZE(sc_exit_table);
830 unknown_dispatch_list = &group->event_notifier_exit_unknown_syscall_dispatch;
831 }
832 /* Check if the syscall id is out of bound. */
833 if (unlikely(id < 0 || id >= table_len)) {
e2d5dbc7 834 syscall_exit_event_unknown(unknown_dispatch_list,
8a8ac9a8
FD
835 regs, id, ret);
836 return;
837 }
838
839 entry = &table[id];
e2d5dbc7
MD
840 if (!entry->event_func) {
841 syscall_entry_event_unknown(unknown_dispatch_list,
8a8ac9a8
FD
842 regs, id);
843 return;
844 }
845
846 if (unlikely(in_compat_syscall())) {
847 dispatch_list = &group->event_notifier_exit_compat_syscall_dispatch[id];
848 } else {
849 dispatch_list = &group->event_notifier_exit_syscall_dispatch[id];
850 }
851 if (unlikely(hlist_empty(dispatch_list)))
852 return;
853
e2d5dbc7
MD
854 syscall_exit_event_call_func(dispatch_list,
855 entry->event_func, entry->nrargs, regs, ret);
8a8ac9a8 856}
33a39a3c
MD
857/*
858 * noinline to diminish caller stack size.
859 * Should be called with sessions lock held.
860 */
49c50022 861static
3b82c4e1
MD
862int lttng_create_syscall_event_if_missing(const struct trace_syscall_entry *table, size_t table_len,
863 struct hlist_head *chan_table, struct lttng_event_enabler *event_enabler,
a67ba386 864 enum sc_type type)
259b6cb3 865{
3b82c4e1
MD
866 struct lttng_channel *chan = event_enabler->chan;
867 struct lttng_session *session = chan->session;
259b6cb3 868 unsigned int i;
49c50022 869
3b82c4e1 870 /* Allocate events for each syscall matching enabler, insert into table */
49c50022 871 for (i = 0; i < table_len; i++) {
437d5aa5 872 const struct lttng_kernel_event_desc *desc = table[i].desc;
606828e4 873 struct lttng_kernel_abi_event ev;
a67ba386
MD
874 struct lttng_kernel_event_recorder_private *event_recorder_priv;
875 struct lttng_kernel_event_recorder *event_recorder;
3b82c4e1
MD
876 struct hlist_head *head;
877 bool found = false;
49c50022
MD
878
879 if (!desc) {
880 /* Unknown syscall */
881 continue;
882 }
3b82c4e1
MD
883 if (lttng_desc_match_enabler(desc,
884 lttng_event_enabler_as_enabler(event_enabler)) <= 0)
885 continue;
49c50022 886 /*
3b82c4e1 887 * Check if already created.
49c50022 888 */
3b82c4e1
MD
889 head = utils_borrow_hash_table_bucket(
890 session->events_ht.table, LTTNG_EVENT_HT_SIZE,
437d5aa5 891 desc->event_name);
a67ba386
MD
892 lttng_hlist_for_each_entry(event_recorder_priv, head, hlist) {
893 if (event_recorder_priv->parent.desc == desc
894 && event_recorder_priv->pub->chan == event_enabler->chan)
3b82c4e1
MD
895 found = true;
896 }
897 if (found)
49c50022 898 continue;
3b82c4e1
MD
899
900 /* We need to create an event for this syscall/enabler. */
49c50022 901 memset(&ev, 0, sizeof(ev));
5b7ac358
MD
902 switch (type) {
903 case SC_TYPE_ENTRY:
606828e4
MD
904 ev.u.syscall.entryexit = LTTNG_KERNEL_ABI_SYSCALL_ENTRY;
905 ev.u.syscall.abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_NATIVE;
5b7ac358
MD
906 break;
907 case SC_TYPE_EXIT:
606828e4
MD
908 ev.u.syscall.entryexit = LTTNG_KERNEL_ABI_SYSCALL_EXIT;
909 ev.u.syscall.abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_NATIVE;
5b7ac358
MD
910 break;
911 case SC_TYPE_COMPAT_ENTRY:
606828e4
MD
912 ev.u.syscall.entryexit = LTTNG_KERNEL_ABI_SYSCALL_ENTRY;
913 ev.u.syscall.abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_COMPAT;
5b7ac358
MD
914 break;
915 case SC_TYPE_COMPAT_EXIT:
606828e4
MD
916 ev.u.syscall.entryexit = LTTNG_KERNEL_ABI_SYSCALL_EXIT;
917 ev.u.syscall.abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_COMPAT;
5b7ac358
MD
918 break;
919 }
606828e4
MD
920 strncpy(ev.name, desc->event_name, LTTNG_KERNEL_ABI_SYM_NAME_LEN - 1);
921 ev.name[LTTNG_KERNEL_ABI_SYM_NAME_LEN - 1] = '\0';
922 ev.instrumentation = LTTNG_KERNEL_ABI_SYSCALL;
a67ba386
MD
923 event_recorder = _lttng_kernel_event_recorder_create(chan, &ev, desc, ev.instrumentation);
924 WARN_ON_ONCE(!event_recorder);
925 if (IS_ERR(event_recorder)) {
49c50022
MD
926 /*
927 * If something goes wrong in event registration
928 * after the first one, we have no choice but to
929 * leave the previous events in there, until
930 * deleted by session teardown.
931 */
a67ba386 932 return PTR_ERR(event_recorder);
49c50022 933 }
a67ba386 934 hlist_add_head(&event_recorder->priv->parent.u.syscall.node, &chan_table[i]);
49c50022
MD
935 }
936 return 0;
937}
938
33a39a3c
MD
939/*
940 * Should be called with sessions lock held.
941 */
a67ba386 942int lttng_syscalls_register_event(struct lttng_event_enabler *event_enabler)
49c50022 943{
3b82c4e1 944 struct lttng_channel *chan = event_enabler->chan;
606828e4 945 struct lttng_kernel_abi_event ev;
259b6cb3
MD
946 int ret;
947
263b6c88 948 wrapper_vmalloc_sync_mappings();
259b6cb3
MD
949
950 if (!chan->sc_table) {
951 /* create syscall table mapping syscall to events */
a67ba386 952 chan->sc_table = kzalloc(sizeof(struct lttng_kernel_event_recorder *)
259b6cb3
MD
953 * ARRAY_SIZE(sc_table), GFP_KERNEL);
954 if (!chan->sc_table)
955 return -ENOMEM;
956 }
5b7ac358
MD
957 if (!chan->sc_exit_table) {
958 /* create syscall table mapping syscall to events */
a67ba386 959 chan->sc_exit_table = kzalloc(sizeof(struct lttng_kernel_event_recorder *)
5b7ac358
MD
960 * ARRAY_SIZE(sc_exit_table), GFP_KERNEL);
961 if (!chan->sc_exit_table)
962 return -ENOMEM;
963 }
964
259b6cb3 965
49c50022
MD
966#ifdef CONFIG_COMPAT
967 if (!chan->compat_sc_table) {
968 /* create syscall table mapping compat syscall to events */
a67ba386 969 chan->compat_sc_table = kzalloc(sizeof(struct lttng_kernel_event_recorder *)
a93244f8 970 * ARRAY_SIZE(compat_sc_table), GFP_KERNEL);
49c50022
MD
971 if (!chan->compat_sc_table)
972 return -ENOMEM;
973 }
5b7ac358
MD
974
975 if (!chan->compat_sc_exit_table) {
976 /* create syscall table mapping compat syscall to events */
a67ba386 977 chan->compat_sc_exit_table = kzalloc(sizeof(struct lttng_kernel_event_recorder *)
5b7ac358
MD
978 * ARRAY_SIZE(compat_sc_exit_table), GFP_KERNEL);
979 if (!chan->compat_sc_exit_table)
980 return -ENOMEM;
981 }
49c50022 982#endif
3b82c4e1 983 if (hlist_empty(&chan->sc_unknown)) {
437d5aa5 984 const struct lttng_kernel_event_desc *desc =
d4291869 985 &__event_desc___syscall_entry_unknown;
a67ba386 986 struct lttng_kernel_event_recorder *event_recorder;
2f804c0a 987
f405cfce 988 memset(&ev, 0, sizeof(ev));
606828e4
MD
989 strncpy(ev.name, desc->event_name, LTTNG_KERNEL_ABI_SYM_NAME_LEN);
990 ev.name[LTTNG_KERNEL_ABI_SYM_NAME_LEN - 1] = '\0';
991 ev.instrumentation = LTTNG_KERNEL_ABI_SYSCALL;
992 ev.u.syscall.entryexit = LTTNG_KERNEL_ABI_SYSCALL_ENTRY;
993 ev.u.syscall.abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_NATIVE;
a67ba386 994 event_recorder = _lttng_kernel_event_recorder_create(chan, &ev, desc,
3b82c4e1 995 ev.instrumentation);
a67ba386
MD
996 WARN_ON_ONCE(!event_recorder);
997 if (IS_ERR(event_recorder)) {
998 return PTR_ERR(event_recorder);
f405cfce 999 }
a67ba386 1000 hlist_add_head(&event_recorder->priv->parent.u.syscall.node, &chan->sc_unknown);
f405cfce
MD
1001 }
1002
3b82c4e1 1003 if (hlist_empty(&chan->sc_compat_unknown)) {
437d5aa5 1004 const struct lttng_kernel_event_desc *desc =
d4291869 1005 &__event_desc___compat_syscall_entry_unknown;
a67ba386 1006 struct lttng_kernel_event_recorder *event_recorder;
b76dc1a0
MD
1007
1008 memset(&ev, 0, sizeof(ev));
606828e4
MD
1009 strncpy(ev.name, desc->event_name, LTTNG_KERNEL_ABI_SYM_NAME_LEN);
1010 ev.name[LTTNG_KERNEL_ABI_SYM_NAME_LEN - 1] = '\0';
1011 ev.instrumentation = LTTNG_KERNEL_ABI_SYSCALL;
1012 ev.u.syscall.entryexit = LTTNG_KERNEL_ABI_SYSCALL_ENTRY;
1013 ev.u.syscall.abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_COMPAT;
a67ba386 1014 event_recorder = _lttng_kernel_event_recorder_create(chan, &ev, desc,
3b82c4e1 1015 ev.instrumentation);
a67ba386
MD
1016 WARN_ON_ONCE(!event_recorder);
1017 if (IS_ERR(event_recorder)) {
1018 return PTR_ERR(event_recorder);
b76dc1a0 1019 }
a67ba386 1020 hlist_add_head(&event_recorder->priv->parent.u.syscall.node, &chan->sc_compat_unknown);
b76dc1a0
MD
1021 }
1022
3b82c4e1 1023 if (hlist_empty(&chan->compat_sc_exit_unknown)) {
437d5aa5 1024 const struct lttng_kernel_event_desc *desc =
5b7ac358 1025 &__event_desc___compat_syscall_exit_unknown;
a67ba386 1026 struct lttng_kernel_event_recorder *event_recorder;
2f804c0a
MD
1027
1028 memset(&ev, 0, sizeof(ev));
606828e4
MD
1029 strncpy(ev.name, desc->event_name, LTTNG_KERNEL_ABI_SYM_NAME_LEN);
1030 ev.name[LTTNG_KERNEL_ABI_SYM_NAME_LEN - 1] = '\0';
1031 ev.instrumentation = LTTNG_KERNEL_ABI_SYSCALL;
1032 ev.u.syscall.entryexit = LTTNG_KERNEL_ABI_SYSCALL_EXIT;
1033 ev.u.syscall.abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_COMPAT;
a67ba386 1034 event_recorder = _lttng_kernel_event_recorder_create(chan, &ev, desc,
3b82c4e1 1035 ev.instrumentation);
a67ba386
MD
1036 WARN_ON_ONCE(!event_recorder);
1037 if (IS_ERR(event_recorder)) {
1038 return PTR_ERR(event_recorder);
5b7ac358 1039 }
a67ba386 1040 hlist_add_head(&event_recorder->priv->parent.u.syscall.node, &chan->compat_sc_exit_unknown);
5b7ac358
MD
1041 }
1042
3b82c4e1 1043 if (hlist_empty(&chan->sc_exit_unknown)) {
437d5aa5 1044 const struct lttng_kernel_event_desc *desc =
5b7ac358 1045 &__event_desc___syscall_exit_unknown;
a67ba386 1046 struct lttng_kernel_event_recorder *event_recorder;
5b7ac358
MD
1047
1048 memset(&ev, 0, sizeof(ev));
606828e4
MD
1049 strncpy(ev.name, desc->event_name, LTTNG_KERNEL_ABI_SYM_NAME_LEN);
1050 ev.name[LTTNG_KERNEL_ABI_SYM_NAME_LEN - 1] = '\0';
1051 ev.instrumentation = LTTNG_KERNEL_ABI_SYSCALL;
1052 ev.u.syscall.entryexit = LTTNG_KERNEL_ABI_SYSCALL_EXIT;
1053 ev.u.syscall.abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_NATIVE;
a67ba386 1054 event_recorder = _lttng_kernel_event_recorder_create(chan, &ev, desc,
3b82c4e1 1055 ev.instrumentation);
a67ba386
MD
1056 WARN_ON_ONCE(!event_recorder);
1057 if (IS_ERR(event_recorder)) {
1058 return PTR_ERR(event_recorder);
2f804c0a 1059 }
a67ba386 1060 hlist_add_head(&event_recorder->priv->parent.u.syscall.node, &chan->sc_exit_unknown);
2f804c0a
MD
1061 }
1062
3b82c4e1 1063 ret = lttng_create_syscall_event_if_missing(sc_table, ARRAY_SIZE(sc_table),
a67ba386 1064 chan->sc_table, event_enabler, SC_TYPE_ENTRY);
5b7ac358
MD
1065 if (ret)
1066 return ret;
3b82c4e1 1067 ret = lttng_create_syscall_event_if_missing(sc_exit_table, ARRAY_SIZE(sc_exit_table),
a67ba386 1068 chan->sc_exit_table, event_enabler, SC_TYPE_EXIT);
49c50022
MD
1069 if (ret)
1070 return ret;
5b7ac358 1071
49c50022 1072#ifdef CONFIG_COMPAT
3b82c4e1 1073 ret = lttng_create_syscall_event_if_missing(compat_sc_table, ARRAY_SIZE(compat_sc_table),
a67ba386 1074 chan->compat_sc_table, event_enabler, SC_TYPE_COMPAT_ENTRY);
5b7ac358
MD
1075 if (ret)
1076 return ret;
3b82c4e1 1077 ret = lttng_create_syscall_event_if_missing(compat_sc_exit_table, ARRAY_SIZE(compat_sc_exit_table),
a67ba386 1078 chan->compat_sc_exit_table, event_enabler, SC_TYPE_COMPAT_EXIT);
49c50022
MD
1079 if (ret)
1080 return ret;
1081#endif
badfe9f5
MD
1082
1083 if (!chan->sc_filter) {
1084 chan->sc_filter = kzalloc(sizeof(struct lttng_syscall_filter),
1085 GFP_KERNEL);
1086 if (!chan->sc_filter)
1087 return -ENOMEM;
1088 }
1089
80f87dd2
MD
1090 if (!chan->sys_enter_registered) {
1091 ret = lttng_wrapper_tracepoint_probe_register("sys_enter",
2d6d88c6 1092 (void *) syscall_entry_event_probe, chan);
80f87dd2
MD
1093 if (ret)
1094 return ret;
1095 chan->sys_enter_registered = 1;
1096 }
63728b02
MD
1097 /*
1098 * We change the name of sys_exit tracepoint due to namespace
1099 * conflict with sys_exit syscall entry.
1100 */
80f87dd2
MD
1101 if (!chan->sys_exit_registered) {
1102 ret = lttng_wrapper_tracepoint_probe_register("sys_exit",
2d6d88c6 1103 (void *) syscall_exit_event_probe, chan);
80f87dd2
MD
1104 if (ret) {
1105 WARN_ON_ONCE(lttng_wrapper_tracepoint_probe_unregister("sys_enter",
2d6d88c6 1106 (void *) syscall_entry_event_probe, chan));
80f87dd2
MD
1107 return ret;
1108 }
1109 chan->sys_exit_registered = 1;
63728b02 1110 }
259b6cb3
MD
1111 return ret;
1112}
1113
1114/*
8a8ac9a8
FD
1115 * Should be called with sessions lock held.
1116 */
1117int lttng_syscalls_register_event_notifier(
a67ba386 1118 struct lttng_event_notifier_enabler *event_notifier_enabler)
8a8ac9a8
FD
1119{
1120 struct lttng_event_notifier_group *group = event_notifier_enabler->group;
1121 unsigned int i;
1122 int ret = 0;
1123
1124 wrapper_vmalloc_sync_mappings();
1125
1126 if (!group->event_notifier_syscall_dispatch) {
1127 group->event_notifier_syscall_dispatch =
1128 kzalloc(sizeof(struct hlist_head) * ARRAY_SIZE(sc_table),
1129 GFP_KERNEL);
1130 if (!group->event_notifier_syscall_dispatch)
1131 return -ENOMEM;
1132
1133 /* Initialize all list_head */
1134 for (i = 0; i < ARRAY_SIZE(sc_table); i++)
1135 INIT_HLIST_HEAD(&group->event_notifier_syscall_dispatch[i]);
1136
1137 /* Init the unknown syscall notifier list. */
1138 INIT_HLIST_HEAD(&group->event_notifier_unknown_syscall_dispatch);
1139 }
1140
1141 if (!group->event_notifier_exit_syscall_dispatch) {
1142 group->event_notifier_exit_syscall_dispatch =
1143 kzalloc(sizeof(struct hlist_head) * ARRAY_SIZE(sc_table),
1144 GFP_KERNEL);
1145 if (!group->event_notifier_exit_syscall_dispatch)
1146 return -ENOMEM;
1147
1148 /* Initialize all list_head */
1149 for (i = 0; i < ARRAY_SIZE(sc_table); i++)
1150 INIT_HLIST_HEAD(&group->event_notifier_exit_syscall_dispatch[i]);
1151
1152 /* Init the unknown exit syscall notifier list. */
1153 INIT_HLIST_HEAD(&group->event_notifier_exit_unknown_syscall_dispatch);
1154 }
1155
1156#ifdef CONFIG_COMPAT
1157 if (!group->event_notifier_compat_syscall_dispatch) {
1158 group->event_notifier_compat_syscall_dispatch =
1159 kzalloc(sizeof(struct hlist_head) * ARRAY_SIZE(compat_sc_table),
1160 GFP_KERNEL);
1161 if (!group->event_notifier_syscall_dispatch)
1162 return -ENOMEM;
1163
1164 /* Initialize all list_head */
1165 for (i = 0; i < ARRAY_SIZE(compat_sc_table); i++)
1166 INIT_HLIST_HEAD(&group->event_notifier_compat_syscall_dispatch[i]);
1167
1168 /* Init the unknown syscall notifier list. */
1169 INIT_HLIST_HEAD(&group->event_notifier_compat_unknown_syscall_dispatch);
1170 }
1171
1172 if (!group->event_notifier_exit_compat_syscall_dispatch) {
1173 group->event_notifier_exit_compat_syscall_dispatch =
1174 kzalloc(sizeof(struct hlist_head) * ARRAY_SIZE(compat_sc_exit_table),
1175 GFP_KERNEL);
1176 if (!group->event_notifier_exit_syscall_dispatch)
1177 return -ENOMEM;
1178
1179 /* Initialize all list_head */
1180 for (i = 0; i < ARRAY_SIZE(compat_sc_exit_table); i++)
1181 INIT_HLIST_HEAD(&group->event_notifier_exit_compat_syscall_dispatch[i]);
1182
1183 /* Init the unknown exit syscall notifier list. */
1184 INIT_HLIST_HEAD(&group->event_notifier_exit_compat_unknown_syscall_dispatch);
1185 }
1186#endif
1187
1188 if (!group->sc_filter) {
1189 group->sc_filter = kzalloc(sizeof(struct lttng_syscall_filter),
1190 GFP_KERNEL);
1191 if (!group->sc_filter)
1192 return -ENOMEM;
1193 }
1194
1195 if (!group->sys_enter_registered) {
1196 ret = lttng_wrapper_tracepoint_probe_register("sys_enter",
1197 (void *) syscall_entry_event_notifier_probe, group);
1198 if (ret)
1199 return ret;
1200 group->sys_enter_registered = 1;
1201 }
1202
1203 if (!group->sys_exit_registered) {
1204 ret = lttng_wrapper_tracepoint_probe_register("sys_exit",
1205 (void *) syscall_exit_event_notifier_probe, group);
1206 if (ret) {
1207 WARN_ON_ONCE(lttng_wrapper_tracepoint_probe_unregister("sys_enter",
1208 (void *) syscall_entry_event_notifier_probe, group));
1209 return ret;
1210 }
1211 group->sys_exit_registered = 1;
1212 }
1213
1214 return ret;
1215}
1216
1217static
1218int create_unknown_event_notifier(
1219 struct lttng_event_notifier_enabler *event_notifier_enabler,
1220 enum sc_type type)
1221{
a67ba386
MD
1222 struct lttng_kernel_event_notifier_private *event_notifier_priv;
1223 struct lttng_kernel_event_notifier *event_notifier;
437d5aa5 1224 const struct lttng_kernel_event_desc *desc;
8a8ac9a8 1225 struct lttng_event_notifier_group *group = event_notifier_enabler->group;
606828e4 1226 struct lttng_kernel_abi_event_notifier event_notifier_param;
8a8ac9a8 1227 uint64_t user_token = event_notifier_enabler->base.user_token;
99f52fcc 1228 uint64_t error_counter_index = event_notifier_enabler->error_counter_index;
8a8ac9a8
FD
1229 struct lttng_enabler *base_enabler = lttng_event_notifier_enabler_as_enabler(
1230 event_notifier_enabler);
1231 struct hlist_head *unknown_dispatch_list;
1232 int ret = 0;
1233 bool found = false;
606828e4
MD
1234 enum lttng_kernel_abi_syscall_abi abi;
1235 enum lttng_kernel_abi_syscall_entryexit entryexit;
8a8ac9a8
FD
1236 struct hlist_head *head;
1237
1238 switch (type) {
1239 case SC_TYPE_ENTRY:
1240 desc = &__event_desc___syscall_entry_unknown;
1241 unknown_dispatch_list = &group->event_notifier_unknown_syscall_dispatch;
606828e4
MD
1242 entryexit = LTTNG_KERNEL_ABI_SYSCALL_ENTRY;
1243 abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_NATIVE;
8a8ac9a8
FD
1244 break;
1245 case SC_TYPE_EXIT:
1246 desc = &__event_desc___syscall_exit_unknown;
1247 unknown_dispatch_list = &group->event_notifier_exit_unknown_syscall_dispatch;
606828e4
MD
1248 entryexit = LTTNG_KERNEL_ABI_SYSCALL_EXIT;
1249 abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_NATIVE;
8a8ac9a8
FD
1250 break;
1251 case SC_TYPE_COMPAT_ENTRY:
1252 desc = &__event_desc___compat_syscall_entry_unknown;
1253 unknown_dispatch_list = &group->event_notifier_compat_unknown_syscall_dispatch;
606828e4
MD
1254 entryexit = LTTNG_KERNEL_ABI_SYSCALL_ENTRY;
1255 abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_COMPAT;
8a8ac9a8
FD
1256 break;
1257 case SC_TYPE_COMPAT_EXIT:
1258 desc = &__event_desc___compat_syscall_exit_unknown;
1259 unknown_dispatch_list = &group->event_notifier_exit_compat_unknown_syscall_dispatch;
606828e4
MD
1260 entryexit = LTTNG_KERNEL_ABI_SYSCALL_EXIT;
1261 abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_COMPAT;
8a8ac9a8
FD
1262 break;
1263 default:
1264 BUG_ON(1);
1265 }
1266
1267 /*
1268 * Check if already created.
1269 */
1270 head = utils_borrow_hash_table_bucket(group->event_notifiers_ht.table,
437d5aa5 1271 LTTNG_EVENT_NOTIFIER_HT_SIZE, desc->event_name);
a67ba386
MD
1272 lttng_hlist_for_each_entry(event_notifier_priv, head, hlist) {
1273 if (event_notifier_priv->parent.desc == desc &&
1274 event_notifier_priv->parent.user_token == base_enabler->user_token)
8a8ac9a8
FD
1275 found = true;
1276 }
1277 if (found)
1278 goto end;
1279
1280 memset(&event_notifier_param, 0, sizeof(event_notifier_param));
437d5aa5 1281 strncat(event_notifier_param.event.name, desc->event_name,
606828e4 1282 LTTNG_KERNEL_ABI_SYM_NAME_LEN - strlen(event_notifier_param.event.name) - 1);
8a8ac9a8 1283
606828e4 1284 event_notifier_param.event.name[LTTNG_KERNEL_ABI_SYM_NAME_LEN - 1] = '\0';
8a8ac9a8 1285
606828e4 1286 event_notifier_param.event.instrumentation = LTTNG_KERNEL_ABI_SYSCALL;
8a8ac9a8
FD
1287 event_notifier_param.event.u.syscall.abi = abi;
1288 event_notifier_param.event.u.syscall.entryexit = entryexit;
1289
a67ba386
MD
1290 event_notifier = _lttng_event_notifier_create(desc, user_token,
1291 error_counter_index, group, &event_notifier_param,
8a8ac9a8 1292 event_notifier_param.event.instrumentation);
a67ba386 1293 if (IS_ERR(event_notifier)) {
8a8ac9a8 1294 printk(KERN_INFO "Unable to create unknown notifier %s\n",
437d5aa5 1295 desc->event_name);
8a8ac9a8
FD
1296 ret = -ENOMEM;
1297 goto end;
1298 }
1299
a67ba386 1300 hlist_add_head_rcu(&event_notifier->priv->parent.u.syscall.node, unknown_dispatch_list);
8a8ac9a8
FD
1301
1302end:
1303 return ret;
1304}
1305
1306static int create_matching_event_notifiers(
1307 struct lttng_event_notifier_enabler *event_notifier_enabler,
a67ba386 1308 const struct trace_syscall_entry *table,
8a8ac9a8
FD
1309 size_t table_len, enum sc_type type)
1310{
1311 struct lttng_event_notifier_group *group = event_notifier_enabler->group;
437d5aa5 1312 const struct lttng_kernel_event_desc *desc;
8a8ac9a8 1313 uint64_t user_token = event_notifier_enabler->base.user_token;
99f52fcc 1314 uint64_t error_counter_index = event_notifier_enabler->error_counter_index;
8a8ac9a8
FD
1315 unsigned int i;
1316 int ret = 0;
1317
1318 /* iterate over all syscall and create event_notifier that match */
1319 for (i = 0; i < table_len; i++) {
a67ba386
MD
1320 struct lttng_kernel_event_notifier_private *event_notifier_priv;
1321 struct lttng_kernel_event_notifier *event_notifier;
606828e4 1322 struct lttng_kernel_abi_event_notifier event_notifier_param;
8a8ac9a8
FD
1323 struct hlist_head *head;
1324 int found = 0;
1325
1326 desc = table[i].desc;
1327 if (!desc) {
1328 /* Unknown syscall */
1329 continue;
1330 }
1331
1332 if (!lttng_desc_match_enabler(desc,
1333 lttng_event_notifier_enabler_as_enabler(event_notifier_enabler)))
1334 continue;
1335
1336 /*
1337 * Check if already created.
1338 */
1339 head = utils_borrow_hash_table_bucket(group->event_notifiers_ht.table,
437d5aa5 1340 LTTNG_EVENT_NOTIFIER_HT_SIZE, desc->event_name);
a67ba386
MD
1341 lttng_hlist_for_each_entry(event_notifier_priv, head, hlist) {
1342 if (event_notifier_priv->parent.desc == desc
1343 && event_notifier_priv->parent.user_token == event_notifier_enabler->base.user_token)
8a8ac9a8
FD
1344 found = 1;
1345 }
1346 if (found)
1347 continue;
1348
1349 memset(&event_notifier_param, 0, sizeof(event_notifier_param));
1350 switch (type) {
1351 case SC_TYPE_ENTRY:
606828e4
MD
1352 event_notifier_param.event.u.syscall.entryexit = LTTNG_KERNEL_ABI_SYSCALL_ENTRY;
1353 event_notifier_param.event.u.syscall.abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_NATIVE;
8a8ac9a8
FD
1354 break;
1355 case SC_TYPE_EXIT:
606828e4
MD
1356 event_notifier_param.event.u.syscall.entryexit = LTTNG_KERNEL_ABI_SYSCALL_EXIT;
1357 event_notifier_param.event.u.syscall.abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_NATIVE;
8a8ac9a8
FD
1358 break;
1359 case SC_TYPE_COMPAT_ENTRY:
606828e4
MD
1360 event_notifier_param.event.u.syscall.entryexit = LTTNG_KERNEL_ABI_SYSCALL_ENTRY;
1361 event_notifier_param.event.u.syscall.abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_COMPAT;
8a8ac9a8
FD
1362 break;
1363 case SC_TYPE_COMPAT_EXIT:
606828e4
MD
1364 event_notifier_param.event.u.syscall.entryexit = LTTNG_KERNEL_ABI_SYSCALL_EXIT;
1365 event_notifier_param.event.u.syscall.abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_COMPAT;
8a8ac9a8
FD
1366 break;
1367 }
437d5aa5 1368 strncat(event_notifier_param.event.name, desc->event_name,
606828e4
MD
1369 LTTNG_KERNEL_ABI_SYM_NAME_LEN - strlen(event_notifier_param.event.name) - 1);
1370 event_notifier_param.event.name[LTTNG_KERNEL_ABI_SYM_NAME_LEN - 1] = '\0';
1371 event_notifier_param.event.instrumentation = LTTNG_KERNEL_ABI_SYSCALL;
8a8ac9a8 1372
99f52fcc
FD
1373 event_notifier = _lttng_event_notifier_create(desc, user_token,
1374 error_counter_index, group, &event_notifier_param,
a67ba386 1375 event_notifier_param.event.instrumentation);
8a8ac9a8
FD
1376 if (IS_ERR(event_notifier)) {
1377 printk(KERN_INFO "Unable to create event_notifier %s\n",
437d5aa5 1378 desc->event_name);
8a8ac9a8
FD
1379 ret = -ENOMEM;
1380 goto end;
1381 }
1382
a67ba386 1383 event_notifier->priv->parent.u.syscall.syscall_id = i;
8a8ac9a8
FD
1384 }
1385
1386end:
1387 return ret;
1388
1389}
1390
a67ba386
MD
1391int lttng_syscalls_create_matching_event_notifiers(
1392 struct lttng_event_notifier_enabler *event_notifier_enabler)
8a8ac9a8
FD
1393{
1394 int ret;
1395 struct lttng_enabler *base_enabler =
1396 lttng_event_notifier_enabler_as_enabler(event_notifier_enabler);
606828e4 1397 enum lttng_kernel_abi_syscall_entryexit entryexit =
8a8ac9a8
FD
1398 base_enabler->event_param.u.syscall.entryexit;
1399
606828e4 1400 if (entryexit == LTTNG_KERNEL_ABI_SYSCALL_ENTRY || entryexit == LTTNG_KERNEL_ABI_SYSCALL_ENTRYEXIT) {
8a8ac9a8 1401 ret = create_matching_event_notifiers(event_notifier_enabler,
a67ba386 1402 sc_table, ARRAY_SIZE(sc_table), SC_TYPE_ENTRY);
8a8ac9a8
FD
1403 if (ret)
1404 goto end;
1405
1406 ret = create_matching_event_notifiers(event_notifier_enabler,
a67ba386 1407 compat_sc_table, ARRAY_SIZE(compat_sc_table),
8a8ac9a8
FD
1408 SC_TYPE_COMPAT_ENTRY);
1409 if (ret)
1410 goto end;
1411
1412 ret = create_unknown_event_notifier(event_notifier_enabler,
1413 SC_TYPE_ENTRY);
1414 if (ret)
1415 goto end;
1416
1417 ret = create_unknown_event_notifier(event_notifier_enabler,
1418 SC_TYPE_COMPAT_ENTRY);
1419 if (ret)
1420 goto end;
1421 }
1422
606828e4 1423 if (entryexit == LTTNG_KERNEL_ABI_SYSCALL_EXIT || entryexit == LTTNG_KERNEL_ABI_SYSCALL_ENTRYEXIT) {
8a8ac9a8 1424 ret = create_matching_event_notifiers(event_notifier_enabler,
a67ba386 1425 sc_exit_table, ARRAY_SIZE(sc_exit_table),
8a8ac9a8
FD
1426 SC_TYPE_EXIT);
1427 if (ret)
1428 goto end;
1429
1430 ret = create_unknown_event_notifier(event_notifier_enabler,
1431 SC_TYPE_EXIT);
1432 if (ret)
1433 goto end;
1434
1435 ret = create_matching_event_notifiers(event_notifier_enabler,
a67ba386 1436 compat_sc_exit_table, ARRAY_SIZE(compat_sc_exit_table),
8a8ac9a8
FD
1437 SC_TYPE_COMPAT_EXIT);
1438 if (ret)
1439 goto end;
1440
1441 ret = create_unknown_event_notifier(event_notifier_enabler,
1442 SC_TYPE_COMPAT_EXIT);
1443 if (ret)
1444 goto end;
1445 }
1446
1447end:
1448 return ret;
1449}
1450
1451/*
1452 * Unregister the syscall event_notifier probes from the callsites.
259b6cb3 1453 */
3b82c4e1 1454int lttng_syscalls_unregister_event_notifier_group(
8a8ac9a8
FD
1455 struct lttng_event_notifier_group *event_notifier_group)
1456{
1457 int ret;
1458
1459 /*
1460 * Only register the event_notifier probe on the `sys_enter` callsite for now.
1461 * At the moment, we don't think it's desirable to have one fired
1462 * event_notifier for the entry and one for the exit of a syscall.
1463 */
1464 if (event_notifier_group->sys_enter_registered) {
1465 ret = lttng_wrapper_tracepoint_probe_unregister("sys_enter",
1466 (void *) syscall_entry_event_notifier_probe, event_notifier_group);
1467 if (ret)
1468 return ret;
1469 event_notifier_group->sys_enter_registered = 0;
1470 }
1471 if (event_notifier_group->sys_exit_registered) {
1472 ret = lttng_wrapper_tracepoint_probe_unregister("sys_exit",
1473 (void *) syscall_exit_event_notifier_probe, event_notifier_group);
1474 if (ret)
1475 return ret;
1476 event_notifier_group->sys_enter_registered = 0;
1477 }
1478
1479 kfree(event_notifier_group->event_notifier_syscall_dispatch);
1480 kfree(event_notifier_group->event_notifier_exit_syscall_dispatch);
1481#ifdef CONFIG_COMPAT
1482 kfree(event_notifier_group->event_notifier_compat_syscall_dispatch);
1483 kfree(event_notifier_group->event_notifier_exit_compat_syscall_dispatch);
1484#endif
1485 return 0;
1486}
1487
3b82c4e1 1488int lttng_syscalls_unregister_channel(struct lttng_channel *chan)
259b6cb3
MD
1489{
1490 int ret;
1491
1492 if (!chan->sc_table)
1493 return 0;
80f87dd2 1494 if (chan->sys_enter_registered) {
2d9cd7f3 1495 ret = lttng_wrapper_tracepoint_probe_unregister("sys_enter",
2d6d88c6 1496 (void *) syscall_entry_event_probe, chan);
80f87dd2
MD
1497 if (ret)
1498 return ret;
1499 chan->sys_enter_registered = 0;
1500 }
1501 if (chan->sys_exit_registered) {
2d9cd7f3 1502 ret = lttng_wrapper_tracepoint_probe_unregister("sys_exit",
2d6d88c6 1503 (void *) syscall_exit_event_probe, chan);
80f87dd2
MD
1504 if (ret)
1505 return ret;
1506 chan->sys_exit_registered = 0;
1507 }
badfe9f5
MD
1508 return 0;
1509}
1510
2d6d88c6 1511int lttng_syscalls_destroy_event(struct lttng_channel *chan)
badfe9f5 1512{
259b6cb3 1513 kfree(chan->sc_table);
5b7ac358 1514 kfree(chan->sc_exit_table);
49c50022
MD
1515#ifdef CONFIG_COMPAT
1516 kfree(chan->compat_sc_table);
5b7ac358 1517 kfree(chan->compat_sc_exit_table);
49c50022 1518#endif
80f87dd2
MD
1519 kfree(chan->sc_filter);
1520 return 0;
1521}
1522
1523static
1524int get_syscall_nr(const char *syscall_name)
1525{
1526 int syscall_nr = -1;
1527 int i;
1528
1529 for (i = 0; i < ARRAY_SIZE(sc_table); i++) {
1530 const struct trace_syscall_entry *entry;
5b7ac358 1531 const char *it_name;
80f87dd2
MD
1532
1533 entry = &sc_table[i];
1534 if (!entry->desc)
1535 continue;
437d5aa5 1536 it_name = entry->desc->event_name;
5b7ac358
MD
1537 it_name += strlen(SYSCALL_ENTRY_STR);
1538 if (!strcmp(syscall_name, it_name)) {
80f87dd2
MD
1539 syscall_nr = i;
1540 break;
1541 }
1542 }
1543 return syscall_nr;
1544}
1545
1546static
1547int get_compat_syscall_nr(const char *syscall_name)
1548{
1549 int syscall_nr = -1;
1550 int i;
1551
1552 for (i = 0; i < ARRAY_SIZE(compat_sc_table); i++) {
1553 const struct trace_syscall_entry *entry;
5b7ac358 1554 const char *it_name;
80f87dd2
MD
1555
1556 entry = &compat_sc_table[i];
1557 if (!entry->desc)
1558 continue;
437d5aa5 1559 it_name = entry->desc->event_name;
5b7ac358
MD
1560 it_name += strlen(COMPAT_SYSCALL_ENTRY_STR);
1561 if (!strcmp(syscall_name, it_name)) {
80f87dd2
MD
1562 syscall_nr = i;
1563 break;
1564 }
1565 }
1566 return syscall_nr;
1567}
1568
12e579db
MD
1569static
1570uint32_t get_sc_tables_len(void)
1571{
1572 return ARRAY_SIZE(sc_table) + ARRAY_SIZE(compat_sc_table);
1573}
1574
badfe9f5 1575static
ade8a729
FD
1576const char *get_syscall_name(const char *desc_name,
1577 enum lttng_syscall_abi abi,
1578 enum lttng_syscall_entryexit entryexit)
80f87dd2 1579{
badfe9f5 1580 size_t prefix_len = 0;
80f87dd2 1581
80f87dd2 1582
ade8a729 1583 switch (entryexit) {
badfe9f5 1584 case LTTNG_SYSCALL_ENTRY:
ade8a729 1585 switch (abi) {
badfe9f5
MD
1586 case LTTNG_SYSCALL_ABI_NATIVE:
1587 prefix_len = strlen(SYSCALL_ENTRY_STR);
1588 break;
1589 case LTTNG_SYSCALL_ABI_COMPAT:
1590 prefix_len = strlen(COMPAT_SYSCALL_ENTRY_STR);
1591 break;
80f87dd2 1592 }
badfe9f5
MD
1593 break;
1594 case LTTNG_SYSCALL_EXIT:
ade8a729 1595 switch (abi) {
badfe9f5
MD
1596 case LTTNG_SYSCALL_ABI_NATIVE:
1597 prefix_len = strlen(SYSCALL_EXIT_STR);
1598 break;
1599 case LTTNG_SYSCALL_ABI_COMPAT:
1600 prefix_len = strlen(COMPAT_SYSCALL_EXIT_STR);
1601 break;
80f87dd2 1602 }
badfe9f5 1603 break;
80f87dd2 1604 }
badfe9f5 1605 WARN_ON_ONCE(prefix_len == 0);
ade8a729 1606 return desc_name + prefix_len;
badfe9f5
MD
1607}
1608
ade8a729
FD
1609static
1610int lttng_syscall_filter_enable(
1611 struct lttng_syscall_filter *filter,
1612 const char *desc_name, enum lttng_syscall_abi abi,
1613 enum lttng_syscall_entryexit entryexit)
badfe9f5 1614{
badfe9f5
MD
1615 const char *syscall_name;
1616 unsigned long *bitmap;
1617 int syscall_nr;
1618
ade8a729 1619 syscall_name = get_syscall_name(desc_name, abi, entryexit);
badfe9f5 1620
ade8a729 1621 switch (abi) {
badfe9f5
MD
1622 case LTTNG_SYSCALL_ABI_NATIVE:
1623 syscall_nr = get_syscall_nr(syscall_name);
1624 break;
1625 case LTTNG_SYSCALL_ABI_COMPAT:
1626 syscall_nr = get_compat_syscall_nr(syscall_name);
1627 break;
1628 default:
1629 return -EINVAL;
80f87dd2 1630 }
badfe9f5
MD
1631 if (syscall_nr < 0)
1632 return -ENOENT;
1633
ade8a729 1634 switch (entryexit) {
badfe9f5 1635 case LTTNG_SYSCALL_ENTRY:
ade8a729 1636 switch (abi) {
badfe9f5
MD
1637 case LTTNG_SYSCALL_ABI_NATIVE:
1638 bitmap = filter->sc_entry;
1639 break;
1640 case LTTNG_SYSCALL_ABI_COMPAT:
1641 bitmap = filter->sc_compat_entry;
1642 break;
6d9694d8
MD
1643 default:
1644 return -EINVAL;
80f87dd2 1645 }
badfe9f5
MD
1646 break;
1647 case LTTNG_SYSCALL_EXIT:
ade8a729 1648 switch (abi) {
badfe9f5
MD
1649 case LTTNG_SYSCALL_ABI_NATIVE:
1650 bitmap = filter->sc_exit;
1651 break;
1652 case LTTNG_SYSCALL_ABI_COMPAT:
1653 bitmap = filter->sc_compat_exit;
1654 break;
6d9694d8
MD
1655 default:
1656 return -EINVAL;
80f87dd2 1657 }
badfe9f5
MD
1658 break;
1659 default:
1660 return -EINVAL;
80f87dd2 1661 }
badfe9f5
MD
1662 if (test_bit(syscall_nr, bitmap))
1663 return -EEXIST;
1664 bitmap_set(bitmap, syscall_nr, 1);
80f87dd2 1665 return 0;
80f87dd2
MD
1666}
1667
8a8ac9a8 1668int lttng_syscall_filter_enable_event_notifier(
a67ba386 1669 struct lttng_kernel_event_notifier *event_notifier)
8a8ac9a8 1670{
a67ba386
MD
1671 struct lttng_event_notifier_group *group = event_notifier->priv->group;
1672 unsigned int syscall_id = event_notifier->priv->parent.u.syscall.syscall_id;
8a8ac9a8
FD
1673 struct hlist_head *dispatch_list;
1674 int ret = 0;
1675
a67ba386 1676 WARN_ON_ONCE(event_notifier->priv->parent.instrumentation != LTTNG_KERNEL_ABI_SYSCALL);
8a8ac9a8
FD
1677
1678 ret = lttng_syscall_filter_enable(group->sc_filter,
a67ba386
MD
1679 event_notifier->priv->parent.desc->event_name,
1680 event_notifier->priv->parent.u.syscall.abi,
1681 event_notifier->priv->parent.u.syscall.entryexit);
8a8ac9a8
FD
1682 if (ret) {
1683 goto end;
1684 }
1685
a67ba386 1686 switch (event_notifier->priv->parent.u.syscall.entryexit) {
8a8ac9a8 1687 case LTTNG_SYSCALL_ENTRY:
a67ba386 1688 switch (event_notifier->priv->parent.u.syscall.abi) {
8a8ac9a8
FD
1689 case LTTNG_SYSCALL_ABI_NATIVE:
1690 dispatch_list = &group->event_notifier_syscall_dispatch[syscall_id];
1691 break;
1692 case LTTNG_SYSCALL_ABI_COMPAT:
1693 dispatch_list = &group->event_notifier_compat_syscall_dispatch[syscall_id];
1694 break;
6866b1c7
MJ
1695 default:
1696 ret = -EINVAL;
1697 goto end;
8a8ac9a8
FD
1698 }
1699 break;
1700 case LTTNG_SYSCALL_EXIT:
a67ba386 1701 switch (event_notifier->priv->parent.u.syscall.abi) {
8a8ac9a8
FD
1702 case LTTNG_SYSCALL_ABI_NATIVE:
1703 dispatch_list = &group->event_notifier_exit_syscall_dispatch[syscall_id];
1704 break;
1705 case LTTNG_SYSCALL_ABI_COMPAT:
1706 dispatch_list = &group->event_notifier_exit_compat_syscall_dispatch[syscall_id];
1707 break;
6866b1c7
MJ
1708 default:
1709 ret = -EINVAL;
1710 goto end;
8a8ac9a8
FD
1711 }
1712 break;
6866b1c7
MJ
1713 default:
1714 ret = -EINVAL;
1715 goto end;
8a8ac9a8
FD
1716 }
1717
a67ba386 1718 hlist_add_head_rcu(&event_notifier->priv->parent.u.syscall.node, dispatch_list);
8a8ac9a8
FD
1719
1720end:
1721 return ret ;
1722}
1723
ade8a729
FD
1724int lttng_syscall_filter_enable_event(
1725 struct lttng_channel *channel,
a67ba386 1726 struct lttng_kernel_event_recorder *event_recorder)
80f87dd2 1727{
a67ba386 1728 WARN_ON_ONCE(event_recorder->priv->parent.instrumentation != LTTNG_KERNEL_ABI_SYSCALL);
ade8a729
FD
1729
1730 return lttng_syscall_filter_enable(channel->sc_filter,
a67ba386
MD
1731 event_recorder->priv->parent.desc->event_name,
1732 event_recorder->priv->parent.u.syscall.abi,
1733 event_recorder->priv->parent.u.syscall.entryexit);
ade8a729
FD
1734}
1735
1736static
1737int lttng_syscall_filter_disable(
1738 struct lttng_syscall_filter *filter,
1739 const char *desc_name, enum lttng_syscall_abi abi,
1740 enum lttng_syscall_entryexit entryexit)
1741{
badfe9f5
MD
1742 const char *syscall_name;
1743 unsigned long *bitmap;
1744 int syscall_nr;
80f87dd2 1745
ade8a729 1746 syscall_name = get_syscall_name(desc_name, abi, entryexit);
80f87dd2 1747
ade8a729 1748 switch (abi) {
badfe9f5
MD
1749 case LTTNG_SYSCALL_ABI_NATIVE:
1750 syscall_nr = get_syscall_nr(syscall_name);
1751 break;
1752 case LTTNG_SYSCALL_ABI_COMPAT:
1753 syscall_nr = get_compat_syscall_nr(syscall_name);
1754 break;
1755 default:
1756 return -EINVAL;
80f87dd2 1757 }
badfe9f5
MD
1758 if (syscall_nr < 0)
1759 return -ENOENT;
80f87dd2 1760
ade8a729 1761 switch (entryexit) {
badfe9f5 1762 case LTTNG_SYSCALL_ENTRY:
ade8a729 1763 switch (abi) {
badfe9f5
MD
1764 case LTTNG_SYSCALL_ABI_NATIVE:
1765 bitmap = filter->sc_entry;
1766 break;
1767 case LTTNG_SYSCALL_ABI_COMPAT:
1768 bitmap = filter->sc_compat_entry;
1769 break;
6d9694d8
MD
1770 default:
1771 return -EINVAL;
80f87dd2 1772 }
badfe9f5
MD
1773 break;
1774 case LTTNG_SYSCALL_EXIT:
ade8a729 1775 switch (abi) {
badfe9f5
MD
1776 case LTTNG_SYSCALL_ABI_NATIVE:
1777 bitmap = filter->sc_exit;
1778 break;
1779 case LTTNG_SYSCALL_ABI_COMPAT:
1780 bitmap = filter->sc_compat_exit;
1781 break;
6d9694d8
MD
1782 default:
1783 return -EINVAL;
80f87dd2 1784 }
badfe9f5
MD
1785 break;
1786 default:
1787 return -EINVAL;
80f87dd2 1788 }
badfe9f5
MD
1789 if (!test_bit(syscall_nr, bitmap))
1790 return -EEXIST;
1791 bitmap_clear(bitmap, syscall_nr, 1);
80f87dd2 1792
badfe9f5 1793 return 0;
259b6cb3 1794}
2d2464bd 1795
8a8ac9a8 1796int lttng_syscall_filter_disable_event_notifier(
a67ba386 1797 struct lttng_kernel_event_notifier *event_notifier)
8a8ac9a8 1798{
a67ba386 1799 struct lttng_event_notifier_group *group = event_notifier->priv->group;
8a8ac9a8
FD
1800 int ret;
1801
a67ba386 1802 WARN_ON_ONCE(event_notifier->priv->parent.instrumentation != LTTNG_KERNEL_ABI_SYSCALL);
8a8ac9a8
FD
1803
1804 ret = lttng_syscall_filter_disable(group->sc_filter,
a67ba386
MD
1805 event_notifier->priv->parent.desc->event_name,
1806 event_notifier->priv->parent.u.syscall.abi,
1807 event_notifier->priv->parent.u.syscall.entryexit);
8a8ac9a8
FD
1808 WARN_ON_ONCE(ret != 0);
1809
a67ba386 1810 hlist_del_rcu(&event_notifier->priv->parent.u.syscall.node);
8a8ac9a8
FD
1811 return 0;
1812}
1813
ade8a729
FD
1814int lttng_syscall_filter_disable_event(
1815 struct lttng_channel *channel,
a67ba386 1816 struct lttng_kernel_event_recorder *event_recorder)
ade8a729
FD
1817{
1818 return lttng_syscall_filter_disable(channel->sc_filter,
a67ba386
MD
1819 event_recorder->priv->parent.desc->event_name,
1820 event_recorder->priv->parent.u.syscall.abi,
1821 event_recorder->priv->parent.u.syscall.entryexit);
ade8a729
FD
1822}
1823
2d2464bd
MD
1824static
1825const struct trace_syscall_entry *syscall_list_get_entry(loff_t *pos)
1826{
1827 const struct trace_syscall_entry *entry;
1828 int iter = 0;
1829
1830 for (entry = sc_table;
1831 entry < sc_table + ARRAY_SIZE(sc_table);
1832 entry++) {
1833 if (iter++ >= *pos)
1834 return entry;
1835 }
1836 for (entry = compat_sc_table;
1837 entry < compat_sc_table + ARRAY_SIZE(compat_sc_table);
1838 entry++) {
1839 if (iter++ >= *pos)
1840 return entry;
1841 }
1842 /* End of list */
1843 return NULL;
1844}
1845
1846static
1847void *syscall_list_start(struct seq_file *m, loff_t *pos)
1848{
1849 return (void *) syscall_list_get_entry(pos);
1850}
1851
1852static
1853void *syscall_list_next(struct seq_file *m, void *p, loff_t *ppos)
1854{
1855 (*ppos)++;
1856 return (void *) syscall_list_get_entry(ppos);
1857}
1858
1859static
1860void syscall_list_stop(struct seq_file *m, void *p)
1861{
1862}
1863
12e579db
MD
1864static
1865int get_sc_table(const struct trace_syscall_entry *entry,
1866 const struct trace_syscall_entry **table,
1867 unsigned int *bitness)
1868{
1869 if (entry >= sc_table && entry < sc_table + ARRAY_SIZE(sc_table)) {
1870 if (bitness)
1871 *bitness = BITS_PER_LONG;
1872 if (table)
1873 *table = sc_table;
1874 return 0;
1875 }
1876 if (!(entry >= compat_sc_table
1877 && entry < compat_sc_table + ARRAY_SIZE(compat_sc_table))) {
1878 return -EINVAL;
1879 }
1880 if (bitness)
1881 *bitness = 32;
1882 if (table)
1883 *table = compat_sc_table;
1884 return 0;
1885}
1886
2d2464bd
MD
1887static
1888int syscall_list_show(struct seq_file *m, void *p)
1889{
1890 const struct trace_syscall_entry *table, *entry = p;
1891 unsigned int bitness;
d4291869 1892 unsigned long index;
12e579db 1893 int ret;
d4291869 1894 const char *name;
2d2464bd 1895
12e579db
MD
1896 ret = get_sc_table(entry, &table, &bitness);
1897 if (ret)
1898 return ret;
f4855b46
MD
1899 if (!entry->desc)
1900 return 0;
d4291869
MD
1901 if (table == sc_table) {
1902 index = entry - table;
437d5aa5 1903 name = &entry->desc->event_name[strlen(SYSCALL_ENTRY_STR)];
d4291869
MD
1904 } else {
1905 index = (entry - table) + ARRAY_SIZE(sc_table);
437d5aa5 1906 name = &entry->desc->event_name[strlen(COMPAT_SYSCALL_ENTRY_STR)];
d4291869 1907 }
12e579db 1908 seq_printf(m, "syscall { index = %lu; name = %s; bitness = %u; };\n",
d4291869 1909 index, name, bitness);
2d2464bd
MD
1910 return 0;
1911}
1912
1913static
1914const struct seq_operations lttng_syscall_list_seq_ops = {
1915 .start = syscall_list_start,
1916 .next = syscall_list_next,
1917 .stop = syscall_list_stop,
1918 .show = syscall_list_show,
1919};
1920
1921static
1922int lttng_syscall_list_open(struct inode *inode, struct file *file)
1923{
1924 return seq_open(file, &lttng_syscall_list_seq_ops);
1925}
1926
1927const struct file_operations lttng_syscall_list_fops = {
1928 .owner = THIS_MODULE,
1929 .open = lttng_syscall_list_open,
1930 .read = seq_read,
1931 .llseek = seq_lseek,
1932 .release = seq_release,
1933};
12e579db 1934
badfe9f5
MD
1935/*
1936 * A syscall is enabled if it is traced for either entry or exit.
1937 */
12e579db 1938long lttng_channel_syscall_mask(struct lttng_channel *channel,
606828e4 1939 struct lttng_kernel_abi_syscall_mask __user *usyscall_mask)
12e579db
MD
1940{
1941 uint32_t len, sc_tables_len, bitmask_len;
1942 int ret = 0, bit;
1943 char *tmp_mask;
1944 struct lttng_syscall_filter *filter;
1945
1946 ret = get_user(len, &usyscall_mask->len);
1947 if (ret)
1948 return ret;
1949 sc_tables_len = get_sc_tables_len();
1950 bitmask_len = ALIGN(sc_tables_len, 8) >> 3;
1951 if (len < sc_tables_len) {
1952 return put_user(sc_tables_len, &usyscall_mask->len);
1953 }
1954 /* Array is large enough, we can copy array to user-space. */
1955 tmp_mask = kzalloc(bitmask_len, GFP_KERNEL);
1956 if (!tmp_mask)
1957 return -ENOMEM;
1958 filter = channel->sc_filter;
1959
1960 for (bit = 0; bit < ARRAY_SIZE(sc_table); bit++) {
e2129868 1961 char state;
2f25059d
MD
1962
1963 if (channel->sc_table) {
3b82c4e1
MD
1964 if (!(READ_ONCE(channel->syscall_all_entry)
1965 || READ_ONCE(channel->syscall_all_exit)) && filter)
badfe9f5
MD
1966 state = test_bit(bit, filter->sc_entry)
1967 || test_bit(bit, filter->sc_exit);
2f25059d
MD
1968 else
1969 state = 1;
1970 } else {
1971 state = 0;
1972 }
1973 bt_bitfield_write_be(tmp_mask, char, bit, 1, state);
12e579db
MD
1974 }
1975 for (; bit < sc_tables_len; bit++) {
e2129868 1976 char state;
2f25059d
MD
1977
1978 if (channel->compat_sc_table) {
3b82c4e1
MD
1979 if (!(READ_ONCE(channel->syscall_all_entry)
1980 || READ_ONCE(channel->syscall_all_exit)) && filter)
2f25059d 1981 state = test_bit(bit - ARRAY_SIZE(sc_table),
badfe9f5
MD
1982 filter->sc_compat_entry)
1983 || test_bit(bit - ARRAY_SIZE(sc_table),
1984 filter->sc_compat_exit);
2f25059d
MD
1985 else
1986 state = 1;
1987 } else {
1988 state = 0;
1989 }
1990 bt_bitfield_write_be(tmp_mask, char, bit, 1, state);
12e579db
MD
1991 }
1992 if (copy_to_user(usyscall_mask->mask, tmp_mask, bitmask_len))
1993 ret = -EFAULT;
1994 kfree(tmp_mask);
1995 return ret;
1996}
082d4946
MD
1997
1998int lttng_abi_syscall_list(void)
1999{
2000 struct file *syscall_list_file;
2001 int file_fd, ret;
2002
4ac10b76 2003 file_fd = lttng_get_unused_fd();
082d4946
MD
2004 if (file_fd < 0) {
2005 ret = file_fd;
2006 goto fd_error;
2007 }
2008
2009 syscall_list_file = anon_inode_getfile("[lttng_syscall_list]",
2010 &lttng_syscall_list_fops,
2011 NULL, O_RDWR);
2012 if (IS_ERR(syscall_list_file)) {
2013 ret = PTR_ERR(syscall_list_file);
2014 goto file_error;
2015 }
2016 ret = lttng_syscall_list_fops.open(NULL, syscall_list_file);
2017 if (ret < 0)
2018 goto open_error;
2019 fd_install(file_fd, syscall_list_file);
082d4946
MD
2020 return file_fd;
2021
2022open_error:
2023 fput(syscall_list_file);
2024file_error:
2025 put_unused_fd(file_fd);
2026fd_error:
2027 return ret;
2028}
This page took 0.153188 seconds and 4 git commands to generate.