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