1 /* SPDX-License-Identifier: (GPL-2.0-only or LGPL-2.1-only)
5 * LTTng syscall probes.
7 * Copyright (C) 2010-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
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>
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>
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>
35 # ifndef is_compat_task
36 # define is_compat_task() (0)
40 /* in_compat_syscall appears in kernel 4.6. */
41 #ifndef in_compat_syscall
42 #define in_compat_syscall() is_compat_task()
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_
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)
63 void syscall_entry_event_probe(void *__data
, struct pt_regs
*regs
, long id
);
65 void syscall_exit_event_probe(void *__data
, struct pt_regs
*regs
, long ret
);
68 void syscall_entry_event_notifier_probe(void *__data
, struct pt_regs
*regs
,
71 void syscall_exit_event_notifier_probe(void *__data
, struct pt_regs
*regs
,
75 * Forward declarations for old kernels.
79 struct oldold_utsname
;
81 struct sel_arg_struct
;
82 struct mmap_arg_struct
;
87 * Forward declaration for kernels >= 5.6
94 #if (LTTNG_LINUX_VERSION_CODE >= LTTNG_KERNEL_VERSION(5,6,0))
95 typedef __kernel_old_time_t
time_t;
98 #ifdef IA32_NR_syscalls
99 #define NR_compat_syscalls IA32_NR_syscalls
101 #define NR_compat_syscalls NR_syscalls
105 * Create LTTng tracepoint probes.
107 #define LTTNG_PACKAGE_BUILD
108 #define CREATE_TRACE_POINTS
109 #define TP_MODULE_NOINIT
110 #define TRACE_INCLUDE_PATH instrumentation/syscalls/headers
112 #define PARAMS(args...) args
114 /* Handle unknown syscalls */
116 #define TRACE_SYSTEM syscalls_unknown
117 #include <instrumentation/syscalls/headers/syscalls_unknown.h>
125 #define sc_in(...) __VA_ARGS__
129 #define sc_inout(...) __VA_ARGS__
131 /* Hijack probe callback for system call enter */
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), \
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))
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
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
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
165 #undef _TRACE_SYSCALLS_INTEGERS_H
166 #undef _TRACE_SYSCALLS_POINTERS_H
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), \
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
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
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
200 #undef _TRACE_SYSCALLS_INTEGERS_H
201 #undef _TRACE_SYSCALLS_POINTERS_H
202 #undef LTTNG_SC_COMPAT
209 #define sc_exit(...) __VA_ARGS__
213 #define sc_out(...) __VA_ARGS__
215 #define sc_inout(...) __VA_ARGS__
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), \
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
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
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
248 #undef _TRACE_SYSCALLS_INTEGERS_H
249 #undef _TRACE_SYSCALLS_POINTERS_H
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), \
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
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
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
284 #undef _TRACE_SYSCALLS_INTEGERS_H
285 #undef _TRACE_SYSCALLS_POINTERS_H
286 #undef LTTNG_SC_COMPAT
290 #undef TP_MODULE_NOINIT
291 #undef LTTNG_PACKAGE_BUILD
292 #undef CREATE_TRACE_POINTS
294 struct trace_syscall_entry
{
296 void *event_notifier_func
;
297 const struct lttng_kernel_event_desc
*desc
;
298 const struct lttng_kernel_event_field
**fields
;
302 #define CREATE_SYSCALL_TABLE
309 #undef TRACE_SYSCALL_TABLE
310 #define TRACE_SYSCALL_TABLE(_template, _name, _nr, _nrargs) \
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, \
319 /* Event syscall enter tracing table */
320 static const struct trace_syscall_entry sc_table
[] = {
321 #include <instrumentation/syscalls/headers/syscalls_integers.h>
322 #include <instrumentation/syscalls/headers/syscalls_pointers.h>
325 #undef TRACE_SYSCALL_TABLE
326 #define TRACE_SYSCALL_TABLE(_template, _name, _nr, _nrargs) \
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, \
335 /* Event compat syscall enter table */
336 const 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>
346 #define sc_exit(...) __VA_ARGS__
348 #undef TRACE_SYSCALL_TABLE
349 #define TRACE_SYSCALL_TABLE(_template, _name, _nr, _nrargs) \
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, \
358 /* Event syscall exit table */
359 static const struct trace_syscall_entry sc_exit_table
[] = {
360 #include <instrumentation/syscalls/headers/syscalls_integers.h>
361 #include <instrumentation/syscalls/headers/syscalls_pointers.h>
364 #undef TRACE_SYSCALL_TABLE
365 #define TRACE_SYSCALL_TABLE(_template, _name, _nr, _nrargs) \
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, \
374 /* Event compat syscall exit table */
375 const 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>
382 #undef CREATE_SYSCALL_TABLE
384 struct 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
);
391 static void syscall_entry_event_unknown(struct hlist_head
*unknown_action_list_head
,
392 struct pt_regs
*regs
, long id
)
394 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
395 struct lttng_kernel_event_common_private
*event_priv
;
397 lttng_syscall_get_arguments(current
, regs
, args
);
398 lttng_hlist_for_each_entry_rcu(event_priv
, unknown_action_list_head
, u
.syscall
.node
) {
399 struct lttng_kernel_event_recorder_private
*event_recorder_priv
=
400 container_of(event_priv
, struct lttng_kernel_event_recorder_private
, parent
);
401 struct lttng_kernel_event_recorder
*event_recorder
= event_recorder_priv
->pub
;
403 if (unlikely(in_compat_syscall()))
404 __event_probe__compat_syscall_entry_unknown(event_recorder
, id
, args
);
406 __event_probe__syscall_entry_unknown(event_recorder
, id
, args
);
410 static void syscall_entry_event_notifier_unknown(
411 struct hlist_head
*unknown_dispatch_list_head
,
412 struct pt_regs
*regs
, long id
)
414 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
415 struct lttng_kernel_event_common_private
*event_priv
;
417 lttng_syscall_get_arguments(current
, regs
, args
);
418 lttng_hlist_for_each_entry_rcu(event_priv
, unknown_dispatch_list_head
, u
.syscall
.node
) {
419 struct lttng_kernel_event_notifier_private
*event_notifier_priv
=
420 container_of(event_priv
, struct lttng_kernel_event_notifier_private
, parent
);
421 struct lttng_kernel_event_notifier
*event_notifier
= event_notifier_priv
->pub
;
423 if (unlikely(in_compat_syscall()))
424 __event_notifier_probe__compat_syscall_entry_unknown(event_notifier
, id
, args
);
426 __event_notifier_probe__syscall_entry_unknown(event_notifier
, id
, args
);
430 static void syscall_exit_event_notifier_unknown(
431 struct hlist_head
*unknown_dispatch_list_head
,
432 struct pt_regs
*regs
, long id
, long ret
)
434 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
435 struct lttng_kernel_event_common_private
*event_priv
;
437 lttng_syscall_get_arguments(current
, regs
, args
);
438 lttng_hlist_for_each_entry_rcu(event_priv
, unknown_dispatch_list_head
, u
.syscall
.node
) {
439 struct lttng_kernel_event_notifier_private
*event_notifier_priv
=
440 container_of(event_priv
, struct lttng_kernel_event_notifier_private
, parent
);
441 struct lttng_kernel_event_notifier
*event_notifier
= event_notifier_priv
->pub
;
443 if (unlikely(in_compat_syscall()))
444 __event_notifier_probe__compat_syscall_exit_unknown(event_notifier
, id
, ret
, args
);
446 __event_notifier_probe__syscall_exit_unknown(event_notifier
, id
, ret
, args
);
450 static __always_inline
451 void syscall_entry_call_func(struct hlist_head
*action_list
,
452 void *func
, unsigned int nrargs
,
453 struct pt_regs
*regs
)
455 struct lttng_kernel_event_common_private
*event_priv
;
460 void (*fptr
)(void *__data
) = func
;
462 lttng_hlist_for_each_entry_rcu(event_priv
, action_list
, u
.syscall
.node
) {
463 struct lttng_kernel_event_recorder_private
*event_recorder_priv
=
464 container_of(event_priv
, struct lttng_kernel_event_recorder_private
, parent
);
465 struct lttng_kernel_event_recorder
*event_recorder
= event_recorder_priv
->pub
;
467 fptr(event_recorder
);
473 void (*fptr
)(void *__data
, unsigned long arg0
) = func
;
474 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
476 lttng_syscall_get_arguments(current
, regs
, args
);
477 lttng_hlist_for_each_entry_rcu(event_priv
, action_list
, u
.syscall
.node
) {
478 struct lttng_kernel_event_recorder_private
*event_recorder_priv
=
479 container_of(event_priv
, struct lttng_kernel_event_recorder_private
, parent
);
480 struct lttng_kernel_event_recorder
*event_recorder
= event_recorder_priv
->pub
;
482 fptr(event_recorder
, args
[0]);
488 void (*fptr
)(void *__data
,
490 unsigned long arg1
) = func
;
491 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
493 lttng_syscall_get_arguments(current
, regs
, args
);
494 lttng_hlist_for_each_entry_rcu(event_priv
, action_list
, u
.syscall
.node
) {
495 struct lttng_kernel_event_recorder_private
*event_recorder_priv
=
496 container_of(event_priv
, struct lttng_kernel_event_recorder_private
, parent
);
497 struct lttng_kernel_event_recorder
*event_recorder
= event_recorder_priv
->pub
;
499 fptr(event_recorder
, args
[0], args
[1]);
505 void (*fptr
)(void *__data
,
508 unsigned long arg2
) = func
;
509 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
511 lttng_syscall_get_arguments(current
, regs
, args
);
512 lttng_hlist_for_each_entry_rcu(event_priv
, action_list
, u
.syscall
.node
) {
513 struct lttng_kernel_event_recorder_private
*event_recorder_priv
=
514 container_of(event_priv
, struct lttng_kernel_event_recorder_private
, parent
);
515 struct lttng_kernel_event_recorder
*event_recorder
= event_recorder_priv
->pub
;
517 fptr(event_recorder
, args
[0], args
[1], args
[2]);
523 void (*fptr
)(void *__data
,
527 unsigned long arg3
) = func
;
528 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
530 lttng_syscall_get_arguments(current
, regs
, args
);
531 lttng_hlist_for_each_entry_rcu(event_priv
, action_list
, u
.syscall
.node
) {
532 struct lttng_kernel_event_recorder_private
*event_recorder_priv
=
533 container_of(event_priv
, struct lttng_kernel_event_recorder_private
, parent
);
534 struct lttng_kernel_event_recorder
*event_recorder
= event_recorder_priv
->pub
;
536 fptr(event_recorder
, args
[0], args
[1], args
[2], args
[3]);
542 void (*fptr
)(void *__data
,
547 unsigned long arg4
) = func
;
548 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
550 lttng_syscall_get_arguments(current
, regs
, args
);
551 lttng_hlist_for_each_entry_rcu(event_priv
, action_list
, u
.syscall
.node
) {
552 struct lttng_kernel_event_recorder_private
*event_recorder_priv
=
553 container_of(event_priv
, struct lttng_kernel_event_recorder_private
, parent
);
554 struct lttng_kernel_event_recorder
*event_recorder
= event_recorder_priv
->pub
;
556 fptr(event_recorder
, args
[0], args
[1], args
[2], args
[3], args
[4]);
562 void (*fptr
)(void *__data
,
568 unsigned long arg5
) = func
;
569 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
571 lttng_syscall_get_arguments(current
, regs
, args
);
572 lttng_hlist_for_each_entry_rcu(event_priv
, action_list
, u
.syscall
.node
) {
573 struct lttng_kernel_event_recorder_private
*event_recorder_priv
=
574 container_of(event_priv
, struct lttng_kernel_event_recorder_private
, parent
);
575 struct lttng_kernel_event_recorder
*event_recorder
= event_recorder_priv
->pub
;
577 fptr(event_recorder
, args
[0], args
[1], args
[2],
578 args
[3], args
[4], args
[5]);
587 static __always_inline
588 void syscall_entry_event_notifier_call_func(struct hlist_head
*dispatch_list
,
589 void *func
, unsigned int nrargs
, struct pt_regs
*regs
)
591 struct lttng_kernel_event_common_private
*event_priv
;
596 void (*fptr
)(void *__data
) = func
;
598 lttng_hlist_for_each_entry_rcu(event_priv
, dispatch_list
, u
.syscall
.node
) {
599 struct lttng_kernel_event_notifier_private
*event_notifier_priv
=
600 container_of(event_priv
, struct lttng_kernel_event_notifier_private
, parent
);
601 struct lttng_kernel_event_notifier
*event_notifier
= event_notifier_priv
->pub
;
603 fptr(event_notifier
);
609 void (*fptr
)(void *__data
, unsigned long arg0
) = func
;
610 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
612 lttng_syscall_get_arguments(current
, regs
, args
);
613 lttng_hlist_for_each_entry_rcu(event_priv
, dispatch_list
, u
.syscall
.node
) {
614 struct lttng_kernel_event_notifier_private
*event_notifier_priv
=
615 container_of(event_priv
, struct lttng_kernel_event_notifier_private
, parent
);
616 struct lttng_kernel_event_notifier
*event_notifier
= event_notifier_priv
->pub
;
618 fptr(event_notifier
, args
[0]);
624 void (*fptr
)(void *__data
,
626 unsigned long arg1
) = func
;
627 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
629 lttng_syscall_get_arguments(current
, regs
, args
);
630 lttng_hlist_for_each_entry_rcu(event_priv
, dispatch_list
, u
.syscall
.node
) {
631 struct lttng_kernel_event_notifier_private
*event_notifier_priv
=
632 container_of(event_priv
, struct lttng_kernel_event_notifier_private
, parent
);
633 struct lttng_kernel_event_notifier
*event_notifier
= event_notifier_priv
->pub
;
635 fptr(event_notifier
, args
[0], args
[1]);
641 void (*fptr
)(void *__data
,
644 unsigned long arg2
) = func
;
645 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
647 lttng_syscall_get_arguments(current
, regs
, args
);
648 lttng_hlist_for_each_entry_rcu(event_priv
, dispatch_list
, u
.syscall
.node
) {
649 struct lttng_kernel_event_notifier_private
*event_notifier_priv
=
650 container_of(event_priv
, struct lttng_kernel_event_notifier_private
, parent
);
651 struct lttng_kernel_event_notifier
*event_notifier
= event_notifier_priv
->pub
;
653 fptr(event_notifier
, args
[0], args
[1], args
[2]);
659 void (*fptr
)(void *__data
,
663 unsigned long arg3
) = func
;
664 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
666 lttng_syscall_get_arguments(current
, regs
, args
);
667 lttng_hlist_for_each_entry_rcu(event_priv
, dispatch_list
, u
.syscall
.node
) {
668 struct lttng_kernel_event_notifier_private
*event_notifier_priv
=
669 container_of(event_priv
, struct lttng_kernel_event_notifier_private
, parent
);
670 struct lttng_kernel_event_notifier
*event_notifier
= event_notifier_priv
->pub
;
672 fptr(event_notifier
, args
[0], args
[1], args
[2], args
[3]);
678 void (*fptr
)(void *__data
,
683 unsigned long arg4
) = func
;
684 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
686 lttng_syscall_get_arguments(current
, regs
, args
);
687 lttng_hlist_for_each_entry_rcu(event_priv
, dispatch_list
, u
.syscall
.node
) {
688 struct lttng_kernel_event_notifier_private
*event_notifier_priv
=
689 container_of(event_priv
, struct lttng_kernel_event_notifier_private
, parent
);
690 struct lttng_kernel_event_notifier
*event_notifier
= event_notifier_priv
->pub
;
692 fptr(event_notifier
, args
[0], args
[1], args
[2], args
[3], args
[4]);
698 void (*fptr
)(void *__data
,
704 unsigned long arg5
) = func
;
705 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
707 lttng_syscall_get_arguments(current
, regs
, args
);
708 lttng_hlist_for_each_entry_rcu(event_priv
, dispatch_list
, u
.syscall
.node
) {
709 struct lttng_kernel_event_notifier_private
*event_notifier_priv
=
710 container_of(event_priv
, struct lttng_kernel_event_notifier_private
, parent
);
711 struct lttng_kernel_event_notifier
*event_notifier
= event_notifier_priv
->pub
;
713 fptr(event_notifier
, args
[0], args
[1], args
[2], args
[3], args
[4], args
[5]);
722 void syscall_entry_event_probe(void *__data
, struct pt_regs
*regs
, long id
)
724 struct lttng_channel
*chan
= __data
;
725 struct hlist_head
*action_list
, *unknown_action_list
;
726 const struct trace_syscall_entry
*table
, *entry
;
729 if (unlikely(in_compat_syscall())) {
730 struct lttng_syscall_filter
*filter
= chan
->sc_filter
;
732 if (id
< 0 || id
>= NR_compat_syscalls
733 || (!READ_ONCE(chan
->syscall_all_entry
) && !test_bit(id
, filter
->sc_compat_entry
))) {
734 /* System call filtered out. */
737 table
= compat_sc_table
;
738 table_len
= ARRAY_SIZE(compat_sc_table
);
739 unknown_action_list
= &chan
->sc_compat_unknown
;
741 struct lttng_syscall_filter
*filter
= chan
->sc_filter
;
743 if (id
< 0 || id
>= NR_syscalls
744 || (!READ_ONCE(chan
->syscall_all_entry
) && !test_bit(id
, filter
->sc_entry
))) {
745 /* System call filtered out. */
749 table_len
= ARRAY_SIZE(sc_table
);
750 unknown_action_list
= &chan
->sc_unknown
;
752 if (unlikely(id
< 0 || id
>= table_len
)) {
753 syscall_entry_event_unknown(unknown_action_list
, regs
, id
);
758 if (!entry
->event_func
) {
759 syscall_entry_event_unknown(unknown_action_list
, regs
, id
);
763 if (unlikely(in_compat_syscall())) {
764 action_list
= &chan
->compat_sc_table
[id
];
766 action_list
= &chan
->sc_table
[id
];
768 if (unlikely(hlist_empty(action_list
)))
771 syscall_entry_call_func(action_list
, entry
->event_func
, entry
->nrargs
, regs
);
774 void syscall_entry_event_notifier_probe(void *__data
, struct pt_regs
*regs
,
777 struct lttng_event_notifier_group
*group
= __data
;
778 const struct trace_syscall_entry
*table
, *entry
;
779 struct hlist_head
*dispatch_list
, *unknown_dispatch_list
;
782 if (unlikely(in_compat_syscall())) {
783 struct lttng_syscall_filter
*filter
= group
->sc_filter
;
785 if (id
< 0 || id
>= NR_compat_syscalls
786 || (!READ_ONCE(group
->syscall_all_entry
) &&
787 !test_bit(id
, filter
->sc_compat_entry
))) {
788 /* System call filtered out. */
791 table
= compat_sc_table
;
792 table_len
= ARRAY_SIZE(compat_sc_table
);
793 unknown_dispatch_list
= &group
->event_notifier_compat_unknown_syscall_dispatch
;
795 struct lttng_syscall_filter
*filter
= group
->sc_filter
;
797 if (id
< 0 || id
>= NR_syscalls
798 || (!READ_ONCE(group
->syscall_all_entry
) &&
799 !test_bit(id
, filter
->sc_entry
))) {
800 /* System call filtered out. */
804 table_len
= ARRAY_SIZE(sc_table
);
805 unknown_dispatch_list
= &group
->event_notifier_unknown_syscall_dispatch
;
807 /* Check if the syscall id is out of bound. */
808 if (unlikely(id
< 0 || id
>= table_len
)) {
809 syscall_entry_event_notifier_unknown(unknown_dispatch_list
,
815 if (!entry
->event_notifier_func
) {
816 syscall_entry_event_notifier_unknown(unknown_dispatch_list
,
821 if (unlikely(in_compat_syscall())) {
822 dispatch_list
= &group
->event_notifier_compat_syscall_dispatch
[id
];
824 dispatch_list
= &group
->event_notifier_syscall_dispatch
[id
];
826 if (unlikely(hlist_empty(dispatch_list
)))
829 syscall_entry_event_notifier_call_func(dispatch_list
,
830 entry
->event_notifier_func
, entry
->nrargs
, regs
);
833 static void syscall_exit_event_unknown(struct hlist_head
*unknown_action_list_head
,
834 struct pt_regs
*regs
, long id
, long ret
)
836 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
837 struct lttng_kernel_event_common_private
*event_priv
;
839 lttng_syscall_get_arguments(current
, regs
, args
);
840 lttng_hlist_for_each_entry_rcu(event_priv
, unknown_action_list_head
, u
.syscall
.node
) {
841 struct lttng_kernel_event_recorder_private
*event_recorder_priv
=
842 container_of(event_priv
, struct lttng_kernel_event_recorder_private
, parent
);
843 struct lttng_kernel_event_recorder
*event_recorder
= event_recorder_priv
->pub
;
845 if (unlikely(in_compat_syscall()))
846 __event_probe__compat_syscall_exit_unknown(event_recorder
, id
, ret
,
849 __event_probe__syscall_exit_unknown(event_recorder
, id
, ret
, args
);
853 static __always_inline
854 void syscall_exit_call_func(struct hlist_head
*action_list
,
855 void *func
, unsigned int nrargs
,
856 struct pt_regs
*regs
, long ret
)
858 struct lttng_kernel_event_common_private
*event_priv
;
863 void (*fptr
)(void *__data
, long ret
) = func
;
865 lttng_hlist_for_each_entry_rcu(event_priv
, action_list
, u
.syscall
.node
) {
866 struct lttng_kernel_event_recorder_private
*event_recorder_priv
=
867 container_of(event_priv
, struct lttng_kernel_event_recorder_private
, parent
);
868 struct lttng_kernel_event_recorder
*event_recorder
= event_recorder_priv
->pub
;
870 fptr(event_recorder
, ret
);
876 void (*fptr
)(void *__data
,
878 unsigned long arg0
) = func
;
879 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
881 lttng_syscall_get_arguments(current
, regs
, args
);
882 lttng_hlist_for_each_entry_rcu(event_priv
, action_list
, u
.syscall
.node
) {
883 struct lttng_kernel_event_recorder_private
*event_recorder_priv
=
884 container_of(event_priv
, struct lttng_kernel_event_recorder_private
, parent
);
885 struct lttng_kernel_event_recorder
*event_recorder
= event_recorder_priv
->pub
;
887 fptr(event_recorder
, ret
, args
[0]);
893 void (*fptr
)(void *__data
,
896 unsigned long arg1
) = func
;
897 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
899 lttng_syscall_get_arguments(current
, regs
, args
);
900 lttng_hlist_for_each_entry_rcu(event_priv
, action_list
, u
.syscall
.node
) {
901 struct lttng_kernel_event_recorder_private
*event_recorder_priv
=
902 container_of(event_priv
, struct lttng_kernel_event_recorder_private
, parent
);
903 struct lttng_kernel_event_recorder
*event_recorder
= event_recorder_priv
->pub
;
905 fptr(event_recorder
, ret
, args
[0], args
[1]);
911 void (*fptr
)(void *__data
,
915 unsigned long arg2
) = func
;
916 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
918 lttng_syscall_get_arguments(current
, regs
, args
);
919 lttng_hlist_for_each_entry_rcu(event_priv
, action_list
, u
.syscall
.node
) {
920 struct lttng_kernel_event_recorder_private
*event_recorder_priv
=
921 container_of(event_priv
, struct lttng_kernel_event_recorder_private
, parent
);
922 struct lttng_kernel_event_recorder
*event_recorder
= event_recorder_priv
->pub
;
924 fptr(event_recorder
, ret
, args
[0], args
[1], args
[2]);
930 void (*fptr
)(void *__data
,
935 unsigned long arg3
) = func
;
936 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
938 lttng_syscall_get_arguments(current
, regs
, args
);
939 lttng_hlist_for_each_entry_rcu(event_priv
, action_list
, u
.syscall
.node
) {
940 struct lttng_kernel_event_recorder_private
*event_recorder_priv
=
941 container_of(event_priv
, struct lttng_kernel_event_recorder_private
, parent
);
942 struct lttng_kernel_event_recorder
*event_recorder
= event_recorder_priv
->pub
;
944 fptr(event_recorder
, ret
, args
[0], args
[1], args
[2], args
[3]);
950 void (*fptr
)(void *__data
,
956 unsigned long arg4
) = func
;
957 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
959 lttng_syscall_get_arguments(current
, regs
, args
);
960 lttng_hlist_for_each_entry_rcu(event_priv
, action_list
, u
.syscall
.node
) {
961 struct lttng_kernel_event_recorder_private
*event_recorder_priv
=
962 container_of(event_priv
, struct lttng_kernel_event_recorder_private
, parent
);
963 struct lttng_kernel_event_recorder
*event_recorder
= event_recorder_priv
->pub
;
965 fptr(event_recorder
, ret
, args
[0], args
[1], args
[2], args
[3], args
[4]);
971 void (*fptr
)(void *__data
,
978 unsigned long arg5
) = func
;
979 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
981 lttng_syscall_get_arguments(current
, regs
, args
);
982 lttng_hlist_for_each_entry_rcu(event_priv
, action_list
, u
.syscall
.node
) {
983 struct lttng_kernel_event_recorder_private
*event_recorder_priv
=
984 container_of(event_priv
, struct lttng_kernel_event_recorder_private
, parent
);
985 struct lttng_kernel_event_recorder
*event_recorder
= event_recorder_priv
->pub
;
987 fptr(event_recorder
, ret
, args
[0], args
[1], args
[2],
988 args
[3], args
[4], args
[5]);
997 void syscall_exit_event_probe(void *__data
, struct pt_regs
*regs
, long ret
)
999 struct lttng_channel
*chan
= __data
;
1000 struct hlist_head
*action_list
, *unknown_action_list
;
1001 const struct trace_syscall_entry
*table
, *entry
;
1005 id
= syscall_get_nr(current
, regs
);
1007 if (unlikely(in_compat_syscall())) {
1008 struct lttng_syscall_filter
*filter
= chan
->sc_filter
;
1010 if (id
< 0 || id
>= NR_compat_syscalls
1011 || (!READ_ONCE(chan
->syscall_all_exit
) && !test_bit(id
, filter
->sc_compat_exit
))) {
1012 /* System call filtered out. */
1015 table
= compat_sc_exit_table
;
1016 table_len
= ARRAY_SIZE(compat_sc_exit_table
);
1017 unknown_action_list
= &chan
->compat_sc_exit_unknown
;
1019 struct lttng_syscall_filter
*filter
= chan
->sc_filter
;
1021 if (id
< 0 || id
>= NR_syscalls
1022 || (!READ_ONCE(chan
->syscall_all_exit
) && !test_bit(id
, filter
->sc_exit
))) {
1023 /* System call filtered out. */
1026 table
= sc_exit_table
;
1027 table_len
= ARRAY_SIZE(sc_exit_table
);
1028 unknown_action_list
= &chan
->sc_exit_unknown
;
1030 if (unlikely(id
< 0 || id
>= table_len
)) {
1031 syscall_exit_event_unknown(unknown_action_list
, regs
, id
, ret
);
1036 if (!entry
->event_func
) {
1037 syscall_exit_event_unknown(unknown_action_list
, regs
, id
, ret
);
1041 if (unlikely(in_compat_syscall())) {
1042 action_list
= &chan
->compat_sc_exit_table
[id
];
1044 action_list
= &chan
->sc_exit_table
[id
];
1046 if (unlikely(hlist_empty(action_list
)))
1049 syscall_exit_call_func(action_list
, entry
->event_func
, entry
->nrargs
,
1053 static __always_inline
1054 void syscall_exit_event_notifier_call_func(struct hlist_head
*dispatch_list
,
1055 void *func
, unsigned int nrargs
, struct pt_regs
*regs
, long ret
)
1057 struct lttng_kernel_event_common_private
*event_priv
;
1062 void (*fptr
)(void *__data
, long ret
) = func
;
1064 lttng_hlist_for_each_entry_rcu(event_priv
, dispatch_list
, u
.syscall
.node
) {
1065 struct lttng_kernel_event_notifier_private
*event_notifier_priv
=
1066 container_of(event_priv
, struct lttng_kernel_event_notifier_private
, parent
);
1067 struct lttng_kernel_event_notifier
*event_notifier
= event_notifier_priv
->pub
;
1069 fptr(event_notifier
, ret
);
1075 void (*fptr
)(void *__data
, long ret
, unsigned long arg0
) = func
;
1076 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
1078 lttng_syscall_get_arguments(current
, regs
, args
);
1079 lttng_hlist_for_each_entry_rcu(event_priv
, dispatch_list
, u
.syscall
.node
) {
1080 struct lttng_kernel_event_notifier_private
*event_notifier_priv
=
1081 container_of(event_priv
, struct lttng_kernel_event_notifier_private
, parent
);
1082 struct lttng_kernel_event_notifier
*event_notifier
= event_notifier_priv
->pub
;
1084 fptr(event_notifier
, ret
, args
[0]);
1090 void (*fptr
)(void *__data
,
1093 unsigned long arg1
) = func
;
1094 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
1096 lttng_syscall_get_arguments(current
, regs
, args
);
1097 lttng_hlist_for_each_entry_rcu(event_priv
, dispatch_list
, u
.syscall
.node
) {
1098 struct lttng_kernel_event_notifier_private
*event_notifier_priv
=
1099 container_of(event_priv
, struct lttng_kernel_event_notifier_private
, parent
);
1100 struct lttng_kernel_event_notifier
*event_notifier
= event_notifier_priv
->pub
;
1102 fptr(event_notifier
, ret
, args
[0], args
[1]);
1108 void (*fptr
)(void *__data
,
1112 unsigned long arg2
) = func
;
1113 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
1115 lttng_syscall_get_arguments(current
, regs
, args
);
1116 lttng_hlist_for_each_entry_rcu(event_priv
, dispatch_list
, u
.syscall
.node
) {
1117 struct lttng_kernel_event_notifier_private
*event_notifier_priv
=
1118 container_of(event_priv
, struct lttng_kernel_event_notifier_private
, parent
);
1119 struct lttng_kernel_event_notifier
*event_notifier
= event_notifier_priv
->pub
;
1121 fptr(event_notifier
, ret
, args
[0], args
[1], args
[2]);
1127 void (*fptr
)(void *__data
,
1132 unsigned long arg3
) = func
;
1133 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
1135 lttng_syscall_get_arguments(current
, regs
, args
);
1136 lttng_hlist_for_each_entry_rcu(event_priv
, dispatch_list
, u
.syscall
.node
) {
1137 struct lttng_kernel_event_notifier_private
*event_notifier_priv
=
1138 container_of(event_priv
, struct lttng_kernel_event_notifier_private
, parent
);
1139 struct lttng_kernel_event_notifier
*event_notifier
= event_notifier_priv
->pub
;
1141 fptr(event_notifier
, ret
, args
[0], args
[1], args
[2], args
[3]);
1147 void (*fptr
)(void *__data
,
1153 unsigned long arg4
) = func
;
1154 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
1156 lttng_syscall_get_arguments(current
, regs
, args
);
1157 lttng_hlist_for_each_entry_rcu(event_priv
, dispatch_list
, u
.syscall
.node
) {
1158 struct lttng_kernel_event_notifier_private
*event_notifier_priv
=
1159 container_of(event_priv
, struct lttng_kernel_event_notifier_private
, parent
);
1160 struct lttng_kernel_event_notifier
*event_notifier
= event_notifier_priv
->pub
;
1162 fptr(event_notifier
, ret
, args
[0], args
[1], args
[2], args
[3], args
[4]);
1168 void (*fptr
)(void *__data
,
1175 unsigned long arg5
) = func
;
1176 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
1178 lttng_syscall_get_arguments(current
, regs
, args
);
1179 lttng_hlist_for_each_entry_rcu(event_priv
, dispatch_list
, u
.syscall
.node
) {
1180 struct lttng_kernel_event_notifier_private
*event_notifier_priv
=
1181 container_of(event_priv
, struct lttng_kernel_event_notifier_private
, parent
);
1182 struct lttng_kernel_event_notifier
*event_notifier
= event_notifier_priv
->pub
;
1184 fptr(event_notifier
, ret
, args
[0], args
[1], args
[2], args
[3], args
[4], args
[5]);
1194 void syscall_exit_event_notifier_probe(void *__data
, struct pt_regs
*regs
,
1197 struct lttng_event_notifier_group
*group
= __data
;
1198 const struct trace_syscall_entry
*table
, *entry
;
1199 struct hlist_head
*dispatch_list
, *unknown_dispatch_list
;
1203 id
= syscall_get_nr(current
, regs
);
1205 if (unlikely(in_compat_syscall())) {
1206 struct lttng_syscall_filter
*filter
= group
->sc_filter
;
1208 if (id
< 0 || id
>= NR_compat_syscalls
1209 || (!READ_ONCE(group
->syscall_all_exit
) &&
1210 !test_bit(id
, filter
->sc_compat_exit
))) {
1211 /* System call filtered out. */
1214 table
= compat_sc_exit_table
;
1215 table_len
= ARRAY_SIZE(compat_sc_exit_table
);
1216 unknown_dispatch_list
= &group
->event_notifier_exit_compat_unknown_syscall_dispatch
;
1218 struct lttng_syscall_filter
*filter
= group
->sc_filter
;
1220 if (id
< 0 || id
>= NR_syscalls
1221 || (!READ_ONCE(group
->syscall_all_exit
) &&
1222 !test_bit(id
, filter
->sc_exit
))) {
1223 /* System call filtered out. */
1226 table
= sc_exit_table
;
1227 table_len
= ARRAY_SIZE(sc_exit_table
);
1228 unknown_dispatch_list
= &group
->event_notifier_exit_unknown_syscall_dispatch
;
1230 /* Check if the syscall id is out of bound. */
1231 if (unlikely(id
< 0 || id
>= table_len
)) {
1232 syscall_exit_event_notifier_unknown(unknown_dispatch_list
,
1238 if (!entry
->event_notifier_func
) {
1239 syscall_entry_event_notifier_unknown(unknown_dispatch_list
,
1244 if (unlikely(in_compat_syscall())) {
1245 dispatch_list
= &group
->event_notifier_exit_compat_syscall_dispatch
[id
];
1247 dispatch_list
= &group
->event_notifier_exit_syscall_dispatch
[id
];
1249 if (unlikely(hlist_empty(dispatch_list
)))
1252 syscall_exit_event_notifier_call_func(dispatch_list
,
1253 entry
->event_notifier_func
, entry
->nrargs
, regs
, ret
);
1256 * noinline to diminish caller stack size.
1257 * Should be called with sessions lock held.
1260 int lttng_create_syscall_event_if_missing(const struct trace_syscall_entry
*table
, size_t table_len
,
1261 struct hlist_head
*chan_table
, struct lttng_event_enabler
*event_enabler
,
1264 struct lttng_channel
*chan
= event_enabler
->chan
;
1265 struct lttng_session
*session
= chan
->session
;
1268 /* Allocate events for each syscall matching enabler, insert into table */
1269 for (i
= 0; i
< table_len
; i
++) {
1270 const struct lttng_kernel_event_desc
*desc
= table
[i
].desc
;
1271 struct lttng_kernel_abi_event ev
;
1272 struct lttng_kernel_event_recorder_private
*event_recorder_priv
;
1273 struct lttng_kernel_event_recorder
*event_recorder
;
1274 struct hlist_head
*head
;
1278 /* Unknown syscall */
1281 if (lttng_desc_match_enabler(desc
,
1282 lttng_event_enabler_as_enabler(event_enabler
)) <= 0)
1285 * Check if already created.
1287 head
= utils_borrow_hash_table_bucket(
1288 session
->events_ht
.table
, LTTNG_EVENT_HT_SIZE
,
1290 lttng_hlist_for_each_entry(event_recorder_priv
, head
, hlist
) {
1291 if (event_recorder_priv
->parent
.desc
== desc
1292 && event_recorder_priv
->pub
->chan
== event_enabler
->chan
)
1298 /* We need to create an event for this syscall/enabler. */
1299 memset(&ev
, 0, sizeof(ev
));
1302 ev
.u
.syscall
.entryexit
= LTTNG_KERNEL_ABI_SYSCALL_ENTRY
;
1303 ev
.u
.syscall
.abi
= LTTNG_KERNEL_ABI_SYSCALL_ABI_NATIVE
;
1306 ev
.u
.syscall
.entryexit
= LTTNG_KERNEL_ABI_SYSCALL_EXIT
;
1307 ev
.u
.syscall
.abi
= LTTNG_KERNEL_ABI_SYSCALL_ABI_NATIVE
;
1309 case SC_TYPE_COMPAT_ENTRY
:
1310 ev
.u
.syscall
.entryexit
= LTTNG_KERNEL_ABI_SYSCALL_ENTRY
;
1311 ev
.u
.syscall
.abi
= LTTNG_KERNEL_ABI_SYSCALL_ABI_COMPAT
;
1313 case SC_TYPE_COMPAT_EXIT
:
1314 ev
.u
.syscall
.entryexit
= LTTNG_KERNEL_ABI_SYSCALL_EXIT
;
1315 ev
.u
.syscall
.abi
= LTTNG_KERNEL_ABI_SYSCALL_ABI_COMPAT
;
1318 strncpy(ev
.name
, desc
->event_name
, LTTNG_KERNEL_ABI_SYM_NAME_LEN
- 1);
1319 ev
.name
[LTTNG_KERNEL_ABI_SYM_NAME_LEN
- 1] = '\0';
1320 ev
.instrumentation
= LTTNG_KERNEL_ABI_SYSCALL
;
1321 event_recorder
= _lttng_kernel_event_recorder_create(chan
, &ev
, desc
, ev
.instrumentation
);
1322 WARN_ON_ONCE(!event_recorder
);
1323 if (IS_ERR(event_recorder
)) {
1325 * If something goes wrong in event registration
1326 * after the first one, we have no choice but to
1327 * leave the previous events in there, until
1328 * deleted by session teardown.
1330 return PTR_ERR(event_recorder
);
1332 hlist_add_head(&event_recorder
->priv
->parent
.u
.syscall
.node
, &chan_table
[i
]);
1338 * Should be called with sessions lock held.
1340 int lttng_syscalls_register_event(struct lttng_event_enabler
*event_enabler
)
1342 struct lttng_channel
*chan
= event_enabler
->chan
;
1343 struct lttng_kernel_abi_event ev
;
1346 wrapper_vmalloc_sync_mappings();
1348 if (!chan
->sc_table
) {
1349 /* create syscall table mapping syscall to events */
1350 chan
->sc_table
= kzalloc(sizeof(struct lttng_kernel_event_recorder
*)
1351 * ARRAY_SIZE(sc_table
), GFP_KERNEL
);
1352 if (!chan
->sc_table
)
1355 if (!chan
->sc_exit_table
) {
1356 /* create syscall table mapping syscall to events */
1357 chan
->sc_exit_table
= kzalloc(sizeof(struct lttng_kernel_event_recorder
*)
1358 * ARRAY_SIZE(sc_exit_table
), GFP_KERNEL
);
1359 if (!chan
->sc_exit_table
)
1364 #ifdef CONFIG_COMPAT
1365 if (!chan
->compat_sc_table
) {
1366 /* create syscall table mapping compat syscall to events */
1367 chan
->compat_sc_table
= kzalloc(sizeof(struct lttng_kernel_event_recorder
*)
1368 * ARRAY_SIZE(compat_sc_table
), GFP_KERNEL
);
1369 if (!chan
->compat_sc_table
)
1373 if (!chan
->compat_sc_exit_table
) {
1374 /* create syscall table mapping compat syscall to events */
1375 chan
->compat_sc_exit_table
= kzalloc(sizeof(struct lttng_kernel_event_recorder
*)
1376 * ARRAY_SIZE(compat_sc_exit_table
), GFP_KERNEL
);
1377 if (!chan
->compat_sc_exit_table
)
1381 if (hlist_empty(&chan
->sc_unknown
)) {
1382 const struct lttng_kernel_event_desc
*desc
=
1383 &__event_desc___syscall_entry_unknown
;
1384 struct lttng_kernel_event_recorder
*event_recorder
;
1386 memset(&ev
, 0, sizeof(ev
));
1387 strncpy(ev
.name
, desc
->event_name
, LTTNG_KERNEL_ABI_SYM_NAME_LEN
);
1388 ev
.name
[LTTNG_KERNEL_ABI_SYM_NAME_LEN
- 1] = '\0';
1389 ev
.instrumentation
= LTTNG_KERNEL_ABI_SYSCALL
;
1390 ev
.u
.syscall
.entryexit
= LTTNG_KERNEL_ABI_SYSCALL_ENTRY
;
1391 ev
.u
.syscall
.abi
= LTTNG_KERNEL_ABI_SYSCALL_ABI_NATIVE
;
1392 event_recorder
= _lttng_kernel_event_recorder_create(chan
, &ev
, desc
,
1393 ev
.instrumentation
);
1394 WARN_ON_ONCE(!event_recorder
);
1395 if (IS_ERR(event_recorder
)) {
1396 return PTR_ERR(event_recorder
);
1398 hlist_add_head(&event_recorder
->priv
->parent
.u
.syscall
.node
, &chan
->sc_unknown
);
1401 if (hlist_empty(&chan
->sc_compat_unknown
)) {
1402 const struct lttng_kernel_event_desc
*desc
=
1403 &__event_desc___compat_syscall_entry_unknown
;
1404 struct lttng_kernel_event_recorder
*event_recorder
;
1406 memset(&ev
, 0, sizeof(ev
));
1407 strncpy(ev
.name
, desc
->event_name
, LTTNG_KERNEL_ABI_SYM_NAME_LEN
);
1408 ev
.name
[LTTNG_KERNEL_ABI_SYM_NAME_LEN
- 1] = '\0';
1409 ev
.instrumentation
= LTTNG_KERNEL_ABI_SYSCALL
;
1410 ev
.u
.syscall
.entryexit
= LTTNG_KERNEL_ABI_SYSCALL_ENTRY
;
1411 ev
.u
.syscall
.abi
= LTTNG_KERNEL_ABI_SYSCALL_ABI_COMPAT
;
1412 event_recorder
= _lttng_kernel_event_recorder_create(chan
, &ev
, desc
,
1413 ev
.instrumentation
);
1414 WARN_ON_ONCE(!event_recorder
);
1415 if (IS_ERR(event_recorder
)) {
1416 return PTR_ERR(event_recorder
);
1418 hlist_add_head(&event_recorder
->priv
->parent
.u
.syscall
.node
, &chan
->sc_compat_unknown
);
1421 if (hlist_empty(&chan
->compat_sc_exit_unknown
)) {
1422 const struct lttng_kernel_event_desc
*desc
=
1423 &__event_desc___compat_syscall_exit_unknown
;
1424 struct lttng_kernel_event_recorder
*event_recorder
;
1426 memset(&ev
, 0, sizeof(ev
));
1427 strncpy(ev
.name
, desc
->event_name
, LTTNG_KERNEL_ABI_SYM_NAME_LEN
);
1428 ev
.name
[LTTNG_KERNEL_ABI_SYM_NAME_LEN
- 1] = '\0';
1429 ev
.instrumentation
= LTTNG_KERNEL_ABI_SYSCALL
;
1430 ev
.u
.syscall
.entryexit
= LTTNG_KERNEL_ABI_SYSCALL_EXIT
;
1431 ev
.u
.syscall
.abi
= LTTNG_KERNEL_ABI_SYSCALL_ABI_COMPAT
;
1432 event_recorder
= _lttng_kernel_event_recorder_create(chan
, &ev
, desc
,
1433 ev
.instrumentation
);
1434 WARN_ON_ONCE(!event_recorder
);
1435 if (IS_ERR(event_recorder
)) {
1436 return PTR_ERR(event_recorder
);
1438 hlist_add_head(&event_recorder
->priv
->parent
.u
.syscall
.node
, &chan
->compat_sc_exit_unknown
);
1441 if (hlist_empty(&chan
->sc_exit_unknown
)) {
1442 const struct lttng_kernel_event_desc
*desc
=
1443 &__event_desc___syscall_exit_unknown
;
1444 struct lttng_kernel_event_recorder
*event_recorder
;
1446 memset(&ev
, 0, sizeof(ev
));
1447 strncpy(ev
.name
, desc
->event_name
, LTTNG_KERNEL_ABI_SYM_NAME_LEN
);
1448 ev
.name
[LTTNG_KERNEL_ABI_SYM_NAME_LEN
- 1] = '\0';
1449 ev
.instrumentation
= LTTNG_KERNEL_ABI_SYSCALL
;
1450 ev
.u
.syscall
.entryexit
= LTTNG_KERNEL_ABI_SYSCALL_EXIT
;
1451 ev
.u
.syscall
.abi
= LTTNG_KERNEL_ABI_SYSCALL_ABI_NATIVE
;
1452 event_recorder
= _lttng_kernel_event_recorder_create(chan
, &ev
, desc
,
1453 ev
.instrumentation
);
1454 WARN_ON_ONCE(!event_recorder
);
1455 if (IS_ERR(event_recorder
)) {
1456 return PTR_ERR(event_recorder
);
1458 hlist_add_head(&event_recorder
->priv
->parent
.u
.syscall
.node
, &chan
->sc_exit_unknown
);
1461 ret
= lttng_create_syscall_event_if_missing(sc_table
, ARRAY_SIZE(sc_table
),
1462 chan
->sc_table
, event_enabler
, SC_TYPE_ENTRY
);
1465 ret
= lttng_create_syscall_event_if_missing(sc_exit_table
, ARRAY_SIZE(sc_exit_table
),
1466 chan
->sc_exit_table
, event_enabler
, SC_TYPE_EXIT
);
1470 #ifdef CONFIG_COMPAT
1471 ret
= lttng_create_syscall_event_if_missing(compat_sc_table
, ARRAY_SIZE(compat_sc_table
),
1472 chan
->compat_sc_table
, event_enabler
, SC_TYPE_COMPAT_ENTRY
);
1475 ret
= lttng_create_syscall_event_if_missing(compat_sc_exit_table
, ARRAY_SIZE(compat_sc_exit_table
),
1476 chan
->compat_sc_exit_table
, event_enabler
, SC_TYPE_COMPAT_EXIT
);
1481 if (!chan
->sc_filter
) {
1482 chan
->sc_filter
= kzalloc(sizeof(struct lttng_syscall_filter
),
1484 if (!chan
->sc_filter
)
1488 if (!chan
->sys_enter_registered
) {
1489 ret
= lttng_wrapper_tracepoint_probe_register("sys_enter",
1490 (void *) syscall_entry_event_probe
, chan
);
1493 chan
->sys_enter_registered
= 1;
1496 * We change the name of sys_exit tracepoint due to namespace
1497 * conflict with sys_exit syscall entry.
1499 if (!chan
->sys_exit_registered
) {
1500 ret
= lttng_wrapper_tracepoint_probe_register("sys_exit",
1501 (void *) syscall_exit_event_probe
, chan
);
1503 WARN_ON_ONCE(lttng_wrapper_tracepoint_probe_unregister("sys_enter",
1504 (void *) syscall_entry_event_probe
, chan
));
1507 chan
->sys_exit_registered
= 1;
1513 * Should be called with sessions lock held.
1515 int lttng_syscalls_register_event_notifier(
1516 struct lttng_event_notifier_enabler
*event_notifier_enabler
)
1518 struct lttng_event_notifier_group
*group
= event_notifier_enabler
->group
;
1522 wrapper_vmalloc_sync_mappings();
1524 if (!group
->event_notifier_syscall_dispatch
) {
1525 group
->event_notifier_syscall_dispatch
=
1526 kzalloc(sizeof(struct hlist_head
) * ARRAY_SIZE(sc_table
),
1528 if (!group
->event_notifier_syscall_dispatch
)
1531 /* Initialize all list_head */
1532 for (i
= 0; i
< ARRAY_SIZE(sc_table
); i
++)
1533 INIT_HLIST_HEAD(&group
->event_notifier_syscall_dispatch
[i
]);
1535 /* Init the unknown syscall notifier list. */
1536 INIT_HLIST_HEAD(&group
->event_notifier_unknown_syscall_dispatch
);
1539 if (!group
->event_notifier_exit_syscall_dispatch
) {
1540 group
->event_notifier_exit_syscall_dispatch
=
1541 kzalloc(sizeof(struct hlist_head
) * ARRAY_SIZE(sc_table
),
1543 if (!group
->event_notifier_exit_syscall_dispatch
)
1546 /* Initialize all list_head */
1547 for (i
= 0; i
< ARRAY_SIZE(sc_table
); i
++)
1548 INIT_HLIST_HEAD(&group
->event_notifier_exit_syscall_dispatch
[i
]);
1550 /* Init the unknown exit syscall notifier list. */
1551 INIT_HLIST_HEAD(&group
->event_notifier_exit_unknown_syscall_dispatch
);
1554 #ifdef CONFIG_COMPAT
1555 if (!group
->event_notifier_compat_syscall_dispatch
) {
1556 group
->event_notifier_compat_syscall_dispatch
=
1557 kzalloc(sizeof(struct hlist_head
) * ARRAY_SIZE(compat_sc_table
),
1559 if (!group
->event_notifier_syscall_dispatch
)
1562 /* Initialize all list_head */
1563 for (i
= 0; i
< ARRAY_SIZE(compat_sc_table
); i
++)
1564 INIT_HLIST_HEAD(&group
->event_notifier_compat_syscall_dispatch
[i
]);
1566 /* Init the unknown syscall notifier list. */
1567 INIT_HLIST_HEAD(&group
->event_notifier_compat_unknown_syscall_dispatch
);
1570 if (!group
->event_notifier_exit_compat_syscall_dispatch
) {
1571 group
->event_notifier_exit_compat_syscall_dispatch
=
1572 kzalloc(sizeof(struct hlist_head
) * ARRAY_SIZE(compat_sc_exit_table
),
1574 if (!group
->event_notifier_exit_syscall_dispatch
)
1577 /* Initialize all list_head */
1578 for (i
= 0; i
< ARRAY_SIZE(compat_sc_exit_table
); i
++)
1579 INIT_HLIST_HEAD(&group
->event_notifier_exit_compat_syscall_dispatch
[i
]);
1581 /* Init the unknown exit syscall notifier list. */
1582 INIT_HLIST_HEAD(&group
->event_notifier_exit_compat_unknown_syscall_dispatch
);
1586 if (!group
->sc_filter
) {
1587 group
->sc_filter
= kzalloc(sizeof(struct lttng_syscall_filter
),
1589 if (!group
->sc_filter
)
1593 if (!group
->sys_enter_registered
) {
1594 ret
= lttng_wrapper_tracepoint_probe_register("sys_enter",
1595 (void *) syscall_entry_event_notifier_probe
, group
);
1598 group
->sys_enter_registered
= 1;
1601 if (!group
->sys_exit_registered
) {
1602 ret
= lttng_wrapper_tracepoint_probe_register("sys_exit",
1603 (void *) syscall_exit_event_notifier_probe
, group
);
1605 WARN_ON_ONCE(lttng_wrapper_tracepoint_probe_unregister("sys_enter",
1606 (void *) syscall_entry_event_notifier_probe
, group
));
1609 group
->sys_exit_registered
= 1;
1616 int create_unknown_event_notifier(
1617 struct lttng_event_notifier_enabler
*event_notifier_enabler
,
1620 struct lttng_kernel_event_notifier_private
*event_notifier_priv
;
1621 struct lttng_kernel_event_notifier
*event_notifier
;
1622 const struct lttng_kernel_event_desc
*desc
;
1623 struct lttng_event_notifier_group
*group
= event_notifier_enabler
->group
;
1624 struct lttng_kernel_abi_event_notifier event_notifier_param
;
1625 uint64_t user_token
= event_notifier_enabler
->base
.user_token
;
1626 uint64_t error_counter_index
= event_notifier_enabler
->error_counter_index
;
1627 struct lttng_enabler
*base_enabler
= lttng_event_notifier_enabler_as_enabler(
1628 event_notifier_enabler
);
1629 struct hlist_head
*unknown_dispatch_list
;
1632 enum lttng_kernel_abi_syscall_abi abi
;
1633 enum lttng_kernel_abi_syscall_entryexit entryexit
;
1634 struct hlist_head
*head
;
1638 desc
= &__event_desc___syscall_entry_unknown
;
1639 unknown_dispatch_list
= &group
->event_notifier_unknown_syscall_dispatch
;
1640 entryexit
= LTTNG_KERNEL_ABI_SYSCALL_ENTRY
;
1641 abi
= LTTNG_KERNEL_ABI_SYSCALL_ABI_NATIVE
;
1644 desc
= &__event_desc___syscall_exit_unknown
;
1645 unknown_dispatch_list
= &group
->event_notifier_exit_unknown_syscall_dispatch
;
1646 entryexit
= LTTNG_KERNEL_ABI_SYSCALL_EXIT
;
1647 abi
= LTTNG_KERNEL_ABI_SYSCALL_ABI_NATIVE
;
1649 case SC_TYPE_COMPAT_ENTRY
:
1650 desc
= &__event_desc___compat_syscall_entry_unknown
;
1651 unknown_dispatch_list
= &group
->event_notifier_compat_unknown_syscall_dispatch
;
1652 entryexit
= LTTNG_KERNEL_ABI_SYSCALL_ENTRY
;
1653 abi
= LTTNG_KERNEL_ABI_SYSCALL_ABI_COMPAT
;
1655 case SC_TYPE_COMPAT_EXIT
:
1656 desc
= &__event_desc___compat_syscall_exit_unknown
;
1657 unknown_dispatch_list
= &group
->event_notifier_exit_compat_unknown_syscall_dispatch
;
1658 entryexit
= LTTNG_KERNEL_ABI_SYSCALL_EXIT
;
1659 abi
= LTTNG_KERNEL_ABI_SYSCALL_ABI_COMPAT
;
1666 * Check if already created.
1668 head
= utils_borrow_hash_table_bucket(group
->event_notifiers_ht
.table
,
1669 LTTNG_EVENT_NOTIFIER_HT_SIZE
, desc
->event_name
);
1670 lttng_hlist_for_each_entry(event_notifier_priv
, head
, hlist
) {
1671 if (event_notifier_priv
->parent
.desc
== desc
&&
1672 event_notifier_priv
->parent
.user_token
== base_enabler
->user_token
)
1678 memset(&event_notifier_param
, 0, sizeof(event_notifier_param
));
1679 strncat(event_notifier_param
.event
.name
, desc
->event_name
,
1680 LTTNG_KERNEL_ABI_SYM_NAME_LEN
- strlen(event_notifier_param
.event
.name
) - 1);
1682 event_notifier_param
.event
.name
[LTTNG_KERNEL_ABI_SYM_NAME_LEN
- 1] = '\0';
1684 event_notifier_param
.event
.instrumentation
= LTTNG_KERNEL_ABI_SYSCALL
;
1685 event_notifier_param
.event
.u
.syscall
.abi
= abi
;
1686 event_notifier_param
.event
.u
.syscall
.entryexit
= entryexit
;
1688 event_notifier
= _lttng_event_notifier_create(desc
, user_token
,
1689 error_counter_index
, group
, &event_notifier_param
,
1690 event_notifier_param
.event
.instrumentation
);
1691 if (IS_ERR(event_notifier
)) {
1692 printk(KERN_INFO
"Unable to create unknown notifier %s\n",
1698 hlist_add_head_rcu(&event_notifier
->priv
->parent
.u
.syscall
.node
, unknown_dispatch_list
);
1704 static int create_matching_event_notifiers(
1705 struct lttng_event_notifier_enabler
*event_notifier_enabler
,
1706 const struct trace_syscall_entry
*table
,
1707 size_t table_len
, enum sc_type type
)
1709 struct lttng_event_notifier_group
*group
= event_notifier_enabler
->group
;
1710 const struct lttng_kernel_event_desc
*desc
;
1711 uint64_t user_token
= event_notifier_enabler
->base
.user_token
;
1712 uint64_t error_counter_index
= event_notifier_enabler
->error_counter_index
;
1716 /* iterate over all syscall and create event_notifier that match */
1717 for (i
= 0; i
< table_len
; i
++) {
1718 struct lttng_kernel_event_notifier_private
*event_notifier_priv
;
1719 struct lttng_kernel_event_notifier
*event_notifier
;
1720 struct lttng_kernel_abi_event_notifier event_notifier_param
;
1721 struct hlist_head
*head
;
1724 desc
= table
[i
].desc
;
1726 /* Unknown syscall */
1730 if (!lttng_desc_match_enabler(desc
,
1731 lttng_event_notifier_enabler_as_enabler(event_notifier_enabler
)))
1735 * Check if already created.
1737 head
= utils_borrow_hash_table_bucket(group
->event_notifiers_ht
.table
,
1738 LTTNG_EVENT_NOTIFIER_HT_SIZE
, desc
->event_name
);
1739 lttng_hlist_for_each_entry(event_notifier_priv
, head
, hlist
) {
1740 if (event_notifier_priv
->parent
.desc
== desc
1741 && event_notifier_priv
->parent
.user_token
== event_notifier_enabler
->base
.user_token
)
1747 memset(&event_notifier_param
, 0, sizeof(event_notifier_param
));
1750 event_notifier_param
.event
.u
.syscall
.entryexit
= LTTNG_KERNEL_ABI_SYSCALL_ENTRY
;
1751 event_notifier_param
.event
.u
.syscall
.abi
= LTTNG_KERNEL_ABI_SYSCALL_ABI_NATIVE
;
1754 event_notifier_param
.event
.u
.syscall
.entryexit
= LTTNG_KERNEL_ABI_SYSCALL_EXIT
;
1755 event_notifier_param
.event
.u
.syscall
.abi
= LTTNG_KERNEL_ABI_SYSCALL_ABI_NATIVE
;
1757 case SC_TYPE_COMPAT_ENTRY
:
1758 event_notifier_param
.event
.u
.syscall
.entryexit
= LTTNG_KERNEL_ABI_SYSCALL_ENTRY
;
1759 event_notifier_param
.event
.u
.syscall
.abi
= LTTNG_KERNEL_ABI_SYSCALL_ABI_COMPAT
;
1761 case SC_TYPE_COMPAT_EXIT
:
1762 event_notifier_param
.event
.u
.syscall
.entryexit
= LTTNG_KERNEL_ABI_SYSCALL_EXIT
;
1763 event_notifier_param
.event
.u
.syscall
.abi
= LTTNG_KERNEL_ABI_SYSCALL_ABI_COMPAT
;
1766 strncat(event_notifier_param
.event
.name
, desc
->event_name
,
1767 LTTNG_KERNEL_ABI_SYM_NAME_LEN
- strlen(event_notifier_param
.event
.name
) - 1);
1768 event_notifier_param
.event
.name
[LTTNG_KERNEL_ABI_SYM_NAME_LEN
- 1] = '\0';
1769 event_notifier_param
.event
.instrumentation
= LTTNG_KERNEL_ABI_SYSCALL
;
1771 event_notifier
= _lttng_event_notifier_create(desc
, user_token
,
1772 error_counter_index
, group
, &event_notifier_param
,
1773 event_notifier_param
.event
.instrumentation
);
1774 if (IS_ERR(event_notifier
)) {
1775 printk(KERN_INFO
"Unable to create event_notifier %s\n",
1781 event_notifier
->priv
->parent
.u
.syscall
.syscall_id
= i
;
1789 int lttng_syscalls_create_matching_event_notifiers(
1790 struct lttng_event_notifier_enabler
*event_notifier_enabler
)
1793 struct lttng_enabler
*base_enabler
=
1794 lttng_event_notifier_enabler_as_enabler(event_notifier_enabler
);
1795 enum lttng_kernel_abi_syscall_entryexit entryexit
=
1796 base_enabler
->event_param
.u
.syscall
.entryexit
;
1798 if (entryexit
== LTTNG_KERNEL_ABI_SYSCALL_ENTRY
|| entryexit
== LTTNG_KERNEL_ABI_SYSCALL_ENTRYEXIT
) {
1799 ret
= create_matching_event_notifiers(event_notifier_enabler
,
1800 sc_table
, ARRAY_SIZE(sc_table
), SC_TYPE_ENTRY
);
1804 ret
= create_matching_event_notifiers(event_notifier_enabler
,
1805 compat_sc_table
, ARRAY_SIZE(compat_sc_table
),
1806 SC_TYPE_COMPAT_ENTRY
);
1810 ret
= create_unknown_event_notifier(event_notifier_enabler
,
1815 ret
= create_unknown_event_notifier(event_notifier_enabler
,
1816 SC_TYPE_COMPAT_ENTRY
);
1821 if (entryexit
== LTTNG_KERNEL_ABI_SYSCALL_EXIT
|| entryexit
== LTTNG_KERNEL_ABI_SYSCALL_ENTRYEXIT
) {
1822 ret
= create_matching_event_notifiers(event_notifier_enabler
,
1823 sc_exit_table
, ARRAY_SIZE(sc_exit_table
),
1828 ret
= create_unknown_event_notifier(event_notifier_enabler
,
1833 ret
= create_matching_event_notifiers(event_notifier_enabler
,
1834 compat_sc_exit_table
, ARRAY_SIZE(compat_sc_exit_table
),
1835 SC_TYPE_COMPAT_EXIT
);
1839 ret
= create_unknown_event_notifier(event_notifier_enabler
,
1840 SC_TYPE_COMPAT_EXIT
);
1850 * Unregister the syscall event_notifier probes from the callsites.
1852 int lttng_syscalls_unregister_event_notifier_group(
1853 struct lttng_event_notifier_group
*event_notifier_group
)
1858 * Only register the event_notifier probe on the `sys_enter` callsite for now.
1859 * At the moment, we don't think it's desirable to have one fired
1860 * event_notifier for the entry and one for the exit of a syscall.
1862 if (event_notifier_group
->sys_enter_registered
) {
1863 ret
= lttng_wrapper_tracepoint_probe_unregister("sys_enter",
1864 (void *) syscall_entry_event_notifier_probe
, event_notifier_group
);
1867 event_notifier_group
->sys_enter_registered
= 0;
1869 if (event_notifier_group
->sys_exit_registered
) {
1870 ret
= lttng_wrapper_tracepoint_probe_unregister("sys_exit",
1871 (void *) syscall_exit_event_notifier_probe
, event_notifier_group
);
1874 event_notifier_group
->sys_enter_registered
= 0;
1877 kfree(event_notifier_group
->event_notifier_syscall_dispatch
);
1878 kfree(event_notifier_group
->event_notifier_exit_syscall_dispatch
);
1879 #ifdef CONFIG_COMPAT
1880 kfree(event_notifier_group
->event_notifier_compat_syscall_dispatch
);
1881 kfree(event_notifier_group
->event_notifier_exit_compat_syscall_dispatch
);
1886 int lttng_syscalls_unregister_channel(struct lttng_channel
*chan
)
1890 if (!chan
->sc_table
)
1892 if (chan
->sys_enter_registered
) {
1893 ret
= lttng_wrapper_tracepoint_probe_unregister("sys_enter",
1894 (void *) syscall_entry_event_probe
, chan
);
1897 chan
->sys_enter_registered
= 0;
1899 if (chan
->sys_exit_registered
) {
1900 ret
= lttng_wrapper_tracepoint_probe_unregister("sys_exit",
1901 (void *) syscall_exit_event_probe
, chan
);
1904 chan
->sys_exit_registered
= 0;
1909 int lttng_syscalls_destroy_event(struct lttng_channel
*chan
)
1911 kfree(chan
->sc_table
);
1912 kfree(chan
->sc_exit_table
);
1913 #ifdef CONFIG_COMPAT
1914 kfree(chan
->compat_sc_table
);
1915 kfree(chan
->compat_sc_exit_table
);
1917 kfree(chan
->sc_filter
);
1922 int get_syscall_nr(const char *syscall_name
)
1924 int syscall_nr
= -1;
1927 for (i
= 0; i
< ARRAY_SIZE(sc_table
); i
++) {
1928 const struct trace_syscall_entry
*entry
;
1929 const char *it_name
;
1931 entry
= &sc_table
[i
];
1934 it_name
= entry
->desc
->event_name
;
1935 it_name
+= strlen(SYSCALL_ENTRY_STR
);
1936 if (!strcmp(syscall_name
, it_name
)) {
1945 int get_compat_syscall_nr(const char *syscall_name
)
1947 int syscall_nr
= -1;
1950 for (i
= 0; i
< ARRAY_SIZE(compat_sc_table
); i
++) {
1951 const struct trace_syscall_entry
*entry
;
1952 const char *it_name
;
1954 entry
= &compat_sc_table
[i
];
1957 it_name
= entry
->desc
->event_name
;
1958 it_name
+= strlen(COMPAT_SYSCALL_ENTRY_STR
);
1959 if (!strcmp(syscall_name
, it_name
)) {
1968 uint32_t get_sc_tables_len(void)
1970 return ARRAY_SIZE(sc_table
) + ARRAY_SIZE(compat_sc_table
);
1974 const char *get_syscall_name(const char *desc_name
,
1975 enum lttng_syscall_abi abi
,
1976 enum lttng_syscall_entryexit entryexit
)
1978 size_t prefix_len
= 0;
1981 switch (entryexit
) {
1982 case LTTNG_SYSCALL_ENTRY
:
1984 case LTTNG_SYSCALL_ABI_NATIVE
:
1985 prefix_len
= strlen(SYSCALL_ENTRY_STR
);
1987 case LTTNG_SYSCALL_ABI_COMPAT
:
1988 prefix_len
= strlen(COMPAT_SYSCALL_ENTRY_STR
);
1992 case LTTNG_SYSCALL_EXIT
:
1994 case LTTNG_SYSCALL_ABI_NATIVE
:
1995 prefix_len
= strlen(SYSCALL_EXIT_STR
);
1997 case LTTNG_SYSCALL_ABI_COMPAT
:
1998 prefix_len
= strlen(COMPAT_SYSCALL_EXIT_STR
);
2003 WARN_ON_ONCE(prefix_len
== 0);
2004 return desc_name
+ prefix_len
;
2008 int lttng_syscall_filter_enable(
2009 struct lttng_syscall_filter
*filter
,
2010 const char *desc_name
, enum lttng_syscall_abi abi
,
2011 enum lttng_syscall_entryexit entryexit
)
2013 const char *syscall_name
;
2014 unsigned long *bitmap
;
2017 syscall_name
= get_syscall_name(desc_name
, abi
, entryexit
);
2020 case LTTNG_SYSCALL_ABI_NATIVE
:
2021 syscall_nr
= get_syscall_nr(syscall_name
);
2023 case LTTNG_SYSCALL_ABI_COMPAT
:
2024 syscall_nr
= get_compat_syscall_nr(syscall_name
);
2032 switch (entryexit
) {
2033 case LTTNG_SYSCALL_ENTRY
:
2035 case LTTNG_SYSCALL_ABI_NATIVE
:
2036 bitmap
= filter
->sc_entry
;
2038 case LTTNG_SYSCALL_ABI_COMPAT
:
2039 bitmap
= filter
->sc_compat_entry
;
2045 case LTTNG_SYSCALL_EXIT
:
2047 case LTTNG_SYSCALL_ABI_NATIVE
:
2048 bitmap
= filter
->sc_exit
;
2050 case LTTNG_SYSCALL_ABI_COMPAT
:
2051 bitmap
= filter
->sc_compat_exit
;
2060 if (test_bit(syscall_nr
, bitmap
))
2062 bitmap_set(bitmap
, syscall_nr
, 1);
2066 int lttng_syscall_filter_enable_event_notifier(
2067 struct lttng_kernel_event_notifier
*event_notifier
)
2069 struct lttng_event_notifier_group
*group
= event_notifier
->priv
->group
;
2070 unsigned int syscall_id
= event_notifier
->priv
->parent
.u
.syscall
.syscall_id
;
2071 struct hlist_head
*dispatch_list
;
2074 WARN_ON_ONCE(event_notifier
->priv
->parent
.instrumentation
!= LTTNG_KERNEL_ABI_SYSCALL
);
2076 ret
= lttng_syscall_filter_enable(group
->sc_filter
,
2077 event_notifier
->priv
->parent
.desc
->event_name
,
2078 event_notifier
->priv
->parent
.u
.syscall
.abi
,
2079 event_notifier
->priv
->parent
.u
.syscall
.entryexit
);
2084 switch (event_notifier
->priv
->parent
.u
.syscall
.entryexit
) {
2085 case LTTNG_SYSCALL_ENTRY
:
2086 switch (event_notifier
->priv
->parent
.u
.syscall
.abi
) {
2087 case LTTNG_SYSCALL_ABI_NATIVE
:
2088 dispatch_list
= &group
->event_notifier_syscall_dispatch
[syscall_id
];
2090 case LTTNG_SYSCALL_ABI_COMPAT
:
2091 dispatch_list
= &group
->event_notifier_compat_syscall_dispatch
[syscall_id
];
2098 case LTTNG_SYSCALL_EXIT
:
2099 switch (event_notifier
->priv
->parent
.u
.syscall
.abi
) {
2100 case LTTNG_SYSCALL_ABI_NATIVE
:
2101 dispatch_list
= &group
->event_notifier_exit_syscall_dispatch
[syscall_id
];
2103 case LTTNG_SYSCALL_ABI_COMPAT
:
2104 dispatch_list
= &group
->event_notifier_exit_compat_syscall_dispatch
[syscall_id
];
2116 hlist_add_head_rcu(&event_notifier
->priv
->parent
.u
.syscall
.node
, dispatch_list
);
2122 int lttng_syscall_filter_enable_event(
2123 struct lttng_channel
*channel
,
2124 struct lttng_kernel_event_recorder
*event_recorder
)
2126 WARN_ON_ONCE(event_recorder
->priv
->parent
.instrumentation
!= LTTNG_KERNEL_ABI_SYSCALL
);
2128 return lttng_syscall_filter_enable(channel
->sc_filter
,
2129 event_recorder
->priv
->parent
.desc
->event_name
,
2130 event_recorder
->priv
->parent
.u
.syscall
.abi
,
2131 event_recorder
->priv
->parent
.u
.syscall
.entryexit
);
2135 int lttng_syscall_filter_disable(
2136 struct lttng_syscall_filter
*filter
,
2137 const char *desc_name
, enum lttng_syscall_abi abi
,
2138 enum lttng_syscall_entryexit entryexit
)
2140 const char *syscall_name
;
2141 unsigned long *bitmap
;
2144 syscall_name
= get_syscall_name(desc_name
, abi
, entryexit
);
2147 case LTTNG_SYSCALL_ABI_NATIVE
:
2148 syscall_nr
= get_syscall_nr(syscall_name
);
2150 case LTTNG_SYSCALL_ABI_COMPAT
:
2151 syscall_nr
= get_compat_syscall_nr(syscall_name
);
2159 switch (entryexit
) {
2160 case LTTNG_SYSCALL_ENTRY
:
2162 case LTTNG_SYSCALL_ABI_NATIVE
:
2163 bitmap
= filter
->sc_entry
;
2165 case LTTNG_SYSCALL_ABI_COMPAT
:
2166 bitmap
= filter
->sc_compat_entry
;
2172 case LTTNG_SYSCALL_EXIT
:
2174 case LTTNG_SYSCALL_ABI_NATIVE
:
2175 bitmap
= filter
->sc_exit
;
2177 case LTTNG_SYSCALL_ABI_COMPAT
:
2178 bitmap
= filter
->sc_compat_exit
;
2187 if (!test_bit(syscall_nr
, bitmap
))
2189 bitmap_clear(bitmap
, syscall_nr
, 1);
2194 int lttng_syscall_filter_disable_event_notifier(
2195 struct lttng_kernel_event_notifier
*event_notifier
)
2197 struct lttng_event_notifier_group
*group
= event_notifier
->priv
->group
;
2200 WARN_ON_ONCE(event_notifier
->priv
->parent
.instrumentation
!= LTTNG_KERNEL_ABI_SYSCALL
);
2202 ret
= lttng_syscall_filter_disable(group
->sc_filter
,
2203 event_notifier
->priv
->parent
.desc
->event_name
,
2204 event_notifier
->priv
->parent
.u
.syscall
.abi
,
2205 event_notifier
->priv
->parent
.u
.syscall
.entryexit
);
2206 WARN_ON_ONCE(ret
!= 0);
2208 hlist_del_rcu(&event_notifier
->priv
->parent
.u
.syscall
.node
);
2212 int lttng_syscall_filter_disable_event(
2213 struct lttng_channel
*channel
,
2214 struct lttng_kernel_event_recorder
*event_recorder
)
2216 return lttng_syscall_filter_disable(channel
->sc_filter
,
2217 event_recorder
->priv
->parent
.desc
->event_name
,
2218 event_recorder
->priv
->parent
.u
.syscall
.abi
,
2219 event_recorder
->priv
->parent
.u
.syscall
.entryexit
);
2223 const struct trace_syscall_entry
*syscall_list_get_entry(loff_t
*pos
)
2225 const struct trace_syscall_entry
*entry
;
2228 for (entry
= sc_table
;
2229 entry
< sc_table
+ ARRAY_SIZE(sc_table
);
2234 for (entry
= compat_sc_table
;
2235 entry
< compat_sc_table
+ ARRAY_SIZE(compat_sc_table
);
2245 void *syscall_list_start(struct seq_file
*m
, loff_t
*pos
)
2247 return (void *) syscall_list_get_entry(pos
);
2251 void *syscall_list_next(struct seq_file
*m
, void *p
, loff_t
*ppos
)
2254 return (void *) syscall_list_get_entry(ppos
);
2258 void syscall_list_stop(struct seq_file
*m
, void *p
)
2263 int get_sc_table(const struct trace_syscall_entry
*entry
,
2264 const struct trace_syscall_entry
**table
,
2265 unsigned int *bitness
)
2267 if (entry
>= sc_table
&& entry
< sc_table
+ ARRAY_SIZE(sc_table
)) {
2269 *bitness
= BITS_PER_LONG
;
2274 if (!(entry
>= compat_sc_table
2275 && entry
< compat_sc_table
+ ARRAY_SIZE(compat_sc_table
))) {
2281 *table
= compat_sc_table
;
2286 int syscall_list_show(struct seq_file
*m
, void *p
)
2288 const struct trace_syscall_entry
*table
, *entry
= p
;
2289 unsigned int bitness
;
2290 unsigned long index
;
2294 ret
= get_sc_table(entry
, &table
, &bitness
);
2299 if (table
== sc_table
) {
2300 index
= entry
- table
;
2301 name
= &entry
->desc
->event_name
[strlen(SYSCALL_ENTRY_STR
)];
2303 index
= (entry
- table
) + ARRAY_SIZE(sc_table
);
2304 name
= &entry
->desc
->event_name
[strlen(COMPAT_SYSCALL_ENTRY_STR
)];
2306 seq_printf(m
, "syscall { index = %lu; name = %s; bitness = %u; };\n",
2307 index
, name
, bitness
);
2312 const struct seq_operations lttng_syscall_list_seq_ops
= {
2313 .start
= syscall_list_start
,
2314 .next
= syscall_list_next
,
2315 .stop
= syscall_list_stop
,
2316 .show
= syscall_list_show
,
2320 int lttng_syscall_list_open(struct inode
*inode
, struct file
*file
)
2322 return seq_open(file
, <tng_syscall_list_seq_ops
);
2325 const struct file_operations lttng_syscall_list_fops
= {
2326 .owner
= THIS_MODULE
,
2327 .open
= lttng_syscall_list_open
,
2329 .llseek
= seq_lseek
,
2330 .release
= seq_release
,
2334 * A syscall is enabled if it is traced for either entry or exit.
2336 long lttng_channel_syscall_mask(struct lttng_channel
*channel
,
2337 struct lttng_kernel_abi_syscall_mask __user
*usyscall_mask
)
2339 uint32_t len
, sc_tables_len
, bitmask_len
;
2342 struct lttng_syscall_filter
*filter
;
2344 ret
= get_user(len
, &usyscall_mask
->len
);
2347 sc_tables_len
= get_sc_tables_len();
2348 bitmask_len
= ALIGN(sc_tables_len
, 8) >> 3;
2349 if (len
< sc_tables_len
) {
2350 return put_user(sc_tables_len
, &usyscall_mask
->len
);
2352 /* Array is large enough, we can copy array to user-space. */
2353 tmp_mask
= kzalloc(bitmask_len
, GFP_KERNEL
);
2356 filter
= channel
->sc_filter
;
2358 for (bit
= 0; bit
< ARRAY_SIZE(sc_table
); bit
++) {
2361 if (channel
->sc_table
) {
2362 if (!(READ_ONCE(channel
->syscall_all_entry
)
2363 || READ_ONCE(channel
->syscall_all_exit
)) && filter
)
2364 state
= test_bit(bit
, filter
->sc_entry
)
2365 || test_bit(bit
, filter
->sc_exit
);
2371 bt_bitfield_write_be(tmp_mask
, char, bit
, 1, state
);
2373 for (; bit
< sc_tables_len
; bit
++) {
2376 if (channel
->compat_sc_table
) {
2377 if (!(READ_ONCE(channel
->syscall_all_entry
)
2378 || READ_ONCE(channel
->syscall_all_exit
)) && filter
)
2379 state
= test_bit(bit
- ARRAY_SIZE(sc_table
),
2380 filter
->sc_compat_entry
)
2381 || test_bit(bit
- ARRAY_SIZE(sc_table
),
2382 filter
->sc_compat_exit
);
2388 bt_bitfield_write_be(tmp_mask
, char, bit
, 1, state
);
2390 if (copy_to_user(usyscall_mask
->mask
, tmp_mask
, bitmask_len
))
2396 int lttng_abi_syscall_list(void)
2398 struct file
*syscall_list_file
;
2401 file_fd
= lttng_get_unused_fd();
2407 syscall_list_file
= anon_inode_getfile("[lttng_syscall_list]",
2408 <tng_syscall_list_fops
,
2410 if (IS_ERR(syscall_list_file
)) {
2411 ret
= PTR_ERR(syscall_list_file
);
2414 ret
= lttng_syscall_list_fops
.open(NULL
, syscall_list_file
);
2417 fd_install(file_fd
, syscall_list_file
);
2421 fput(syscall_list_file
);
2423 put_unused_fd(file_fd
);