Refactoring: combine probe callbacks
[lttng-modules.git] / src / lttng-syscalls.c
1 /* SPDX-License-Identifier: (GPL-2.0-only or LGPL-2.1-only)
2 *
3 * lttng-syscalls.c
4 *
5 * LTTng syscall probes.
6 *
7 * Copyright (C) 2010-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
8 */
9
10 #include <linux/module.h>
11 #include <linux/slab.h>
12 #include <linux/compat.h>
13 #include <linux/err.h>
14 #include <linux/bitmap.h>
15 #include <linux/in.h>
16 #include <linux/in6.h>
17 #include <linux/seq_file.h>
18 #include <linux/stringify.h>
19 #include <linux/file.h>
20 #include <linux/anon_inodes.h>
21 #include <linux/fcntl.h>
22 #include <linux/mman.h>
23 #include <asm/ptrace.h>
24 #include <asm/syscall.h>
25
26 #include <lttng/bitfield.h>
27 #include <wrapper/tracepoint.h>
28 #include <wrapper/file.h>
29 #include <wrapper/rcu.h>
30 #include <wrapper/syscall.h>
31 #include <lttng/events.h>
32 #include <lttng/utils.h>
33
34 #ifndef CONFIG_COMPAT
35 # ifndef is_compat_task
36 # define is_compat_task() (0)
37 # endif
38 #endif
39
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
45 enum sc_type {
46 SC_TYPE_ENTRY,
47 SC_TYPE_EXIT,
48 SC_TYPE_COMPAT_ENTRY,
49 SC_TYPE_COMPAT_EXIT,
50 };
51
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)
61
62 static
63 void syscall_entry_event_probe(void *__data, struct pt_regs *regs, long id);
64 static
65 void syscall_exit_event_probe(void *__data, struct pt_regs *regs, long ret);
66
67 static
68 void syscall_entry_event_notifier_probe(void *__data, struct pt_regs *regs,
69 long id);
70 static
71 void syscall_exit_event_notifier_probe(void *__data, struct pt_regs *regs,
72 long ret);
73
74 /*
75 * Forward declarations for old kernels.
76 */
77 struct mmsghdr;
78 struct rlimit64;
79 struct oldold_utsname;
80 struct old_utsname;
81 struct sel_arg_struct;
82 struct mmap_arg_struct;
83 struct file_handle;
84 struct user_msghdr;
85
86 /*
87 * Forward declaration for kernels >= 5.6
88 */
89 struct timex;
90 struct timeval;
91 struct itimerval;
92 struct itimerspec;
93
94 #if (LTTNG_LINUX_VERSION_CODE >= LTTNG_KERNEL_VERSION(5,6,0))
95 typedef __kernel_old_time_t time_t;
96 #endif
97
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
104 /*
105 * Create LTTng tracepoint probes.
106 */
107 #define LTTNG_PACKAGE_BUILD
108 #define CREATE_TRACE_POINTS
109 #define TP_MODULE_NOINIT
110 #define TRACE_INCLUDE_PATH instrumentation/syscalls/headers
111
112 #define PARAMS(args...) args
113
114 /* Handle unknown syscalls */
115 #undef TRACE_SYSTEM
116 #define TRACE_SYSTEM syscalls_unknown
117 #include <instrumentation/syscalls/headers/syscalls_unknown.h>
118 #undef TRACE_SYSTEM
119
120 #define SC_ENTER
121
122 #undef sc_exit
123 #define sc_exit(...)
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__
130
131 /* Hijack probe callback for system call enter */
132 #undef TP_PROBE_CB
133 #define TP_PROBE_CB(_template) &syscall_entry_event_probe
134 #define SC_LTTNG_TRACEPOINT_EVENT(_name, _proto, _args, _fields) \
135 LTTNG_TRACEPOINT_EVENT(syscall_entry_##_name, PARAMS(_proto), PARAMS(_args), \
136 PARAMS(_fields))
137 #define SC_LTTNG_TRACEPOINT_EVENT_CODE(_name, _proto, _args, _locvar, _code_pre, _fields, _code_post) \
138 LTTNG_TRACEPOINT_EVENT_CODE(syscall_entry_##_name, PARAMS(_proto), PARAMS(_args), \
139 PARAMS(_locvar), PARAMS(_code_pre), \
140 PARAMS(_fields), PARAMS(_code_post))
141 #define SC_LTTNG_TRACEPOINT_EVENT_CLASS_NOARGS(_name, _fields) \
142 LTTNG_TRACEPOINT_EVENT_CLASS_NOARGS(syscall_entry_##_name, PARAMS(_fields))
143 #define SC_LTTNG_TRACEPOINT_EVENT_INSTANCE_NOARGS(_template, _name) \
144 LTTNG_TRACEPOINT_EVENT_INSTANCE_NOARGS(syscall_entry_##_template, syscall_entry_##_name)
145 /* Enumerations only defined at first inclusion. */
146 #define SC_LTTNG_TRACEPOINT_ENUM(_name, _values) \
147 LTTNG_TRACEPOINT_ENUM(_name, PARAMS(_values))
148 #undef TRACE_SYSTEM
149 #define TRACE_SYSTEM syscall_entry_integers
150 #define TRACE_INCLUDE_FILE syscalls_integers
151 #include <instrumentation/syscalls/headers/syscalls_integers.h>
152 #undef TRACE_INCLUDE_FILE
153 #undef TRACE_SYSTEM
154 #define TRACE_SYSTEM syscall_entry_pointers
155 #define TRACE_INCLUDE_FILE syscalls_pointers
156 #include <instrumentation/syscalls/headers/syscalls_pointers.h>
157 #undef TRACE_INCLUDE_FILE
158 #undef TRACE_SYSTEM
159 #undef SC_LTTNG_TRACEPOINT_ENUM
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
164 #undef TP_PROBE_CB
165 #undef _TRACE_SYSCALLS_INTEGERS_H
166 #undef _TRACE_SYSCALLS_POINTERS_H
167
168 /* Hijack probe callback for compat system call enter */
169 #define TP_PROBE_CB(_template) &syscall_entry_event_probe
170 #define LTTNG_SC_COMPAT
171 #define SC_LTTNG_TRACEPOINT_EVENT(_name, _proto, _args, _fields) \
172 LTTNG_TRACEPOINT_EVENT(compat_syscall_entry_##_name, PARAMS(_proto), PARAMS(_args), \
173 PARAMS(_fields))
174 #define SC_LTTNG_TRACEPOINT_EVENT_CODE(_name, _proto, _args, _locvar, _code_pre, _fields, _code_post) \
175 LTTNG_TRACEPOINT_EVENT_CODE(compat_syscall_entry_##_name, PARAMS(_proto), PARAMS(_args), \
176 PARAMS(_locvar), PARAMS(_code_pre), PARAMS(_fields), PARAMS(_code_post))
177 #define SC_LTTNG_TRACEPOINT_EVENT_CLASS_NOARGS(_name, _fields) \
178 LTTNG_TRACEPOINT_EVENT_CLASS_NOARGS(compat_syscall_entry_##_name, PARAMS(_fields))
179 #define SC_LTTNG_TRACEPOINT_EVENT_INSTANCE_NOARGS(_template, _name) \
180 LTTNG_TRACEPOINT_EVENT_INSTANCE_NOARGS(compat_syscall_entry_##_template, \
181 compat_syscall_entry_##_name)
182 /* Enumerations only defined at inital inclusion (not here). */
183 #define SC_LTTNG_TRACEPOINT_ENUM(_name, _values)
184 #define TRACE_SYSTEM compat_syscall_entry_integers
185 #define TRACE_INCLUDE_FILE compat_syscalls_integers
186 #include <instrumentation/syscalls/headers/compat_syscalls_integers.h>
187 #undef TRACE_INCLUDE_FILE
188 #undef TRACE_SYSTEM
189 #define TRACE_SYSTEM compat_syscall_entry_pointers
190 #define TRACE_INCLUDE_FILE compat_syscalls_pointers
191 #include <instrumentation/syscalls/headers/compat_syscalls_pointers.h>
192 #undef TRACE_INCLUDE_FILE
193 #undef TRACE_SYSTEM
194 #undef SC_LTTNG_TRACEPOINT_ENUM
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
199 #undef TP_PROBE_CB
200 #undef _TRACE_SYSCALLS_INTEGERS_H
201 #undef _TRACE_SYSCALLS_POINTERS_H
202 #undef LTTNG_SC_COMPAT
203
204 #undef SC_ENTER
205
206 #define SC_EXIT
207
208 #undef sc_exit
209 #define sc_exit(...) __VA_ARGS__
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__
216
217 /* Hijack probe callback for system call exit */
218 #define TP_PROBE_CB(_template) &syscall_exit_event_probe
219 #define SC_LTTNG_TRACEPOINT_EVENT(_name, _proto, _args, _fields) \
220 LTTNG_TRACEPOINT_EVENT(syscall_exit_##_name, PARAMS(_proto), PARAMS(_args), \
221 PARAMS(_fields))
222 #define SC_LTTNG_TRACEPOINT_EVENT_CODE(_name, _proto, _args, _locvar, _code_pre, _fields, _code_post) \
223 LTTNG_TRACEPOINT_EVENT_CODE(syscall_exit_##_name, PARAMS(_proto), PARAMS(_args), \
224 PARAMS(_locvar), PARAMS(_code_pre), PARAMS(_fields), PARAMS(_code_post))
225 #define SC_LTTNG_TRACEPOINT_EVENT_CLASS_NOARGS(_name, _fields) \
226 LTTNG_TRACEPOINT_EVENT_CLASS_NOARGS(syscall_exit_##_name, PARAMS(_fields))
227 #define SC_LTTNG_TRACEPOINT_EVENT_INSTANCE_NOARGS(_template, _name) \
228 LTTNG_TRACEPOINT_EVENT_INSTANCE_NOARGS(syscall_exit_##_template, \
229 syscall_exit_##_name)
230 /* Enumerations only defined at inital inclusion (not here). */
231 #define SC_LTTNG_TRACEPOINT_ENUM(_name, _values)
232 #define TRACE_SYSTEM syscall_exit_integers
233 #define TRACE_INCLUDE_FILE syscalls_integers
234 #include <instrumentation/syscalls/headers/syscalls_integers.h>
235 #undef TRACE_INCLUDE_FILE
236 #undef TRACE_SYSTEM
237 #define TRACE_SYSTEM syscall_exit_pointers
238 #define TRACE_INCLUDE_FILE syscalls_pointers
239 #include <instrumentation/syscalls/headers/syscalls_pointers.h>
240 #undef TRACE_INCLUDE_FILE
241 #undef TRACE_SYSTEM
242 #undef SC_LTTNG_TRACEPOINT_ENUM
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
247 #undef TP_PROBE_CB
248 #undef _TRACE_SYSCALLS_INTEGERS_H
249 #undef _TRACE_SYSCALLS_POINTERS_H
250
251
252 /* Hijack probe callback for compat system call exit */
253 #define TP_PROBE_CB(_template) &syscall_exit_event_probe
254 #define LTTNG_SC_COMPAT
255 #define SC_LTTNG_TRACEPOINT_EVENT(_name, _proto, _args, _fields) \
256 LTTNG_TRACEPOINT_EVENT(compat_syscall_exit_##_name, PARAMS(_proto), PARAMS(_args), \
257 PARAMS(_fields))
258 #define SC_LTTNG_TRACEPOINT_EVENT_CODE(_name, _proto, _args, _locvar, _code_pre, _fields, _code_post) \
259 LTTNG_TRACEPOINT_EVENT_CODE(compat_syscall_exit_##_name, PARAMS(_proto), PARAMS(_args), \
260 PARAMS(_locvar), PARAMS(_code_pre), PARAMS(_fields), PARAMS(_code_post))
261 #define SC_LTTNG_TRACEPOINT_EVENT_CLASS_NOARGS(_name, _fields) \
262 LTTNG_TRACEPOINT_EVENT_CLASS_NOARGS(compat_syscall_exit_##_name, PARAMS(_fields))
263 #define SC_LTTNG_TRACEPOINT_EVENT_INSTANCE_NOARGS(_template, _name) \
264 LTTNG_TRACEPOINT_EVENT_INSTANCE_NOARGS(compat_syscall_exit_##_template, \
265 compat_syscall_exit_##_name)
266 /* Enumerations only defined at inital inclusion (not here). */
267 #define SC_LTTNG_TRACEPOINT_ENUM(_name, _values)
268 #define TRACE_SYSTEM compat_syscall_exit_integers
269 #define TRACE_INCLUDE_FILE compat_syscalls_integers
270 #include <instrumentation/syscalls/headers/compat_syscalls_integers.h>
271 #undef TRACE_INCLUDE_FILE
272 #undef TRACE_SYSTEM
273 #define TRACE_SYSTEM compat_syscall_exit_pointers
274 #define TRACE_INCLUDE_FILE compat_syscalls_pointers
275 #include <instrumentation/syscalls/headers/compat_syscalls_pointers.h>
276 #undef TRACE_INCLUDE_FILE
277 #undef TRACE_SYSTEM
278 #undef SC_LTTNG_TRACEPOINT_ENUM
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
283 #undef TP_PROBE_CB
284 #undef _TRACE_SYSCALLS_INTEGERS_H
285 #undef _TRACE_SYSCALLS_POINTERS_H
286 #undef LTTNG_SC_COMPAT
287
288 #undef SC_EXIT
289
290 #undef TP_MODULE_NOINIT
291 #undef LTTNG_PACKAGE_BUILD
292 #undef CREATE_TRACE_POINTS
293
294 struct trace_syscall_entry {
295 void *event_func;
296 const struct lttng_kernel_event_desc *desc;
297 const struct lttng_kernel_event_field **fields;
298 unsigned int nrargs;
299 };
300
301 #define CREATE_SYSCALL_TABLE
302
303 #define SC_ENTER
304
305 #undef sc_exit
306 #define sc_exit(...)
307
308 #undef TRACE_SYSCALL_TABLE
309 #define TRACE_SYSCALL_TABLE(_template, _name, _nr, _nrargs) \
310 [ _nr ] = { \
311 .event_func = __event_probe__syscall_entry_##_template, \
312 .nrargs = (_nrargs), \
313 .fields = __event_fields___syscall_entry_##_template, \
314 .desc = &__event_desc___syscall_entry_##_name, \
315 },
316
317 /* Event syscall enter tracing table */
318 static const struct trace_syscall_entry sc_table[] = {
319 #include <instrumentation/syscalls/headers/syscalls_integers.h>
320 #include <instrumentation/syscalls/headers/syscalls_pointers.h>
321 };
322
323 #undef TRACE_SYSCALL_TABLE
324 #define TRACE_SYSCALL_TABLE(_template, _name, _nr, _nrargs) \
325 [ _nr ] = { \
326 .event_func = __event_probe__compat_syscall_entry_##_template, \
327 .nrargs = (_nrargs), \
328 .fields = __event_fields___compat_syscall_entry_##_template, \
329 .desc = &__event_desc___compat_syscall_entry_##_name, \
330 },
331
332 /* Event compat syscall enter table */
333 const struct trace_syscall_entry compat_sc_table[] = {
334 #include <instrumentation/syscalls/headers/compat_syscalls_integers.h>
335 #include <instrumentation/syscalls/headers/compat_syscalls_pointers.h>
336 };
337
338 #undef SC_ENTER
339
340 #define SC_EXIT
341
342 #undef sc_exit
343 #define sc_exit(...) __VA_ARGS__
344
345 #undef TRACE_SYSCALL_TABLE
346 #define TRACE_SYSCALL_TABLE(_template, _name, _nr, _nrargs) \
347 [ _nr ] = { \
348 .event_func = __event_probe__syscall_exit_##_template, \
349 .nrargs = (_nrargs), \
350 .fields = __event_fields___syscall_exit_##_template, \
351 .desc = &__event_desc___syscall_exit_##_name, \
352 },
353
354 /* Event syscall exit table */
355 static const struct trace_syscall_entry sc_exit_table[] = {
356 #include <instrumentation/syscalls/headers/syscalls_integers.h>
357 #include <instrumentation/syscalls/headers/syscalls_pointers.h>
358 };
359
360 #undef TRACE_SYSCALL_TABLE
361 #define TRACE_SYSCALL_TABLE(_template, _name, _nr, _nrargs) \
362 [ _nr ] = { \
363 .event_func = __event_probe__compat_syscall_exit_##_template, \
364 .nrargs = (_nrargs), \
365 .fields = __event_fields___compat_syscall_exit_##_template, \
366 .desc = &__event_desc___compat_syscall_exit_##_name, \
367 },
368
369 /* Event compat syscall exit table */
370 const struct trace_syscall_entry compat_sc_exit_table[] = {
371 #include <instrumentation/syscalls/headers/compat_syscalls_integers.h>
372 #include <instrumentation/syscalls/headers/compat_syscalls_pointers.h>
373 };
374
375 #undef SC_EXIT
376
377 #undef CREATE_SYSCALL_TABLE
378
379 struct lttng_syscall_filter {
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);
384 };
385
386 static void syscall_entry_event_unknown(struct hlist_head *unknown_action_list_head,
387 struct pt_regs *regs, long id)
388 {
389 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
390 struct lttng_kernel_event_common_private *event_priv;
391
392 lttng_syscall_get_arguments(current, regs, args);
393 lttng_hlist_for_each_entry_rcu(event_priv, unknown_action_list_head, u.syscall.node) {
394 if (unlikely(in_compat_syscall()))
395 __event_probe__compat_syscall_entry_unknown(event_priv->pub, id, args);
396 else
397 __event_probe__syscall_entry_unknown(event_priv->pub, id, args);
398 }
399 }
400
401 static __always_inline
402 void syscall_entry_event_call_func(struct hlist_head *action_list,
403 void *func, unsigned int nrargs,
404 struct pt_regs *regs)
405 {
406 struct lttng_kernel_event_common_private *event_priv;
407
408 switch (nrargs) {
409 case 0:
410 {
411 void (*fptr)(void *__data) = func;
412
413 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node)
414 fptr(event_priv->pub);
415 break;
416 }
417 case 1:
418 {
419 void (*fptr)(void *__data, unsigned long arg0) = func;
420 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
421
422 lttng_syscall_get_arguments(current, regs, args);
423 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node)
424 fptr(event_priv->pub, args[0]);
425 break;
426 }
427 case 2:
428 {
429 void (*fptr)(void *__data,
430 unsigned long arg0,
431 unsigned long arg1) = func;
432 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
433
434 lttng_syscall_get_arguments(current, regs, args);
435 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node)
436 fptr(event_priv->pub, args[0], args[1]);
437 break;
438 }
439 case 3:
440 {
441 void (*fptr)(void *__data,
442 unsigned long arg0,
443 unsigned long arg1,
444 unsigned long arg2) = func;
445 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
446
447 lttng_syscall_get_arguments(current, regs, args);
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]);
450 break;
451 }
452 case 4:
453 {
454 void (*fptr)(void *__data,
455 unsigned long arg0,
456 unsigned long arg1,
457 unsigned long arg2,
458 unsigned long arg3) = func;
459 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
460
461 lttng_syscall_get_arguments(current, regs, args);
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]);
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,
473 unsigned long arg4) = func;
474 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
475
476 lttng_syscall_get_arguments(current, regs, args);
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]);
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,
489 unsigned long arg5) = func;
490 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
491
492 lttng_syscall_get_arguments(current, regs, args);
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],
495 args[3], args[4], args[5]);
496 break;
497 }
498 default:
499 break;
500 }
501 }
502
503 void syscall_entry_event_probe(void *__data, struct pt_regs *regs, long id)
504 {
505 struct lttng_channel *chan = __data;
506 struct hlist_head *action_list, *unknown_action_list;
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
514 || (!READ_ONCE(chan->syscall_all_entry) && !test_bit(id, filter->sc_compat_entry))) {
515 /* System call filtered out. */
516 return;
517 }
518 table = compat_sc_table;
519 table_len = ARRAY_SIZE(compat_sc_table);
520 unknown_action_list = &chan->sc_compat_unknown;
521 } else {
522 struct lttng_syscall_filter *filter = chan->sc_filter;
523
524 if (id < 0 || id >= NR_syscalls
525 || (!READ_ONCE(chan->syscall_all_entry) && !test_bit(id, filter->sc_entry))) {
526 /* System call filtered out. */
527 return;
528 }
529 table = sc_table;
530 table_len = ARRAY_SIZE(sc_table);
531 unknown_action_list = &chan->sc_unknown;
532 }
533 if (unlikely(id < 0 || id >= table_len)) {
534 syscall_entry_event_unknown(unknown_action_list, regs, id);
535 return;
536 }
537
538 entry = &table[id];
539 if (!entry->event_func) {
540 syscall_entry_event_unknown(unknown_action_list, regs, id);
541 return;
542 }
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
552 syscall_entry_event_call_func(action_list, entry->event_func, entry->nrargs, regs);
553 }
554
555 void 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)) {
590 syscall_entry_event_unknown(unknown_dispatch_list,
591 regs, id);
592 return;
593 }
594
595 entry = &table[id];
596 if (!entry->event_func) {
597 syscall_entry_event_unknown(unknown_dispatch_list,
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
610 syscall_entry_event_call_func(dispatch_list,
611 entry->event_func, entry->nrargs, regs);
612 }
613
614 static void syscall_exit_event_unknown(struct hlist_head *unknown_action_list_head,
615 struct pt_regs *regs, long id, long ret)
616 {
617 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
618 struct lttng_kernel_event_common_private *event_priv;
619
620 lttng_syscall_get_arguments(current, regs, args);
621 lttng_hlist_for_each_entry_rcu(event_priv, unknown_action_list_head, u.syscall.node) {
622 if (unlikely(in_compat_syscall()))
623 __event_probe__compat_syscall_exit_unknown(event_priv->pub, id, ret,
624 args);
625 else
626 __event_probe__syscall_exit_unknown(event_priv->pub, id, ret, args);
627 }
628 }
629
630 static __always_inline
631 void syscall_exit_event_call_func(struct hlist_head *action_list,
632 void *func, unsigned int nrargs,
633 struct pt_regs *regs, long ret)
634 {
635 struct lttng_kernel_event_common_private *event_priv;
636
637 switch (nrargs) {
638 case 0:
639 {
640 void (*fptr)(void *__data, long ret) = func;
641
642 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node)
643 fptr(event_priv->pub, ret);
644 break;
645 }
646 case 1:
647 {
648 void (*fptr)(void *__data,
649 long ret,
650 unsigned long arg0) = func;
651 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
652
653 lttng_syscall_get_arguments(current, regs, args);
654 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node)
655 fptr(event_priv->pub, ret, args[0]);
656 break;
657 }
658 case 2:
659 {
660 void (*fptr)(void *__data,
661 long ret,
662 unsigned long arg0,
663 unsigned long arg1) = func;
664 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
665
666 lttng_syscall_get_arguments(current, regs, args);
667 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node)
668 fptr(event_priv->pub, ret, args[0], args[1]);
669 break;
670 }
671 case 3:
672 {
673 void (*fptr)(void *__data,
674 long ret,
675 unsigned long arg0,
676 unsigned long arg1,
677 unsigned long arg2) = func;
678 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
679
680 lttng_syscall_get_arguments(current, regs, args);
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]);
683 break;
684 }
685 case 4:
686 {
687 void (*fptr)(void *__data,
688 long ret,
689 unsigned long arg0,
690 unsigned long arg1,
691 unsigned long arg2,
692 unsigned long arg3) = func;
693 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
694
695 lttng_syscall_get_arguments(current, regs, args);
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]);
698 break;
699 }
700 case 5:
701 {
702 void (*fptr)(void *__data,
703 long ret,
704 unsigned long arg0,
705 unsigned long arg1,
706 unsigned long arg2,
707 unsigned long arg3,
708 unsigned long arg4) = func;
709 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
710
711 lttng_syscall_get_arguments(current, regs, args);
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]);
714 break;
715 }
716 case 6:
717 {
718 void (*fptr)(void *__data,
719 long ret,
720 unsigned long arg0,
721 unsigned long arg1,
722 unsigned long arg2,
723 unsigned long arg3,
724 unsigned long arg4,
725 unsigned long arg5) = func;
726 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
727
728 lttng_syscall_get_arguments(current, regs, args);
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],
731 args[3], args[4], args[5]);
732 break;
733 }
734 default:
735 break;
736 }
737 }
738
739 void 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
791 syscall_exit_event_call_func(action_list, entry->event_func, entry->nrargs,
792 regs, ret);
793 }
794
795 static
796 void 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)) {
834 syscall_exit_event_unknown(unknown_dispatch_list,
835 regs, id, ret);
836 return;
837 }
838
839 entry = &table[id];
840 if (!entry->event_func) {
841 syscall_entry_event_unknown(unknown_dispatch_list,
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
854 syscall_exit_event_call_func(dispatch_list,
855 entry->event_func, entry->nrargs, regs, ret);
856 }
857 /*
858 * noinline to diminish caller stack size.
859 * Should be called with sessions lock held.
860 */
861 static
862 int 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,
864 enum sc_type type)
865 {
866 struct lttng_channel *chan = event_enabler->chan;
867 struct lttng_session *session = chan->session;
868 unsigned int i;
869
870 /* Allocate events for each syscall matching enabler, insert into table */
871 for (i = 0; i < table_len; i++) {
872 const struct lttng_kernel_event_desc *desc = table[i].desc;
873 struct lttng_kernel_abi_event ev;
874 struct lttng_kernel_event_recorder_private *event_recorder_priv;
875 struct lttng_kernel_event_recorder *event_recorder;
876 struct hlist_head *head;
877 bool found = false;
878
879 if (!desc) {
880 /* Unknown syscall */
881 continue;
882 }
883 if (lttng_desc_match_enabler(desc,
884 lttng_event_enabler_as_enabler(event_enabler)) <= 0)
885 continue;
886 /*
887 * Check if already created.
888 */
889 head = utils_borrow_hash_table_bucket(
890 session->events_ht.table, LTTNG_EVENT_HT_SIZE,
891 desc->event_name);
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)
895 found = true;
896 }
897 if (found)
898 continue;
899
900 /* We need to create an event for this syscall/enabler. */
901 memset(&ev, 0, sizeof(ev));
902 switch (type) {
903 case SC_TYPE_ENTRY:
904 ev.u.syscall.entryexit = LTTNG_KERNEL_ABI_SYSCALL_ENTRY;
905 ev.u.syscall.abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_NATIVE;
906 break;
907 case SC_TYPE_EXIT:
908 ev.u.syscall.entryexit = LTTNG_KERNEL_ABI_SYSCALL_EXIT;
909 ev.u.syscall.abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_NATIVE;
910 break;
911 case SC_TYPE_COMPAT_ENTRY:
912 ev.u.syscall.entryexit = LTTNG_KERNEL_ABI_SYSCALL_ENTRY;
913 ev.u.syscall.abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_COMPAT;
914 break;
915 case SC_TYPE_COMPAT_EXIT:
916 ev.u.syscall.entryexit = LTTNG_KERNEL_ABI_SYSCALL_EXIT;
917 ev.u.syscall.abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_COMPAT;
918 break;
919 }
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;
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)) {
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 */
932 return PTR_ERR(event_recorder);
933 }
934 hlist_add_head(&event_recorder->priv->parent.u.syscall.node, &chan_table[i]);
935 }
936 return 0;
937 }
938
939 /*
940 * Should be called with sessions lock held.
941 */
942 int lttng_syscalls_register_event(struct lttng_event_enabler *event_enabler)
943 {
944 struct lttng_channel *chan = event_enabler->chan;
945 struct lttng_kernel_abi_event ev;
946 int ret;
947
948 wrapper_vmalloc_sync_mappings();
949
950 if (!chan->sc_table) {
951 /* create syscall table mapping syscall to events */
952 chan->sc_table = kzalloc(sizeof(struct lttng_kernel_event_recorder *)
953 * ARRAY_SIZE(sc_table), GFP_KERNEL);
954 if (!chan->sc_table)
955 return -ENOMEM;
956 }
957 if (!chan->sc_exit_table) {
958 /* create syscall table mapping syscall to events */
959 chan->sc_exit_table = kzalloc(sizeof(struct lttng_kernel_event_recorder *)
960 * ARRAY_SIZE(sc_exit_table), GFP_KERNEL);
961 if (!chan->sc_exit_table)
962 return -ENOMEM;
963 }
964
965
966 #ifdef CONFIG_COMPAT
967 if (!chan->compat_sc_table) {
968 /* create syscall table mapping compat syscall to events */
969 chan->compat_sc_table = kzalloc(sizeof(struct lttng_kernel_event_recorder *)
970 * ARRAY_SIZE(compat_sc_table), GFP_KERNEL);
971 if (!chan->compat_sc_table)
972 return -ENOMEM;
973 }
974
975 if (!chan->compat_sc_exit_table) {
976 /* create syscall table mapping compat syscall to events */
977 chan->compat_sc_exit_table = kzalloc(sizeof(struct lttng_kernel_event_recorder *)
978 * ARRAY_SIZE(compat_sc_exit_table), GFP_KERNEL);
979 if (!chan->compat_sc_exit_table)
980 return -ENOMEM;
981 }
982 #endif
983 if (hlist_empty(&chan->sc_unknown)) {
984 const struct lttng_kernel_event_desc *desc =
985 &__event_desc___syscall_entry_unknown;
986 struct lttng_kernel_event_recorder *event_recorder;
987
988 memset(&ev, 0, sizeof(ev));
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;
994 event_recorder = _lttng_kernel_event_recorder_create(chan, &ev, desc,
995 ev.instrumentation);
996 WARN_ON_ONCE(!event_recorder);
997 if (IS_ERR(event_recorder)) {
998 return PTR_ERR(event_recorder);
999 }
1000 hlist_add_head(&event_recorder->priv->parent.u.syscall.node, &chan->sc_unknown);
1001 }
1002
1003 if (hlist_empty(&chan->sc_compat_unknown)) {
1004 const struct lttng_kernel_event_desc *desc =
1005 &__event_desc___compat_syscall_entry_unknown;
1006 struct lttng_kernel_event_recorder *event_recorder;
1007
1008 memset(&ev, 0, sizeof(ev));
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;
1014 event_recorder = _lttng_kernel_event_recorder_create(chan, &ev, desc,
1015 ev.instrumentation);
1016 WARN_ON_ONCE(!event_recorder);
1017 if (IS_ERR(event_recorder)) {
1018 return PTR_ERR(event_recorder);
1019 }
1020 hlist_add_head(&event_recorder->priv->parent.u.syscall.node, &chan->sc_compat_unknown);
1021 }
1022
1023 if (hlist_empty(&chan->compat_sc_exit_unknown)) {
1024 const struct lttng_kernel_event_desc *desc =
1025 &__event_desc___compat_syscall_exit_unknown;
1026 struct lttng_kernel_event_recorder *event_recorder;
1027
1028 memset(&ev, 0, sizeof(ev));
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;
1034 event_recorder = _lttng_kernel_event_recorder_create(chan, &ev, desc,
1035 ev.instrumentation);
1036 WARN_ON_ONCE(!event_recorder);
1037 if (IS_ERR(event_recorder)) {
1038 return PTR_ERR(event_recorder);
1039 }
1040 hlist_add_head(&event_recorder->priv->parent.u.syscall.node, &chan->compat_sc_exit_unknown);
1041 }
1042
1043 if (hlist_empty(&chan->sc_exit_unknown)) {
1044 const struct lttng_kernel_event_desc *desc =
1045 &__event_desc___syscall_exit_unknown;
1046 struct lttng_kernel_event_recorder *event_recorder;
1047
1048 memset(&ev, 0, sizeof(ev));
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;
1054 event_recorder = _lttng_kernel_event_recorder_create(chan, &ev, desc,
1055 ev.instrumentation);
1056 WARN_ON_ONCE(!event_recorder);
1057 if (IS_ERR(event_recorder)) {
1058 return PTR_ERR(event_recorder);
1059 }
1060 hlist_add_head(&event_recorder->priv->parent.u.syscall.node, &chan->sc_exit_unknown);
1061 }
1062
1063 ret = lttng_create_syscall_event_if_missing(sc_table, ARRAY_SIZE(sc_table),
1064 chan->sc_table, event_enabler, SC_TYPE_ENTRY);
1065 if (ret)
1066 return ret;
1067 ret = lttng_create_syscall_event_if_missing(sc_exit_table, ARRAY_SIZE(sc_exit_table),
1068 chan->sc_exit_table, event_enabler, SC_TYPE_EXIT);
1069 if (ret)
1070 return ret;
1071
1072 #ifdef CONFIG_COMPAT
1073 ret = lttng_create_syscall_event_if_missing(compat_sc_table, ARRAY_SIZE(compat_sc_table),
1074 chan->compat_sc_table, event_enabler, SC_TYPE_COMPAT_ENTRY);
1075 if (ret)
1076 return ret;
1077 ret = lttng_create_syscall_event_if_missing(compat_sc_exit_table, ARRAY_SIZE(compat_sc_exit_table),
1078 chan->compat_sc_exit_table, event_enabler, SC_TYPE_COMPAT_EXIT);
1079 if (ret)
1080 return ret;
1081 #endif
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
1090 if (!chan->sys_enter_registered) {
1091 ret = lttng_wrapper_tracepoint_probe_register("sys_enter",
1092 (void *) syscall_entry_event_probe, chan);
1093 if (ret)
1094 return ret;
1095 chan->sys_enter_registered = 1;
1096 }
1097 /*
1098 * We change the name of sys_exit tracepoint due to namespace
1099 * conflict with sys_exit syscall entry.
1100 */
1101 if (!chan->sys_exit_registered) {
1102 ret = lttng_wrapper_tracepoint_probe_register("sys_exit",
1103 (void *) syscall_exit_event_probe, chan);
1104 if (ret) {
1105 WARN_ON_ONCE(lttng_wrapper_tracepoint_probe_unregister("sys_enter",
1106 (void *) syscall_entry_event_probe, chan));
1107 return ret;
1108 }
1109 chan->sys_exit_registered = 1;
1110 }
1111 return ret;
1112 }
1113
1114 /*
1115 * Should be called with sessions lock held.
1116 */
1117 int lttng_syscalls_register_event_notifier(
1118 struct lttng_event_notifier_enabler *event_notifier_enabler)
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
1217 static
1218 int create_unknown_event_notifier(
1219 struct lttng_event_notifier_enabler *event_notifier_enabler,
1220 enum sc_type type)
1221 {
1222 struct lttng_kernel_event_notifier_private *event_notifier_priv;
1223 struct lttng_kernel_event_notifier *event_notifier;
1224 const struct lttng_kernel_event_desc *desc;
1225 struct lttng_event_notifier_group *group = event_notifier_enabler->group;
1226 struct lttng_kernel_abi_event_notifier event_notifier_param;
1227 uint64_t user_token = event_notifier_enabler->base.user_token;
1228 uint64_t error_counter_index = event_notifier_enabler->error_counter_index;
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;
1234 enum lttng_kernel_abi_syscall_abi abi;
1235 enum lttng_kernel_abi_syscall_entryexit entryexit;
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;
1242 entryexit = LTTNG_KERNEL_ABI_SYSCALL_ENTRY;
1243 abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_NATIVE;
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;
1248 entryexit = LTTNG_KERNEL_ABI_SYSCALL_EXIT;
1249 abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_NATIVE;
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;
1254 entryexit = LTTNG_KERNEL_ABI_SYSCALL_ENTRY;
1255 abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_COMPAT;
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;
1260 entryexit = LTTNG_KERNEL_ABI_SYSCALL_EXIT;
1261 abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_COMPAT;
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,
1271 LTTNG_EVENT_NOTIFIER_HT_SIZE, desc->event_name);
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)
1275 found = true;
1276 }
1277 if (found)
1278 goto end;
1279
1280 memset(&event_notifier_param, 0, sizeof(event_notifier_param));
1281 strncat(event_notifier_param.event.name, desc->event_name,
1282 LTTNG_KERNEL_ABI_SYM_NAME_LEN - strlen(event_notifier_param.event.name) - 1);
1283
1284 event_notifier_param.event.name[LTTNG_KERNEL_ABI_SYM_NAME_LEN - 1] = '\0';
1285
1286 event_notifier_param.event.instrumentation = LTTNG_KERNEL_ABI_SYSCALL;
1287 event_notifier_param.event.u.syscall.abi = abi;
1288 event_notifier_param.event.u.syscall.entryexit = entryexit;
1289
1290 event_notifier = _lttng_event_notifier_create(desc, user_token,
1291 error_counter_index, group, &event_notifier_param,
1292 event_notifier_param.event.instrumentation);
1293 if (IS_ERR(event_notifier)) {
1294 printk(KERN_INFO "Unable to create unknown notifier %s\n",
1295 desc->event_name);
1296 ret = -ENOMEM;
1297 goto end;
1298 }
1299
1300 hlist_add_head_rcu(&event_notifier->priv->parent.u.syscall.node, unknown_dispatch_list);
1301
1302 end:
1303 return ret;
1304 }
1305
1306 static int create_matching_event_notifiers(
1307 struct lttng_event_notifier_enabler *event_notifier_enabler,
1308 const struct trace_syscall_entry *table,
1309 size_t table_len, enum sc_type type)
1310 {
1311 struct lttng_event_notifier_group *group = event_notifier_enabler->group;
1312 const struct lttng_kernel_event_desc *desc;
1313 uint64_t user_token = event_notifier_enabler->base.user_token;
1314 uint64_t error_counter_index = event_notifier_enabler->error_counter_index;
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++) {
1320 struct lttng_kernel_event_notifier_private *event_notifier_priv;
1321 struct lttng_kernel_event_notifier *event_notifier;
1322 struct lttng_kernel_abi_event_notifier event_notifier_param;
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,
1340 LTTNG_EVENT_NOTIFIER_HT_SIZE, desc->event_name);
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)
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:
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;
1354 break;
1355 case SC_TYPE_EXIT:
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;
1358 break;
1359 case SC_TYPE_COMPAT_ENTRY:
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;
1362 break;
1363 case SC_TYPE_COMPAT_EXIT:
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;
1366 break;
1367 }
1368 strncat(event_notifier_param.event.name, desc->event_name,
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;
1372
1373 event_notifier = _lttng_event_notifier_create(desc, user_token,
1374 error_counter_index, group, &event_notifier_param,
1375 event_notifier_param.event.instrumentation);
1376 if (IS_ERR(event_notifier)) {
1377 printk(KERN_INFO "Unable to create event_notifier %s\n",
1378 desc->event_name);
1379 ret = -ENOMEM;
1380 goto end;
1381 }
1382
1383 event_notifier->priv->parent.u.syscall.syscall_id = i;
1384 }
1385
1386 end:
1387 return ret;
1388
1389 }
1390
1391 int lttng_syscalls_create_matching_event_notifiers(
1392 struct lttng_event_notifier_enabler *event_notifier_enabler)
1393 {
1394 int ret;
1395 struct lttng_enabler *base_enabler =
1396 lttng_event_notifier_enabler_as_enabler(event_notifier_enabler);
1397 enum lttng_kernel_abi_syscall_entryexit entryexit =
1398 base_enabler->event_param.u.syscall.entryexit;
1399
1400 if (entryexit == LTTNG_KERNEL_ABI_SYSCALL_ENTRY || entryexit == LTTNG_KERNEL_ABI_SYSCALL_ENTRYEXIT) {
1401 ret = create_matching_event_notifiers(event_notifier_enabler,
1402 sc_table, ARRAY_SIZE(sc_table), SC_TYPE_ENTRY);
1403 if (ret)
1404 goto end;
1405
1406 ret = create_matching_event_notifiers(event_notifier_enabler,
1407 compat_sc_table, ARRAY_SIZE(compat_sc_table),
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
1423 if (entryexit == LTTNG_KERNEL_ABI_SYSCALL_EXIT || entryexit == LTTNG_KERNEL_ABI_SYSCALL_ENTRYEXIT) {
1424 ret = create_matching_event_notifiers(event_notifier_enabler,
1425 sc_exit_table, ARRAY_SIZE(sc_exit_table),
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,
1436 compat_sc_exit_table, ARRAY_SIZE(compat_sc_exit_table),
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
1447 end:
1448 return ret;
1449 }
1450
1451 /*
1452 * Unregister the syscall event_notifier probes from the callsites.
1453 */
1454 int lttng_syscalls_unregister_event_notifier_group(
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
1488 int lttng_syscalls_unregister_channel(struct lttng_channel *chan)
1489 {
1490 int ret;
1491
1492 if (!chan->sc_table)
1493 return 0;
1494 if (chan->sys_enter_registered) {
1495 ret = lttng_wrapper_tracepoint_probe_unregister("sys_enter",
1496 (void *) syscall_entry_event_probe, chan);
1497 if (ret)
1498 return ret;
1499 chan->sys_enter_registered = 0;
1500 }
1501 if (chan->sys_exit_registered) {
1502 ret = lttng_wrapper_tracepoint_probe_unregister("sys_exit",
1503 (void *) syscall_exit_event_probe, chan);
1504 if (ret)
1505 return ret;
1506 chan->sys_exit_registered = 0;
1507 }
1508 return 0;
1509 }
1510
1511 int lttng_syscalls_destroy_event(struct lttng_channel *chan)
1512 {
1513 kfree(chan->sc_table);
1514 kfree(chan->sc_exit_table);
1515 #ifdef CONFIG_COMPAT
1516 kfree(chan->compat_sc_table);
1517 kfree(chan->compat_sc_exit_table);
1518 #endif
1519 kfree(chan->sc_filter);
1520 return 0;
1521 }
1522
1523 static
1524 int 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;
1531 const char *it_name;
1532
1533 entry = &sc_table[i];
1534 if (!entry->desc)
1535 continue;
1536 it_name = entry->desc->event_name;
1537 it_name += strlen(SYSCALL_ENTRY_STR);
1538 if (!strcmp(syscall_name, it_name)) {
1539 syscall_nr = i;
1540 break;
1541 }
1542 }
1543 return syscall_nr;
1544 }
1545
1546 static
1547 int 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;
1554 const char *it_name;
1555
1556 entry = &compat_sc_table[i];
1557 if (!entry->desc)
1558 continue;
1559 it_name = entry->desc->event_name;
1560 it_name += strlen(COMPAT_SYSCALL_ENTRY_STR);
1561 if (!strcmp(syscall_name, it_name)) {
1562 syscall_nr = i;
1563 break;
1564 }
1565 }
1566 return syscall_nr;
1567 }
1568
1569 static
1570 uint32_t get_sc_tables_len(void)
1571 {
1572 return ARRAY_SIZE(sc_table) + ARRAY_SIZE(compat_sc_table);
1573 }
1574
1575 static
1576 const char *get_syscall_name(const char *desc_name,
1577 enum lttng_syscall_abi abi,
1578 enum lttng_syscall_entryexit entryexit)
1579 {
1580 size_t prefix_len = 0;
1581
1582
1583 switch (entryexit) {
1584 case LTTNG_SYSCALL_ENTRY:
1585 switch (abi) {
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;
1592 }
1593 break;
1594 case LTTNG_SYSCALL_EXIT:
1595 switch (abi) {
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;
1602 }
1603 break;
1604 }
1605 WARN_ON_ONCE(prefix_len == 0);
1606 return desc_name + prefix_len;
1607 }
1608
1609 static
1610 int 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)
1614 {
1615 const char *syscall_name;
1616 unsigned long *bitmap;
1617 int syscall_nr;
1618
1619 syscall_name = get_syscall_name(desc_name, abi, entryexit);
1620
1621 switch (abi) {
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;
1630 }
1631 if (syscall_nr < 0)
1632 return -ENOENT;
1633
1634 switch (entryexit) {
1635 case LTTNG_SYSCALL_ENTRY:
1636 switch (abi) {
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;
1643 default:
1644 return -EINVAL;
1645 }
1646 break;
1647 case LTTNG_SYSCALL_EXIT:
1648 switch (abi) {
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;
1655 default:
1656 return -EINVAL;
1657 }
1658 break;
1659 default:
1660 return -EINVAL;
1661 }
1662 if (test_bit(syscall_nr, bitmap))
1663 return -EEXIST;
1664 bitmap_set(bitmap, syscall_nr, 1);
1665 return 0;
1666 }
1667
1668 int lttng_syscall_filter_enable_event_notifier(
1669 struct lttng_kernel_event_notifier *event_notifier)
1670 {
1671 struct lttng_event_notifier_group *group = event_notifier->priv->group;
1672 unsigned int syscall_id = event_notifier->priv->parent.u.syscall.syscall_id;
1673 struct hlist_head *dispatch_list;
1674 int ret = 0;
1675
1676 WARN_ON_ONCE(event_notifier->priv->parent.instrumentation != LTTNG_KERNEL_ABI_SYSCALL);
1677
1678 ret = lttng_syscall_filter_enable(group->sc_filter,
1679 event_notifier->priv->parent.desc->event_name,
1680 event_notifier->priv->parent.u.syscall.abi,
1681 event_notifier->priv->parent.u.syscall.entryexit);
1682 if (ret) {
1683 goto end;
1684 }
1685
1686 switch (event_notifier->priv->parent.u.syscall.entryexit) {
1687 case LTTNG_SYSCALL_ENTRY:
1688 switch (event_notifier->priv->parent.u.syscall.abi) {
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;
1695 default:
1696 ret = -EINVAL;
1697 goto end;
1698 }
1699 break;
1700 case LTTNG_SYSCALL_EXIT:
1701 switch (event_notifier->priv->parent.u.syscall.abi) {
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;
1708 default:
1709 ret = -EINVAL;
1710 goto end;
1711 }
1712 break;
1713 default:
1714 ret = -EINVAL;
1715 goto end;
1716 }
1717
1718 hlist_add_head_rcu(&event_notifier->priv->parent.u.syscall.node, dispatch_list);
1719
1720 end:
1721 return ret ;
1722 }
1723
1724 int lttng_syscall_filter_enable_event(
1725 struct lttng_channel *channel,
1726 struct lttng_kernel_event_recorder *event_recorder)
1727 {
1728 WARN_ON_ONCE(event_recorder->priv->parent.instrumentation != LTTNG_KERNEL_ABI_SYSCALL);
1729
1730 return lttng_syscall_filter_enable(channel->sc_filter,
1731 event_recorder->priv->parent.desc->event_name,
1732 event_recorder->priv->parent.u.syscall.abi,
1733 event_recorder->priv->parent.u.syscall.entryexit);
1734 }
1735
1736 static
1737 int 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 {
1742 const char *syscall_name;
1743 unsigned long *bitmap;
1744 int syscall_nr;
1745
1746 syscall_name = get_syscall_name(desc_name, abi, entryexit);
1747
1748 switch (abi) {
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;
1757 }
1758 if (syscall_nr < 0)
1759 return -ENOENT;
1760
1761 switch (entryexit) {
1762 case LTTNG_SYSCALL_ENTRY:
1763 switch (abi) {
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;
1770 default:
1771 return -EINVAL;
1772 }
1773 break;
1774 case LTTNG_SYSCALL_EXIT:
1775 switch (abi) {
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;
1782 default:
1783 return -EINVAL;
1784 }
1785 break;
1786 default:
1787 return -EINVAL;
1788 }
1789 if (!test_bit(syscall_nr, bitmap))
1790 return -EEXIST;
1791 bitmap_clear(bitmap, syscall_nr, 1);
1792
1793 return 0;
1794 }
1795
1796 int lttng_syscall_filter_disable_event_notifier(
1797 struct lttng_kernel_event_notifier *event_notifier)
1798 {
1799 struct lttng_event_notifier_group *group = event_notifier->priv->group;
1800 int ret;
1801
1802 WARN_ON_ONCE(event_notifier->priv->parent.instrumentation != LTTNG_KERNEL_ABI_SYSCALL);
1803
1804 ret = lttng_syscall_filter_disable(group->sc_filter,
1805 event_notifier->priv->parent.desc->event_name,
1806 event_notifier->priv->parent.u.syscall.abi,
1807 event_notifier->priv->parent.u.syscall.entryexit);
1808 WARN_ON_ONCE(ret != 0);
1809
1810 hlist_del_rcu(&event_notifier->priv->parent.u.syscall.node);
1811 return 0;
1812 }
1813
1814 int lttng_syscall_filter_disable_event(
1815 struct lttng_channel *channel,
1816 struct lttng_kernel_event_recorder *event_recorder)
1817 {
1818 return lttng_syscall_filter_disable(channel->sc_filter,
1819 event_recorder->priv->parent.desc->event_name,
1820 event_recorder->priv->parent.u.syscall.abi,
1821 event_recorder->priv->parent.u.syscall.entryexit);
1822 }
1823
1824 static
1825 const 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
1846 static
1847 void *syscall_list_start(struct seq_file *m, loff_t *pos)
1848 {
1849 return (void *) syscall_list_get_entry(pos);
1850 }
1851
1852 static
1853 void *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
1859 static
1860 void syscall_list_stop(struct seq_file *m, void *p)
1861 {
1862 }
1863
1864 static
1865 int 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
1887 static
1888 int syscall_list_show(struct seq_file *m, void *p)
1889 {
1890 const struct trace_syscall_entry *table, *entry = p;
1891 unsigned int bitness;
1892 unsigned long index;
1893 int ret;
1894 const char *name;
1895
1896 ret = get_sc_table(entry, &table, &bitness);
1897 if (ret)
1898 return ret;
1899 if (!entry->desc)
1900 return 0;
1901 if (table == sc_table) {
1902 index = entry - table;
1903 name = &entry->desc->event_name[strlen(SYSCALL_ENTRY_STR)];
1904 } else {
1905 index = (entry - table) + ARRAY_SIZE(sc_table);
1906 name = &entry->desc->event_name[strlen(COMPAT_SYSCALL_ENTRY_STR)];
1907 }
1908 seq_printf(m, "syscall { index = %lu; name = %s; bitness = %u; };\n",
1909 index, name, bitness);
1910 return 0;
1911 }
1912
1913 static
1914 const 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
1921 static
1922 int lttng_syscall_list_open(struct inode *inode, struct file *file)
1923 {
1924 return seq_open(file, &lttng_syscall_list_seq_ops);
1925 }
1926
1927 const 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 };
1934
1935 /*
1936 * A syscall is enabled if it is traced for either entry or exit.
1937 */
1938 long lttng_channel_syscall_mask(struct lttng_channel *channel,
1939 struct lttng_kernel_abi_syscall_mask __user *usyscall_mask)
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++) {
1961 char state;
1962
1963 if (channel->sc_table) {
1964 if (!(READ_ONCE(channel->syscall_all_entry)
1965 || READ_ONCE(channel->syscall_all_exit)) && filter)
1966 state = test_bit(bit, filter->sc_entry)
1967 || test_bit(bit, filter->sc_exit);
1968 else
1969 state = 1;
1970 } else {
1971 state = 0;
1972 }
1973 bt_bitfield_write_be(tmp_mask, char, bit, 1, state);
1974 }
1975 for (; bit < sc_tables_len; bit++) {
1976 char state;
1977
1978 if (channel->compat_sc_table) {
1979 if (!(READ_ONCE(channel->syscall_all_entry)
1980 || READ_ONCE(channel->syscall_all_exit)) && filter)
1981 state = test_bit(bit - ARRAY_SIZE(sc_table),
1982 filter->sc_compat_entry)
1983 || test_bit(bit - ARRAY_SIZE(sc_table),
1984 filter->sc_compat_exit);
1985 else
1986 state = 1;
1987 } else {
1988 state = 0;
1989 }
1990 bt_bitfield_write_be(tmp_mask, char, bit, 1, state);
1991 }
1992 if (copy_to_user(usyscall_mask->mask, tmp_mask, bitmask_len))
1993 ret = -EFAULT;
1994 kfree(tmp_mask);
1995 return ret;
1996 }
1997
1998 int lttng_abi_syscall_list(void)
1999 {
2000 struct file *syscall_list_file;
2001 int file_fd, ret;
2002
2003 file_fd = lttng_get_unused_fd();
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);
2020 return file_fd;
2021
2022 open_error:
2023 fput(syscall_list_file);
2024 file_error:
2025 put_unused_fd(file_fd);
2026 fd_error:
2027 return ret;
2028 }
This page took 0.070168 seconds and 4 git commands to generate.