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