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/events-internal.h>
33 #include <lttng/utils.h>
36 # ifndef is_compat_task
37 # define is_compat_task() (0)
41 /* in_compat_syscall appears in kernel 4.6. */
42 #ifndef in_compat_syscall
43 #define in_compat_syscall() is_compat_task()
53 #define SYSCALL_ENTRY_TOK syscall_entry_
54 #define COMPAT_SYSCALL_ENTRY_TOK compat_syscall_entry_
55 #define SYSCALL_EXIT_TOK syscall_exit_
56 #define COMPAT_SYSCALL_EXIT_TOK compat_syscall_exit_
58 #define SYSCALL_ENTRY_STR __stringify(SYSCALL_ENTRY_TOK)
59 #define COMPAT_SYSCALL_ENTRY_STR __stringify(COMPAT_SYSCALL_ENTRY_TOK)
60 #define SYSCALL_EXIT_STR __stringify(SYSCALL_EXIT_TOK)
61 #define COMPAT_SYSCALL_EXIT_STR __stringify(COMPAT_SYSCALL_EXIT_TOK)
64 void syscall_entry_event_probe(void *__data
, struct pt_regs
*regs
, long id
);
66 void syscall_exit_event_probe(void *__data
, struct pt_regs
*regs
, long ret
);
69 void syscall_entry_event_notifier_probe(void *__data
, struct pt_regs
*regs
,
72 void syscall_exit_event_notifier_probe(void *__data
, struct pt_regs
*regs
,
76 * Forward declarations for old kernels.
80 struct oldold_utsname
;
82 struct sel_arg_struct
;
83 struct mmap_arg_struct
;
88 * Forward declaration for kernels >= 5.6
95 #if (LTTNG_LINUX_VERSION_CODE >= LTTNG_KERNEL_VERSION(5,6,0))
96 typedef __kernel_old_time_t
time_t;
99 #ifdef IA32_NR_syscalls
100 #define NR_compat_syscalls IA32_NR_syscalls
102 #define NR_compat_syscalls NR_syscalls
106 * Create LTTng tracepoint probes.
108 #define LTTNG_PACKAGE_BUILD
109 #define CREATE_TRACE_POINTS
110 #define TP_MODULE_NOINIT
111 #define TRACE_INCLUDE_PATH instrumentation/syscalls/headers
113 #define PARAMS(args...) args
115 /* Handle unknown syscalls */
117 #define TRACE_SYSTEM syscalls_unknown
118 #include <instrumentation/syscalls/headers/syscalls_unknown.h>
126 #define sc_in(...) __VA_ARGS__
130 #define sc_inout(...) __VA_ARGS__
132 /* Hijack probe callback for system call enter */
134 #define TP_PROBE_CB(_template) &syscall_entry_event_probe
135 #define SC_LTTNG_TRACEPOINT_EVENT(_name, _proto, _args, _fields) \
136 LTTNG_TRACEPOINT_EVENT(syscall_entry_##_name, PARAMS(_proto), PARAMS(_args), \
138 #define SC_LTTNG_TRACEPOINT_EVENT_CODE(_name, _proto, _args, _locvar, _code_pre, _fields, _code_post) \
139 LTTNG_TRACEPOINT_EVENT_CODE(syscall_entry_##_name, PARAMS(_proto), PARAMS(_args), \
140 PARAMS(_locvar), PARAMS(_code_pre), \
141 PARAMS(_fields), PARAMS(_code_post))
142 #define SC_LTTNG_TRACEPOINT_EVENT_CLASS_NOARGS(_name, _fields) \
143 LTTNG_TRACEPOINT_EVENT_CLASS_NOARGS(syscall_entry_##_name, PARAMS(_fields))
144 #define SC_LTTNG_TRACEPOINT_EVENT_INSTANCE_NOARGS(_template, _name) \
145 LTTNG_TRACEPOINT_EVENT_INSTANCE_NOARGS(syscall_entry_##_template, syscall_entry_##_name)
146 /* Enumerations only defined at first inclusion. */
147 #define SC_LTTNG_TRACEPOINT_ENUM(_name, _values) \
148 LTTNG_TRACEPOINT_ENUM(_name, PARAMS(_values))
150 #define TRACE_SYSTEM syscall_entry_integers
151 #define TRACE_INCLUDE_FILE syscalls_integers
152 #include <instrumentation/syscalls/headers/syscalls_integers.h>
153 #undef TRACE_INCLUDE_FILE
155 #define TRACE_SYSTEM syscall_entry_pointers
156 #define TRACE_INCLUDE_FILE syscalls_pointers
157 #include <instrumentation/syscalls/headers/syscalls_pointers.h>
158 #undef TRACE_INCLUDE_FILE
160 #undef SC_LTTNG_TRACEPOINT_ENUM
161 #undef SC_LTTNG_TRACEPOINT_EVENT_CODE
162 #undef SC_LTTNG_TRACEPOINT_EVENT
163 #undef SC_LTTNG_TRACEPOINT_EVENT_CLASS_NOARGS
164 #undef SC_LTTNG_TRACEPOINT_EVENT_INSTANCE_NOARGS
166 #undef _TRACE_SYSCALLS_INTEGERS_H
167 #undef _TRACE_SYSCALLS_POINTERS_H
169 /* Hijack probe callback for compat system call enter */
170 #define TP_PROBE_CB(_template) &syscall_entry_event_probe
171 #define LTTNG_SC_COMPAT
172 #define SC_LTTNG_TRACEPOINT_EVENT(_name, _proto, _args, _fields) \
173 LTTNG_TRACEPOINT_EVENT(compat_syscall_entry_##_name, PARAMS(_proto), PARAMS(_args), \
175 #define SC_LTTNG_TRACEPOINT_EVENT_CODE(_name, _proto, _args, _locvar, _code_pre, _fields, _code_post) \
176 LTTNG_TRACEPOINT_EVENT_CODE(compat_syscall_entry_##_name, PARAMS(_proto), PARAMS(_args), \
177 PARAMS(_locvar), PARAMS(_code_pre), PARAMS(_fields), PARAMS(_code_post))
178 #define SC_LTTNG_TRACEPOINT_EVENT_CLASS_NOARGS(_name, _fields) \
179 LTTNG_TRACEPOINT_EVENT_CLASS_NOARGS(compat_syscall_entry_##_name, PARAMS(_fields))
180 #define SC_LTTNG_TRACEPOINT_EVENT_INSTANCE_NOARGS(_template, _name) \
181 LTTNG_TRACEPOINT_EVENT_INSTANCE_NOARGS(compat_syscall_entry_##_template, \
182 compat_syscall_entry_##_name)
183 /* Enumerations only defined at inital inclusion (not here). */
184 #define SC_LTTNG_TRACEPOINT_ENUM(_name, _values)
185 #define TRACE_SYSTEM compat_syscall_entry_integers
186 #define TRACE_INCLUDE_FILE compat_syscalls_integers
187 #include <instrumentation/syscalls/headers/compat_syscalls_integers.h>
188 #undef TRACE_INCLUDE_FILE
190 #define TRACE_SYSTEM compat_syscall_entry_pointers
191 #define TRACE_INCLUDE_FILE compat_syscalls_pointers
192 #include <instrumentation/syscalls/headers/compat_syscalls_pointers.h>
193 #undef TRACE_INCLUDE_FILE
195 #undef SC_LTTNG_TRACEPOINT_ENUM
196 #undef SC_LTTNG_TRACEPOINT_EVENT_CODE
197 #undef SC_LTTNG_TRACEPOINT_EVENT
198 #undef SC_LTTNG_TRACEPOINT_EVENT_CLASS_NOARGS
199 #undef SC_LTTNG_TRACEPOINT_EVENT_INSTANCE_NOARGS
201 #undef _TRACE_SYSCALLS_INTEGERS_H
202 #undef _TRACE_SYSCALLS_POINTERS_H
203 #undef LTTNG_SC_COMPAT
210 #define sc_exit(...) __VA_ARGS__
214 #define sc_out(...) __VA_ARGS__
216 #define sc_inout(...) __VA_ARGS__
218 /* Hijack probe callback for system call exit */
219 #define TP_PROBE_CB(_template) &syscall_exit_event_probe
220 #define SC_LTTNG_TRACEPOINT_EVENT(_name, _proto, _args, _fields) \
221 LTTNG_TRACEPOINT_EVENT(syscall_exit_##_name, PARAMS(_proto), PARAMS(_args), \
223 #define SC_LTTNG_TRACEPOINT_EVENT_CODE(_name, _proto, _args, _locvar, _code_pre, _fields, _code_post) \
224 LTTNG_TRACEPOINT_EVENT_CODE(syscall_exit_##_name, PARAMS(_proto), PARAMS(_args), \
225 PARAMS(_locvar), PARAMS(_code_pre), PARAMS(_fields), PARAMS(_code_post))
226 #define SC_LTTNG_TRACEPOINT_EVENT_CLASS_NOARGS(_name, _fields) \
227 LTTNG_TRACEPOINT_EVENT_CLASS_NOARGS(syscall_exit_##_name, PARAMS(_fields))
228 #define SC_LTTNG_TRACEPOINT_EVENT_INSTANCE_NOARGS(_template, _name) \
229 LTTNG_TRACEPOINT_EVENT_INSTANCE_NOARGS(syscall_exit_##_template, \
230 syscall_exit_##_name)
231 /* Enumerations only defined at inital inclusion (not here). */
232 #define SC_LTTNG_TRACEPOINT_ENUM(_name, _values)
233 #define TRACE_SYSTEM syscall_exit_integers
234 #define TRACE_INCLUDE_FILE syscalls_integers
235 #include <instrumentation/syscalls/headers/syscalls_integers.h>
236 #undef TRACE_INCLUDE_FILE
238 #define TRACE_SYSTEM syscall_exit_pointers
239 #define TRACE_INCLUDE_FILE syscalls_pointers
240 #include <instrumentation/syscalls/headers/syscalls_pointers.h>
241 #undef TRACE_INCLUDE_FILE
243 #undef SC_LTTNG_TRACEPOINT_ENUM
244 #undef SC_LTTNG_TRACEPOINT_EVENT_CODE
245 #undef SC_LTTNG_TRACEPOINT_EVENT
246 #undef SC_LTTNG_TRACEPOINT_EVENT_CLASS_NOARGS
247 #undef SC_LTTNG_TRACEPOINT_EVENT_INSTANCE_NOARGS
249 #undef _TRACE_SYSCALLS_INTEGERS_H
250 #undef _TRACE_SYSCALLS_POINTERS_H
253 /* Hijack probe callback for compat system call exit */
254 #define TP_PROBE_CB(_template) &syscall_exit_event_probe
255 #define LTTNG_SC_COMPAT
256 #define SC_LTTNG_TRACEPOINT_EVENT(_name, _proto, _args, _fields) \
257 LTTNG_TRACEPOINT_EVENT(compat_syscall_exit_##_name, PARAMS(_proto), PARAMS(_args), \
259 #define SC_LTTNG_TRACEPOINT_EVENT_CODE(_name, _proto, _args, _locvar, _code_pre, _fields, _code_post) \
260 LTTNG_TRACEPOINT_EVENT_CODE(compat_syscall_exit_##_name, PARAMS(_proto), PARAMS(_args), \
261 PARAMS(_locvar), PARAMS(_code_pre), PARAMS(_fields), PARAMS(_code_post))
262 #define SC_LTTNG_TRACEPOINT_EVENT_CLASS_NOARGS(_name, _fields) \
263 LTTNG_TRACEPOINT_EVENT_CLASS_NOARGS(compat_syscall_exit_##_name, PARAMS(_fields))
264 #define SC_LTTNG_TRACEPOINT_EVENT_INSTANCE_NOARGS(_template, _name) \
265 LTTNG_TRACEPOINT_EVENT_INSTANCE_NOARGS(compat_syscall_exit_##_template, \
266 compat_syscall_exit_##_name)
267 /* Enumerations only defined at inital inclusion (not here). */
268 #define SC_LTTNG_TRACEPOINT_ENUM(_name, _values)
269 #define TRACE_SYSTEM compat_syscall_exit_integers
270 #define TRACE_INCLUDE_FILE compat_syscalls_integers
271 #include <instrumentation/syscalls/headers/compat_syscalls_integers.h>
272 #undef TRACE_INCLUDE_FILE
274 #define TRACE_SYSTEM compat_syscall_exit_pointers
275 #define TRACE_INCLUDE_FILE compat_syscalls_pointers
276 #include <instrumentation/syscalls/headers/compat_syscalls_pointers.h>
277 #undef TRACE_INCLUDE_FILE
279 #undef SC_LTTNG_TRACEPOINT_ENUM
280 #undef SC_LTTNG_TRACEPOINT_EVENT_CODE
281 #undef SC_LTTNG_TRACEPOINT_EVENT
282 #undef SC_LTTNG_TRACEPOINT_EVENT_CLASS_NOARGS
283 #undef SC_LTTNG_TRACEPOINT_EVENT_INSTANCE_NOARGS
285 #undef _TRACE_SYSCALLS_INTEGERS_H
286 #undef _TRACE_SYSCALLS_POINTERS_H
287 #undef LTTNG_SC_COMPAT
291 #undef TP_MODULE_NOINIT
292 #undef LTTNG_PACKAGE_BUILD
293 #undef CREATE_TRACE_POINTS
295 struct trace_syscall_entry
{
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 .nrargs = (_nrargs), \
314 .fields = __event_fields___syscall_entry_##_template, \
315 .desc = &__event_desc___syscall_entry_##_name, \
318 /* Event syscall enter tracing table */
319 static const struct trace_syscall_entry sc_table
[] = {
320 #include <instrumentation/syscalls/headers/syscalls_integers.h>
321 #include <instrumentation/syscalls/headers/syscalls_pointers.h>
324 #undef TRACE_SYSCALL_TABLE
325 #define TRACE_SYSCALL_TABLE(_template, _name, _nr, _nrargs) \
327 .event_func = __event_probe__compat_syscall_entry_##_template, \
328 .nrargs = (_nrargs), \
329 .fields = __event_fields___compat_syscall_entry_##_template, \
330 .desc = &__event_desc___compat_syscall_entry_##_name, \
333 /* Event compat syscall enter table */
334 const struct trace_syscall_entry compat_sc_table
[] = {
335 #include <instrumentation/syscalls/headers/compat_syscalls_integers.h>
336 #include <instrumentation/syscalls/headers/compat_syscalls_pointers.h>
344 #define sc_exit(...) __VA_ARGS__
346 #undef TRACE_SYSCALL_TABLE
347 #define TRACE_SYSCALL_TABLE(_template, _name, _nr, _nrargs) \
349 .event_func = __event_probe__syscall_exit_##_template, \
350 .nrargs = (_nrargs), \
351 .fields = __event_fields___syscall_exit_##_template, \
352 .desc = &__event_desc___syscall_exit_##_name, \
355 /* Event syscall exit table */
356 static const struct trace_syscall_entry sc_exit_table
[] = {
357 #include <instrumentation/syscalls/headers/syscalls_integers.h>
358 #include <instrumentation/syscalls/headers/syscalls_pointers.h>
361 #undef TRACE_SYSCALL_TABLE
362 #define TRACE_SYSCALL_TABLE(_template, _name, _nr, _nrargs) \
364 .event_func = __event_probe__compat_syscall_exit_##_template, \
365 .nrargs = (_nrargs), \
366 .fields = __event_fields___compat_syscall_exit_##_template, \
367 .desc = &__event_desc___compat_syscall_exit_##_name, \
370 /* Event compat syscall exit table */
371 const struct trace_syscall_entry compat_sc_exit_table
[] = {
372 #include <instrumentation/syscalls/headers/compat_syscalls_integers.h>
373 #include <instrumentation/syscalls/headers/compat_syscalls_pointers.h>
378 #undef CREATE_SYSCALL_TABLE
380 struct lttng_syscall_filter
{
381 DECLARE_BITMAP(sc_entry
, NR_syscalls
);
382 DECLARE_BITMAP(sc_exit
, NR_syscalls
);
383 DECLARE_BITMAP(sc_compat_entry
, NR_compat_syscalls
);
384 DECLARE_BITMAP(sc_compat_exit
, NR_compat_syscalls
);
387 static void syscall_entry_event_unknown(struct hlist_head
*unknown_action_list_head
,
388 struct pt_regs
*regs
, long id
)
390 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
391 struct lttng_kernel_event_common_private
*event_priv
;
393 lttng_syscall_get_arguments(current
, regs
, args
);
394 lttng_hlist_for_each_entry_rcu(event_priv
, unknown_action_list_head
, u
.syscall
.node
) {
395 if (unlikely(in_compat_syscall()))
396 __event_probe__compat_syscall_entry_unknown(event_priv
->pub
, id
, args
);
398 __event_probe__syscall_entry_unknown(event_priv
->pub
, id
, args
);
402 static __always_inline
403 void syscall_entry_event_call_func(struct hlist_head
*action_list
,
404 void *func
, unsigned int nrargs
,
405 struct pt_regs
*regs
)
407 struct lttng_kernel_event_common_private
*event_priv
;
412 void (*fptr
)(void *__data
) = func
;
414 lttng_hlist_for_each_entry_rcu(event_priv
, action_list
, u
.syscall
.node
)
415 fptr(event_priv
->pub
);
420 void (*fptr
)(void *__data
, unsigned long arg0
) = func
;
421 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
423 lttng_syscall_get_arguments(current
, regs
, args
);
424 lttng_hlist_for_each_entry_rcu(event_priv
, action_list
, u
.syscall
.node
)
425 fptr(event_priv
->pub
, args
[0]);
430 void (*fptr
)(void *__data
,
432 unsigned long arg1
) = func
;
433 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
435 lttng_syscall_get_arguments(current
, regs
, args
);
436 lttng_hlist_for_each_entry_rcu(event_priv
, action_list
, u
.syscall
.node
)
437 fptr(event_priv
->pub
, args
[0], args
[1]);
442 void (*fptr
)(void *__data
,
445 unsigned long arg2
) = func
;
446 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
448 lttng_syscall_get_arguments(current
, regs
, args
);
449 lttng_hlist_for_each_entry_rcu(event_priv
, action_list
, u
.syscall
.node
)
450 fptr(event_priv
->pub
, args
[0], args
[1], args
[2]);
455 void (*fptr
)(void *__data
,
459 unsigned long arg3
) = func
;
460 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
462 lttng_syscall_get_arguments(current
, regs
, args
);
463 lttng_hlist_for_each_entry_rcu(event_priv
, action_list
, u
.syscall
.node
)
464 fptr(event_priv
->pub
, args
[0], args
[1], args
[2], args
[3]);
469 void (*fptr
)(void *__data
,
474 unsigned long arg4
) = func
;
475 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
477 lttng_syscall_get_arguments(current
, regs
, args
);
478 lttng_hlist_for_each_entry_rcu(event_priv
, action_list
, u
.syscall
.node
)
479 fptr(event_priv
->pub
, args
[0], args
[1], args
[2], args
[3], args
[4]);
484 void (*fptr
)(void *__data
,
490 unsigned long arg5
) = 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 fptr(event_priv
->pub
, args
[0], args
[1], args
[2],
496 args
[3], args
[4], args
[5]);
504 void syscall_entry_event_probe(void *__data
, struct pt_regs
*regs
, long id
)
506 struct lttng_channel
*chan
= __data
;
507 struct hlist_head
*action_list
, *unknown_action_list
;
508 const struct trace_syscall_entry
*table
, *entry
;
511 if (unlikely(in_compat_syscall())) {
512 struct lttng_syscall_filter
*filter
= chan
->sc_filter
;
514 if (id
< 0 || id
>= NR_compat_syscalls
515 || (!READ_ONCE(chan
->syscall_all_entry
) && !test_bit(id
, filter
->sc_compat_entry
))) {
516 /* System call filtered out. */
519 table
= compat_sc_table
;
520 table_len
= ARRAY_SIZE(compat_sc_table
);
521 unknown_action_list
= &chan
->sc_compat_unknown
;
523 struct lttng_syscall_filter
*filter
= chan
->sc_filter
;
525 if (id
< 0 || id
>= NR_syscalls
526 || (!READ_ONCE(chan
->syscall_all_entry
) && !test_bit(id
, filter
->sc_entry
))) {
527 /* System call filtered out. */
531 table_len
= ARRAY_SIZE(sc_table
);
532 unknown_action_list
= &chan
->sc_unknown
;
534 if (unlikely(id
< 0 || id
>= table_len
)) {
535 syscall_entry_event_unknown(unknown_action_list
, regs
, id
);
540 if (!entry
->event_func
) {
541 syscall_entry_event_unknown(unknown_action_list
, regs
, id
);
545 if (unlikely(in_compat_syscall())) {
546 action_list
= &chan
->compat_sc_table
[id
];
548 action_list
= &chan
->sc_table
[id
];
550 if (unlikely(hlist_empty(action_list
)))
553 syscall_entry_event_call_func(action_list
, entry
->event_func
, entry
->nrargs
, regs
);
556 void syscall_entry_event_notifier_probe(void *__data
, struct pt_regs
*regs
,
559 struct lttng_event_notifier_group
*group
= __data
;
560 const struct trace_syscall_entry
*table
, *entry
;
561 struct hlist_head
*dispatch_list
, *unknown_dispatch_list
;
564 if (unlikely(in_compat_syscall())) {
565 struct lttng_syscall_filter
*filter
= group
->sc_filter
;
567 if (id
< 0 || id
>= NR_compat_syscalls
568 || (!READ_ONCE(group
->syscall_all_entry
) &&
569 !test_bit(id
, filter
->sc_compat_entry
))) {
570 /* System call filtered out. */
573 table
= compat_sc_table
;
574 table_len
= ARRAY_SIZE(compat_sc_table
);
575 unknown_dispatch_list
= &group
->event_notifier_compat_unknown_syscall_dispatch
;
577 struct lttng_syscall_filter
*filter
= group
->sc_filter
;
579 if (id
< 0 || id
>= NR_syscalls
580 || (!READ_ONCE(group
->syscall_all_entry
) &&
581 !test_bit(id
, filter
->sc_entry
))) {
582 /* System call filtered out. */
586 table_len
= ARRAY_SIZE(sc_table
);
587 unknown_dispatch_list
= &group
->event_notifier_unknown_syscall_dispatch
;
589 /* Check if the syscall id is out of bound. */
590 if (unlikely(id
< 0 || id
>= table_len
)) {
591 syscall_entry_event_unknown(unknown_dispatch_list
,
597 if (!entry
->event_func
) {
598 syscall_entry_event_unknown(unknown_dispatch_list
,
603 if (unlikely(in_compat_syscall())) {
604 dispatch_list
= &group
->event_notifier_compat_syscall_dispatch
[id
];
606 dispatch_list
= &group
->event_notifier_syscall_dispatch
[id
];
608 if (unlikely(hlist_empty(dispatch_list
)))
611 syscall_entry_event_call_func(dispatch_list
,
612 entry
->event_func
, entry
->nrargs
, regs
);
615 static void syscall_exit_event_unknown(struct hlist_head
*unknown_action_list_head
,
616 struct pt_regs
*regs
, long id
, long ret
)
618 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
619 struct lttng_kernel_event_common_private
*event_priv
;
621 lttng_syscall_get_arguments(current
, regs
, args
);
622 lttng_hlist_for_each_entry_rcu(event_priv
, unknown_action_list_head
, u
.syscall
.node
) {
623 if (unlikely(in_compat_syscall()))
624 __event_probe__compat_syscall_exit_unknown(event_priv
->pub
, id
, ret
,
627 __event_probe__syscall_exit_unknown(event_priv
->pub
, id
, ret
, args
);
631 static __always_inline
632 void syscall_exit_event_call_func(struct hlist_head
*action_list
,
633 void *func
, unsigned int nrargs
,
634 struct pt_regs
*regs
, long ret
)
636 struct lttng_kernel_event_common_private
*event_priv
;
641 void (*fptr
)(void *__data
, long ret
) = func
;
643 lttng_hlist_for_each_entry_rcu(event_priv
, action_list
, u
.syscall
.node
)
644 fptr(event_priv
->pub
, ret
);
649 void (*fptr
)(void *__data
,
651 unsigned long arg0
) = func
;
652 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
654 lttng_syscall_get_arguments(current
, regs
, args
);
655 lttng_hlist_for_each_entry_rcu(event_priv
, action_list
, u
.syscall
.node
)
656 fptr(event_priv
->pub
, ret
, args
[0]);
661 void (*fptr
)(void *__data
,
664 unsigned long arg1
) = func
;
665 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
667 lttng_syscall_get_arguments(current
, regs
, args
);
668 lttng_hlist_for_each_entry_rcu(event_priv
, action_list
, u
.syscall
.node
)
669 fptr(event_priv
->pub
, ret
, args
[0], args
[1]);
674 void (*fptr
)(void *__data
,
678 unsigned long arg2
) = func
;
679 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
681 lttng_syscall_get_arguments(current
, regs
, args
);
682 lttng_hlist_for_each_entry_rcu(event_priv
, action_list
, u
.syscall
.node
)
683 fptr(event_priv
->pub
, ret
, args
[0], args
[1], args
[2]);
688 void (*fptr
)(void *__data
,
693 unsigned long arg3
) = func
;
694 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
696 lttng_syscall_get_arguments(current
, regs
, args
);
697 lttng_hlist_for_each_entry_rcu(event_priv
, action_list
, u
.syscall
.node
)
698 fptr(event_priv
->pub
, ret
, args
[0], args
[1], args
[2], args
[3]);
703 void (*fptr
)(void *__data
,
709 unsigned long arg4
) = func
;
710 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
712 lttng_syscall_get_arguments(current
, regs
, args
);
713 lttng_hlist_for_each_entry_rcu(event_priv
, action_list
, u
.syscall
.node
)
714 fptr(event_priv
->pub
, ret
, args
[0], args
[1], args
[2], args
[3], args
[4]);
719 void (*fptr
)(void *__data
,
726 unsigned long arg5
) = func
;
727 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
729 lttng_syscall_get_arguments(current
, regs
, args
);
730 lttng_hlist_for_each_entry_rcu(event_priv
, action_list
, u
.syscall
.node
)
731 fptr(event_priv
->pub
, ret
, args
[0], args
[1], args
[2],
732 args
[3], args
[4], args
[5]);
740 void syscall_exit_event_probe(void *__data
, struct pt_regs
*regs
, long ret
)
742 struct lttng_channel
*chan
= __data
;
743 struct hlist_head
*action_list
, *unknown_action_list
;
744 const struct trace_syscall_entry
*table
, *entry
;
748 id
= syscall_get_nr(current
, regs
);
750 if (unlikely(in_compat_syscall())) {
751 struct lttng_syscall_filter
*filter
= chan
->sc_filter
;
753 if (id
< 0 || id
>= NR_compat_syscalls
754 || (!READ_ONCE(chan
->syscall_all_exit
) && !test_bit(id
, filter
->sc_compat_exit
))) {
755 /* System call filtered out. */
758 table
= compat_sc_exit_table
;
759 table_len
= ARRAY_SIZE(compat_sc_exit_table
);
760 unknown_action_list
= &chan
->compat_sc_exit_unknown
;
762 struct lttng_syscall_filter
*filter
= chan
->sc_filter
;
764 if (id
< 0 || id
>= NR_syscalls
765 || (!READ_ONCE(chan
->syscall_all_exit
) && !test_bit(id
, filter
->sc_exit
))) {
766 /* System call filtered out. */
769 table
= sc_exit_table
;
770 table_len
= ARRAY_SIZE(sc_exit_table
);
771 unknown_action_list
= &chan
->sc_exit_unknown
;
773 if (unlikely(id
< 0 || id
>= table_len
)) {
774 syscall_exit_event_unknown(unknown_action_list
, regs
, id
, ret
);
779 if (!entry
->event_func
) {
780 syscall_exit_event_unknown(unknown_action_list
, regs
, id
, ret
);
784 if (unlikely(in_compat_syscall())) {
785 action_list
= &chan
->compat_sc_exit_table
[id
];
787 action_list
= &chan
->sc_exit_table
[id
];
789 if (unlikely(hlist_empty(action_list
)))
792 syscall_exit_event_call_func(action_list
, entry
->event_func
, entry
->nrargs
,
797 void syscall_exit_event_notifier_probe(void *__data
, struct pt_regs
*regs
,
800 struct lttng_event_notifier_group
*group
= __data
;
801 const struct trace_syscall_entry
*table
, *entry
;
802 struct hlist_head
*dispatch_list
, *unknown_dispatch_list
;
806 id
= syscall_get_nr(current
, regs
);
808 if (unlikely(in_compat_syscall())) {
809 struct lttng_syscall_filter
*filter
= group
->sc_filter
;
811 if (id
< 0 || id
>= NR_compat_syscalls
812 || (!READ_ONCE(group
->syscall_all_exit
) &&
813 !test_bit(id
, filter
->sc_compat_exit
))) {
814 /* System call filtered out. */
817 table
= compat_sc_exit_table
;
818 table_len
= ARRAY_SIZE(compat_sc_exit_table
);
819 unknown_dispatch_list
= &group
->event_notifier_exit_compat_unknown_syscall_dispatch
;
821 struct lttng_syscall_filter
*filter
= group
->sc_filter
;
823 if (id
< 0 || id
>= NR_syscalls
824 || (!READ_ONCE(group
->syscall_all_exit
) &&
825 !test_bit(id
, filter
->sc_exit
))) {
826 /* System call filtered out. */
829 table
= sc_exit_table
;
830 table_len
= ARRAY_SIZE(sc_exit_table
);
831 unknown_dispatch_list
= &group
->event_notifier_exit_unknown_syscall_dispatch
;
833 /* Check if the syscall id is out of bound. */
834 if (unlikely(id
< 0 || id
>= table_len
)) {
835 syscall_exit_event_unknown(unknown_dispatch_list
,
841 if (!entry
->event_func
) {
842 syscall_entry_event_unknown(unknown_dispatch_list
,
847 if (unlikely(in_compat_syscall())) {
848 dispatch_list
= &group
->event_notifier_exit_compat_syscall_dispatch
[id
];
850 dispatch_list
= &group
->event_notifier_exit_syscall_dispatch
[id
];
852 if (unlikely(hlist_empty(dispatch_list
)))
855 syscall_exit_event_call_func(dispatch_list
,
856 entry
->event_func
, entry
->nrargs
, regs
, ret
);
859 * noinline to diminish caller stack size.
860 * Should be called with sessions lock held.
863 int lttng_create_syscall_event_if_missing(const struct trace_syscall_entry
*table
, size_t table_len
,
864 struct hlist_head
*chan_table
, struct lttng_event_enabler
*event_enabler
,
867 struct lttng_channel
*chan
= event_enabler
->chan
;
868 struct lttng_session
*session
= chan
->session
;
871 /* Allocate events for each syscall matching enabler, insert into table */
872 for (i
= 0; i
< table_len
; i
++) {
873 const struct lttng_kernel_event_desc
*desc
= table
[i
].desc
;
874 struct lttng_kernel_abi_event ev
;
875 struct lttng_kernel_event_recorder_private
*event_recorder_priv
;
876 struct lttng_kernel_event_recorder
*event_recorder
;
877 struct hlist_head
*head
;
881 /* Unknown syscall */
884 if (lttng_desc_match_enabler(desc
,
885 lttng_event_enabler_as_enabler(event_enabler
)) <= 0)
888 * Check if already created.
890 head
= utils_borrow_hash_table_bucket(
891 session
->events_ht
.table
, LTTNG_EVENT_HT_SIZE
,
893 lttng_hlist_for_each_entry(event_recorder_priv
, head
, hlist
) {
894 if (event_recorder_priv
->parent
.desc
== desc
895 && event_recorder_priv
->pub
->chan
== event_enabler
->chan
)
901 /* We need to create an event for this syscall/enabler. */
902 memset(&ev
, 0, sizeof(ev
));
905 ev
.u
.syscall
.entryexit
= LTTNG_KERNEL_ABI_SYSCALL_ENTRY
;
906 ev
.u
.syscall
.abi
= LTTNG_KERNEL_ABI_SYSCALL_ABI_NATIVE
;
909 ev
.u
.syscall
.entryexit
= LTTNG_KERNEL_ABI_SYSCALL_EXIT
;
910 ev
.u
.syscall
.abi
= LTTNG_KERNEL_ABI_SYSCALL_ABI_NATIVE
;
912 case SC_TYPE_COMPAT_ENTRY
:
913 ev
.u
.syscall
.entryexit
= LTTNG_KERNEL_ABI_SYSCALL_ENTRY
;
914 ev
.u
.syscall
.abi
= LTTNG_KERNEL_ABI_SYSCALL_ABI_COMPAT
;
916 case SC_TYPE_COMPAT_EXIT
:
917 ev
.u
.syscall
.entryexit
= LTTNG_KERNEL_ABI_SYSCALL_EXIT
;
918 ev
.u
.syscall
.abi
= LTTNG_KERNEL_ABI_SYSCALL_ABI_COMPAT
;
921 strncpy(ev
.name
, desc
->event_name
, LTTNG_KERNEL_ABI_SYM_NAME_LEN
- 1);
922 ev
.name
[LTTNG_KERNEL_ABI_SYM_NAME_LEN
- 1] = '\0';
923 ev
.instrumentation
= LTTNG_KERNEL_ABI_SYSCALL
;
924 event_recorder
= _lttng_kernel_event_recorder_create(chan
, &ev
, desc
, ev
.instrumentation
);
925 WARN_ON_ONCE(!event_recorder
);
926 if (IS_ERR(event_recorder
)) {
928 * If something goes wrong in event registration
929 * after the first one, we have no choice but to
930 * leave the previous events in there, until
931 * deleted by session teardown.
933 return PTR_ERR(event_recorder
);
935 hlist_add_head(&event_recorder
->priv
->parent
.u
.syscall
.node
, &chan_table
[i
]);
941 * Should be called with sessions lock held.
943 int lttng_syscalls_register_event(struct lttng_event_enabler
*event_enabler
)
945 struct lttng_channel
*chan
= event_enabler
->chan
;
946 struct lttng_kernel_abi_event ev
;
949 wrapper_vmalloc_sync_mappings();
951 if (!chan
->sc_table
) {
952 /* create syscall table mapping syscall to events */
953 chan
->sc_table
= kzalloc(sizeof(struct lttng_kernel_event_recorder
*)
954 * ARRAY_SIZE(sc_table
), GFP_KERNEL
);
958 if (!chan
->sc_exit_table
) {
959 /* create syscall table mapping syscall to events */
960 chan
->sc_exit_table
= kzalloc(sizeof(struct lttng_kernel_event_recorder
*)
961 * ARRAY_SIZE(sc_exit_table
), GFP_KERNEL
);
962 if (!chan
->sc_exit_table
)
968 if (!chan
->compat_sc_table
) {
969 /* create syscall table mapping compat syscall to events */
970 chan
->compat_sc_table
= kzalloc(sizeof(struct lttng_kernel_event_recorder
*)
971 * ARRAY_SIZE(compat_sc_table
), GFP_KERNEL
);
972 if (!chan
->compat_sc_table
)
976 if (!chan
->compat_sc_exit_table
) {
977 /* create syscall table mapping compat syscall to events */
978 chan
->compat_sc_exit_table
= kzalloc(sizeof(struct lttng_kernel_event_recorder
*)
979 * ARRAY_SIZE(compat_sc_exit_table
), GFP_KERNEL
);
980 if (!chan
->compat_sc_exit_table
)
984 if (hlist_empty(&chan
->sc_unknown
)) {
985 const struct lttng_kernel_event_desc
*desc
=
986 &__event_desc___syscall_entry_unknown
;
987 struct lttng_kernel_event_recorder
*event_recorder
;
989 memset(&ev
, 0, sizeof(ev
));
990 strncpy(ev
.name
, desc
->event_name
, LTTNG_KERNEL_ABI_SYM_NAME_LEN
);
991 ev
.name
[LTTNG_KERNEL_ABI_SYM_NAME_LEN
- 1] = '\0';
992 ev
.instrumentation
= LTTNG_KERNEL_ABI_SYSCALL
;
993 ev
.u
.syscall
.entryexit
= LTTNG_KERNEL_ABI_SYSCALL_ENTRY
;
994 ev
.u
.syscall
.abi
= LTTNG_KERNEL_ABI_SYSCALL_ABI_NATIVE
;
995 event_recorder
= _lttng_kernel_event_recorder_create(chan
, &ev
, desc
,
997 WARN_ON_ONCE(!event_recorder
);
998 if (IS_ERR(event_recorder
)) {
999 return PTR_ERR(event_recorder
);
1001 hlist_add_head(&event_recorder
->priv
->parent
.u
.syscall
.node
, &chan
->sc_unknown
);
1004 if (hlist_empty(&chan
->sc_compat_unknown
)) {
1005 const struct lttng_kernel_event_desc
*desc
=
1006 &__event_desc___compat_syscall_entry_unknown
;
1007 struct lttng_kernel_event_recorder
*event_recorder
;
1009 memset(&ev
, 0, sizeof(ev
));
1010 strncpy(ev
.name
, desc
->event_name
, LTTNG_KERNEL_ABI_SYM_NAME_LEN
);
1011 ev
.name
[LTTNG_KERNEL_ABI_SYM_NAME_LEN
- 1] = '\0';
1012 ev
.instrumentation
= LTTNG_KERNEL_ABI_SYSCALL
;
1013 ev
.u
.syscall
.entryexit
= LTTNG_KERNEL_ABI_SYSCALL_ENTRY
;
1014 ev
.u
.syscall
.abi
= LTTNG_KERNEL_ABI_SYSCALL_ABI_COMPAT
;
1015 event_recorder
= _lttng_kernel_event_recorder_create(chan
, &ev
, desc
,
1016 ev
.instrumentation
);
1017 WARN_ON_ONCE(!event_recorder
);
1018 if (IS_ERR(event_recorder
)) {
1019 return PTR_ERR(event_recorder
);
1021 hlist_add_head(&event_recorder
->priv
->parent
.u
.syscall
.node
, &chan
->sc_compat_unknown
);
1024 if (hlist_empty(&chan
->compat_sc_exit_unknown
)) {
1025 const struct lttng_kernel_event_desc
*desc
=
1026 &__event_desc___compat_syscall_exit_unknown
;
1027 struct lttng_kernel_event_recorder
*event_recorder
;
1029 memset(&ev
, 0, sizeof(ev
));
1030 strncpy(ev
.name
, desc
->event_name
, LTTNG_KERNEL_ABI_SYM_NAME_LEN
);
1031 ev
.name
[LTTNG_KERNEL_ABI_SYM_NAME_LEN
- 1] = '\0';
1032 ev
.instrumentation
= LTTNG_KERNEL_ABI_SYSCALL
;
1033 ev
.u
.syscall
.entryexit
= LTTNG_KERNEL_ABI_SYSCALL_EXIT
;
1034 ev
.u
.syscall
.abi
= LTTNG_KERNEL_ABI_SYSCALL_ABI_COMPAT
;
1035 event_recorder
= _lttng_kernel_event_recorder_create(chan
, &ev
, desc
,
1036 ev
.instrumentation
);
1037 WARN_ON_ONCE(!event_recorder
);
1038 if (IS_ERR(event_recorder
)) {
1039 return PTR_ERR(event_recorder
);
1041 hlist_add_head(&event_recorder
->priv
->parent
.u
.syscall
.node
, &chan
->compat_sc_exit_unknown
);
1044 if (hlist_empty(&chan
->sc_exit_unknown
)) {
1045 const struct lttng_kernel_event_desc
*desc
=
1046 &__event_desc___syscall_exit_unknown
;
1047 struct lttng_kernel_event_recorder
*event_recorder
;
1049 memset(&ev
, 0, sizeof(ev
));
1050 strncpy(ev
.name
, desc
->event_name
, LTTNG_KERNEL_ABI_SYM_NAME_LEN
);
1051 ev
.name
[LTTNG_KERNEL_ABI_SYM_NAME_LEN
- 1] = '\0';
1052 ev
.instrumentation
= LTTNG_KERNEL_ABI_SYSCALL
;
1053 ev
.u
.syscall
.entryexit
= LTTNG_KERNEL_ABI_SYSCALL_EXIT
;
1054 ev
.u
.syscall
.abi
= LTTNG_KERNEL_ABI_SYSCALL_ABI_NATIVE
;
1055 event_recorder
= _lttng_kernel_event_recorder_create(chan
, &ev
, desc
,
1056 ev
.instrumentation
);
1057 WARN_ON_ONCE(!event_recorder
);
1058 if (IS_ERR(event_recorder
)) {
1059 return PTR_ERR(event_recorder
);
1061 hlist_add_head(&event_recorder
->priv
->parent
.u
.syscall
.node
, &chan
->sc_exit_unknown
);
1064 ret
= lttng_create_syscall_event_if_missing(sc_table
, ARRAY_SIZE(sc_table
),
1065 chan
->sc_table
, event_enabler
, SC_TYPE_ENTRY
);
1068 ret
= lttng_create_syscall_event_if_missing(sc_exit_table
, ARRAY_SIZE(sc_exit_table
),
1069 chan
->sc_exit_table
, event_enabler
, SC_TYPE_EXIT
);
1073 #ifdef CONFIG_COMPAT
1074 ret
= lttng_create_syscall_event_if_missing(compat_sc_table
, ARRAY_SIZE(compat_sc_table
),
1075 chan
->compat_sc_table
, event_enabler
, SC_TYPE_COMPAT_ENTRY
);
1078 ret
= lttng_create_syscall_event_if_missing(compat_sc_exit_table
, ARRAY_SIZE(compat_sc_exit_table
),
1079 chan
->compat_sc_exit_table
, event_enabler
, SC_TYPE_COMPAT_EXIT
);
1084 if (!chan
->sc_filter
) {
1085 chan
->sc_filter
= kzalloc(sizeof(struct lttng_syscall_filter
),
1087 if (!chan
->sc_filter
)
1091 if (!chan
->sys_enter_registered
) {
1092 ret
= lttng_wrapper_tracepoint_probe_register("sys_enter",
1093 (void *) syscall_entry_event_probe
, chan
);
1096 chan
->sys_enter_registered
= 1;
1099 * We change the name of sys_exit tracepoint due to namespace
1100 * conflict with sys_exit syscall entry.
1102 if (!chan
->sys_exit_registered
) {
1103 ret
= lttng_wrapper_tracepoint_probe_register("sys_exit",
1104 (void *) syscall_exit_event_probe
, chan
);
1106 WARN_ON_ONCE(lttng_wrapper_tracepoint_probe_unregister("sys_enter",
1107 (void *) syscall_entry_event_probe
, chan
));
1110 chan
->sys_exit_registered
= 1;
1116 * Should be called with sessions lock held.
1118 int lttng_syscalls_register_event_notifier(
1119 struct lttng_event_notifier_enabler
*event_notifier_enabler
)
1121 struct lttng_event_notifier_group
*group
= event_notifier_enabler
->group
;
1125 wrapper_vmalloc_sync_mappings();
1127 if (!group
->event_notifier_syscall_dispatch
) {
1128 group
->event_notifier_syscall_dispatch
=
1129 kzalloc(sizeof(struct hlist_head
) * ARRAY_SIZE(sc_table
),
1131 if (!group
->event_notifier_syscall_dispatch
)
1134 /* Initialize all list_head */
1135 for (i
= 0; i
< ARRAY_SIZE(sc_table
); i
++)
1136 INIT_HLIST_HEAD(&group
->event_notifier_syscall_dispatch
[i
]);
1138 /* Init the unknown syscall notifier list. */
1139 INIT_HLIST_HEAD(&group
->event_notifier_unknown_syscall_dispatch
);
1142 if (!group
->event_notifier_exit_syscall_dispatch
) {
1143 group
->event_notifier_exit_syscall_dispatch
=
1144 kzalloc(sizeof(struct hlist_head
) * ARRAY_SIZE(sc_table
),
1146 if (!group
->event_notifier_exit_syscall_dispatch
)
1149 /* Initialize all list_head */
1150 for (i
= 0; i
< ARRAY_SIZE(sc_table
); i
++)
1151 INIT_HLIST_HEAD(&group
->event_notifier_exit_syscall_dispatch
[i
]);
1153 /* Init the unknown exit syscall notifier list. */
1154 INIT_HLIST_HEAD(&group
->event_notifier_exit_unknown_syscall_dispatch
);
1157 #ifdef CONFIG_COMPAT
1158 if (!group
->event_notifier_compat_syscall_dispatch
) {
1159 group
->event_notifier_compat_syscall_dispatch
=
1160 kzalloc(sizeof(struct hlist_head
) * ARRAY_SIZE(compat_sc_table
),
1162 if (!group
->event_notifier_syscall_dispatch
)
1165 /* Initialize all list_head */
1166 for (i
= 0; i
< ARRAY_SIZE(compat_sc_table
); i
++)
1167 INIT_HLIST_HEAD(&group
->event_notifier_compat_syscall_dispatch
[i
]);
1169 /* Init the unknown syscall notifier list. */
1170 INIT_HLIST_HEAD(&group
->event_notifier_compat_unknown_syscall_dispatch
);
1173 if (!group
->event_notifier_exit_compat_syscall_dispatch
) {
1174 group
->event_notifier_exit_compat_syscall_dispatch
=
1175 kzalloc(sizeof(struct hlist_head
) * ARRAY_SIZE(compat_sc_exit_table
),
1177 if (!group
->event_notifier_exit_syscall_dispatch
)
1180 /* Initialize all list_head */
1181 for (i
= 0; i
< ARRAY_SIZE(compat_sc_exit_table
); i
++)
1182 INIT_HLIST_HEAD(&group
->event_notifier_exit_compat_syscall_dispatch
[i
]);
1184 /* Init the unknown exit syscall notifier list. */
1185 INIT_HLIST_HEAD(&group
->event_notifier_exit_compat_unknown_syscall_dispatch
);
1189 if (!group
->sc_filter
) {
1190 group
->sc_filter
= kzalloc(sizeof(struct lttng_syscall_filter
),
1192 if (!group
->sc_filter
)
1196 if (!group
->sys_enter_registered
) {
1197 ret
= lttng_wrapper_tracepoint_probe_register("sys_enter",
1198 (void *) syscall_entry_event_notifier_probe
, group
);
1201 group
->sys_enter_registered
= 1;
1204 if (!group
->sys_exit_registered
) {
1205 ret
= lttng_wrapper_tracepoint_probe_register("sys_exit",
1206 (void *) syscall_exit_event_notifier_probe
, group
);
1208 WARN_ON_ONCE(lttng_wrapper_tracepoint_probe_unregister("sys_enter",
1209 (void *) syscall_entry_event_notifier_probe
, group
));
1212 group
->sys_exit_registered
= 1;
1219 int create_unknown_event_notifier(
1220 struct lttng_event_notifier_enabler
*event_notifier_enabler
,
1223 struct lttng_kernel_event_notifier_private
*event_notifier_priv
;
1224 struct lttng_kernel_event_notifier
*event_notifier
;
1225 const struct lttng_kernel_event_desc
*desc
;
1226 struct lttng_event_notifier_group
*group
= event_notifier_enabler
->group
;
1227 struct lttng_kernel_abi_event_notifier event_notifier_param
;
1228 uint64_t user_token
= event_notifier_enabler
->base
.user_token
;
1229 uint64_t error_counter_index
= event_notifier_enabler
->error_counter_index
;
1230 struct lttng_enabler
*base_enabler
= lttng_event_notifier_enabler_as_enabler(
1231 event_notifier_enabler
);
1232 struct hlist_head
*unknown_dispatch_list
;
1235 enum lttng_kernel_abi_syscall_abi abi
;
1236 enum lttng_kernel_abi_syscall_entryexit entryexit
;
1237 struct hlist_head
*head
;
1241 desc
= &__event_desc___syscall_entry_unknown
;
1242 unknown_dispatch_list
= &group
->event_notifier_unknown_syscall_dispatch
;
1243 entryexit
= LTTNG_KERNEL_ABI_SYSCALL_ENTRY
;
1244 abi
= LTTNG_KERNEL_ABI_SYSCALL_ABI_NATIVE
;
1247 desc
= &__event_desc___syscall_exit_unknown
;
1248 unknown_dispatch_list
= &group
->event_notifier_exit_unknown_syscall_dispatch
;
1249 entryexit
= LTTNG_KERNEL_ABI_SYSCALL_EXIT
;
1250 abi
= LTTNG_KERNEL_ABI_SYSCALL_ABI_NATIVE
;
1252 case SC_TYPE_COMPAT_ENTRY
:
1253 desc
= &__event_desc___compat_syscall_entry_unknown
;
1254 unknown_dispatch_list
= &group
->event_notifier_compat_unknown_syscall_dispatch
;
1255 entryexit
= LTTNG_KERNEL_ABI_SYSCALL_ENTRY
;
1256 abi
= LTTNG_KERNEL_ABI_SYSCALL_ABI_COMPAT
;
1258 case SC_TYPE_COMPAT_EXIT
:
1259 desc
= &__event_desc___compat_syscall_exit_unknown
;
1260 unknown_dispatch_list
= &group
->event_notifier_exit_compat_unknown_syscall_dispatch
;
1261 entryexit
= LTTNG_KERNEL_ABI_SYSCALL_EXIT
;
1262 abi
= LTTNG_KERNEL_ABI_SYSCALL_ABI_COMPAT
;
1269 * Check if already created.
1271 head
= utils_borrow_hash_table_bucket(group
->event_notifiers_ht
.table
,
1272 LTTNG_EVENT_NOTIFIER_HT_SIZE
, desc
->event_name
);
1273 lttng_hlist_for_each_entry(event_notifier_priv
, head
, hlist
) {
1274 if (event_notifier_priv
->parent
.desc
== desc
&&
1275 event_notifier_priv
->parent
.user_token
== base_enabler
->user_token
)
1281 memset(&event_notifier_param
, 0, sizeof(event_notifier_param
));
1282 strncat(event_notifier_param
.event
.name
, desc
->event_name
,
1283 LTTNG_KERNEL_ABI_SYM_NAME_LEN
- strlen(event_notifier_param
.event
.name
) - 1);
1285 event_notifier_param
.event
.name
[LTTNG_KERNEL_ABI_SYM_NAME_LEN
- 1] = '\0';
1287 event_notifier_param
.event
.instrumentation
= LTTNG_KERNEL_ABI_SYSCALL
;
1288 event_notifier_param
.event
.u
.syscall
.abi
= abi
;
1289 event_notifier_param
.event
.u
.syscall
.entryexit
= entryexit
;
1291 event_notifier
= _lttng_event_notifier_create(desc
, user_token
,
1292 error_counter_index
, group
, &event_notifier_param
,
1293 event_notifier_param
.event
.instrumentation
);
1294 if (IS_ERR(event_notifier
)) {
1295 printk(KERN_INFO
"Unable to create unknown notifier %s\n",
1301 hlist_add_head_rcu(&event_notifier
->priv
->parent
.u
.syscall
.node
, unknown_dispatch_list
);
1307 static int create_matching_event_notifiers(
1308 struct lttng_event_notifier_enabler
*event_notifier_enabler
,
1309 const struct trace_syscall_entry
*table
,
1310 size_t table_len
, enum sc_type type
)
1312 struct lttng_event_notifier_group
*group
= event_notifier_enabler
->group
;
1313 const struct lttng_kernel_event_desc
*desc
;
1314 uint64_t user_token
= event_notifier_enabler
->base
.user_token
;
1315 uint64_t error_counter_index
= event_notifier_enabler
->error_counter_index
;
1319 /* iterate over all syscall and create event_notifier that match */
1320 for (i
= 0; i
< table_len
; i
++) {
1321 struct lttng_kernel_event_notifier_private
*event_notifier_priv
;
1322 struct lttng_kernel_event_notifier
*event_notifier
;
1323 struct lttng_kernel_abi_event_notifier event_notifier_param
;
1324 struct hlist_head
*head
;
1327 desc
= table
[i
].desc
;
1329 /* Unknown syscall */
1333 if (!lttng_desc_match_enabler(desc
,
1334 lttng_event_notifier_enabler_as_enabler(event_notifier_enabler
)))
1338 * Check if already created.
1340 head
= utils_borrow_hash_table_bucket(group
->event_notifiers_ht
.table
,
1341 LTTNG_EVENT_NOTIFIER_HT_SIZE
, desc
->event_name
);
1342 lttng_hlist_for_each_entry(event_notifier_priv
, head
, hlist
) {
1343 if (event_notifier_priv
->parent
.desc
== desc
1344 && event_notifier_priv
->parent
.user_token
== event_notifier_enabler
->base
.user_token
)
1350 memset(&event_notifier_param
, 0, sizeof(event_notifier_param
));
1353 event_notifier_param
.event
.u
.syscall
.entryexit
= LTTNG_KERNEL_ABI_SYSCALL_ENTRY
;
1354 event_notifier_param
.event
.u
.syscall
.abi
= LTTNG_KERNEL_ABI_SYSCALL_ABI_NATIVE
;
1357 event_notifier_param
.event
.u
.syscall
.entryexit
= LTTNG_KERNEL_ABI_SYSCALL_EXIT
;
1358 event_notifier_param
.event
.u
.syscall
.abi
= LTTNG_KERNEL_ABI_SYSCALL_ABI_NATIVE
;
1360 case SC_TYPE_COMPAT_ENTRY
:
1361 event_notifier_param
.event
.u
.syscall
.entryexit
= LTTNG_KERNEL_ABI_SYSCALL_ENTRY
;
1362 event_notifier_param
.event
.u
.syscall
.abi
= LTTNG_KERNEL_ABI_SYSCALL_ABI_COMPAT
;
1364 case SC_TYPE_COMPAT_EXIT
:
1365 event_notifier_param
.event
.u
.syscall
.entryexit
= LTTNG_KERNEL_ABI_SYSCALL_EXIT
;
1366 event_notifier_param
.event
.u
.syscall
.abi
= LTTNG_KERNEL_ABI_SYSCALL_ABI_COMPAT
;
1369 strncat(event_notifier_param
.event
.name
, desc
->event_name
,
1370 LTTNG_KERNEL_ABI_SYM_NAME_LEN
- strlen(event_notifier_param
.event
.name
) - 1);
1371 event_notifier_param
.event
.name
[LTTNG_KERNEL_ABI_SYM_NAME_LEN
- 1] = '\0';
1372 event_notifier_param
.event
.instrumentation
= LTTNG_KERNEL_ABI_SYSCALL
;
1374 event_notifier
= _lttng_event_notifier_create(desc
, user_token
,
1375 error_counter_index
, group
, &event_notifier_param
,
1376 event_notifier_param
.event
.instrumentation
);
1377 if (IS_ERR(event_notifier
)) {
1378 printk(KERN_INFO
"Unable to create event_notifier %s\n",
1384 event_notifier
->priv
->parent
.u
.syscall
.syscall_id
= i
;
1392 int lttng_syscalls_create_matching_event_notifiers(
1393 struct lttng_event_notifier_enabler
*event_notifier_enabler
)
1396 struct lttng_enabler
*base_enabler
=
1397 lttng_event_notifier_enabler_as_enabler(event_notifier_enabler
);
1398 enum lttng_kernel_abi_syscall_entryexit entryexit
=
1399 base_enabler
->event_param
.u
.syscall
.entryexit
;
1401 if (entryexit
== LTTNG_KERNEL_ABI_SYSCALL_ENTRY
|| entryexit
== LTTNG_KERNEL_ABI_SYSCALL_ENTRYEXIT
) {
1402 ret
= create_matching_event_notifiers(event_notifier_enabler
,
1403 sc_table
, ARRAY_SIZE(sc_table
), SC_TYPE_ENTRY
);
1407 ret
= create_matching_event_notifiers(event_notifier_enabler
,
1408 compat_sc_table
, ARRAY_SIZE(compat_sc_table
),
1409 SC_TYPE_COMPAT_ENTRY
);
1413 ret
= create_unknown_event_notifier(event_notifier_enabler
,
1418 ret
= create_unknown_event_notifier(event_notifier_enabler
,
1419 SC_TYPE_COMPAT_ENTRY
);
1424 if (entryexit
== LTTNG_KERNEL_ABI_SYSCALL_EXIT
|| entryexit
== LTTNG_KERNEL_ABI_SYSCALL_ENTRYEXIT
) {
1425 ret
= create_matching_event_notifiers(event_notifier_enabler
,
1426 sc_exit_table
, ARRAY_SIZE(sc_exit_table
),
1431 ret
= create_unknown_event_notifier(event_notifier_enabler
,
1436 ret
= create_matching_event_notifiers(event_notifier_enabler
,
1437 compat_sc_exit_table
, ARRAY_SIZE(compat_sc_exit_table
),
1438 SC_TYPE_COMPAT_EXIT
);
1442 ret
= create_unknown_event_notifier(event_notifier_enabler
,
1443 SC_TYPE_COMPAT_EXIT
);
1453 * Unregister the syscall event_notifier probes from the callsites.
1455 int lttng_syscalls_unregister_event_notifier_group(
1456 struct lttng_event_notifier_group
*event_notifier_group
)
1461 * Only register the event_notifier probe on the `sys_enter` callsite for now.
1462 * At the moment, we don't think it's desirable to have one fired
1463 * event_notifier for the entry and one for the exit of a syscall.
1465 if (event_notifier_group
->sys_enter_registered
) {
1466 ret
= lttng_wrapper_tracepoint_probe_unregister("sys_enter",
1467 (void *) syscall_entry_event_notifier_probe
, event_notifier_group
);
1470 event_notifier_group
->sys_enter_registered
= 0;
1472 if (event_notifier_group
->sys_exit_registered
) {
1473 ret
= lttng_wrapper_tracepoint_probe_unregister("sys_exit",
1474 (void *) syscall_exit_event_notifier_probe
, event_notifier_group
);
1477 event_notifier_group
->sys_enter_registered
= 0;
1480 kfree(event_notifier_group
->event_notifier_syscall_dispatch
);
1481 kfree(event_notifier_group
->event_notifier_exit_syscall_dispatch
);
1482 #ifdef CONFIG_COMPAT
1483 kfree(event_notifier_group
->event_notifier_compat_syscall_dispatch
);
1484 kfree(event_notifier_group
->event_notifier_exit_compat_syscall_dispatch
);
1489 int lttng_syscalls_unregister_channel(struct lttng_channel
*chan
)
1493 if (!chan
->sc_table
)
1495 if (chan
->sys_enter_registered
) {
1496 ret
= lttng_wrapper_tracepoint_probe_unregister("sys_enter",
1497 (void *) syscall_entry_event_probe
, chan
);
1500 chan
->sys_enter_registered
= 0;
1502 if (chan
->sys_exit_registered
) {
1503 ret
= lttng_wrapper_tracepoint_probe_unregister("sys_exit",
1504 (void *) syscall_exit_event_probe
, chan
);
1507 chan
->sys_exit_registered
= 0;
1512 int lttng_syscalls_destroy_event(struct lttng_channel
*chan
)
1514 kfree(chan
->sc_table
);
1515 kfree(chan
->sc_exit_table
);
1516 #ifdef CONFIG_COMPAT
1517 kfree(chan
->compat_sc_table
);
1518 kfree(chan
->compat_sc_exit_table
);
1520 kfree(chan
->sc_filter
);
1525 int get_syscall_nr(const char *syscall_name
)
1527 int syscall_nr
= -1;
1530 for (i
= 0; i
< ARRAY_SIZE(sc_table
); i
++) {
1531 const struct trace_syscall_entry
*entry
;
1532 const char *it_name
;
1534 entry
= &sc_table
[i
];
1537 it_name
= entry
->desc
->event_name
;
1538 it_name
+= strlen(SYSCALL_ENTRY_STR
);
1539 if (!strcmp(syscall_name
, it_name
)) {
1548 int get_compat_syscall_nr(const char *syscall_name
)
1550 int syscall_nr
= -1;
1553 for (i
= 0; i
< ARRAY_SIZE(compat_sc_table
); i
++) {
1554 const struct trace_syscall_entry
*entry
;
1555 const char *it_name
;
1557 entry
= &compat_sc_table
[i
];
1560 it_name
= entry
->desc
->event_name
;
1561 it_name
+= strlen(COMPAT_SYSCALL_ENTRY_STR
);
1562 if (!strcmp(syscall_name
, it_name
)) {
1571 uint32_t get_sc_tables_len(void)
1573 return ARRAY_SIZE(sc_table
) + ARRAY_SIZE(compat_sc_table
);
1577 const char *get_syscall_name(const char *desc_name
,
1578 enum lttng_syscall_abi abi
,
1579 enum lttng_syscall_entryexit entryexit
)
1581 size_t prefix_len
= 0;
1584 switch (entryexit
) {
1585 case LTTNG_SYSCALL_ENTRY
:
1587 case LTTNG_SYSCALL_ABI_NATIVE
:
1588 prefix_len
= strlen(SYSCALL_ENTRY_STR
);
1590 case LTTNG_SYSCALL_ABI_COMPAT
:
1591 prefix_len
= strlen(COMPAT_SYSCALL_ENTRY_STR
);
1595 case LTTNG_SYSCALL_EXIT
:
1597 case LTTNG_SYSCALL_ABI_NATIVE
:
1598 prefix_len
= strlen(SYSCALL_EXIT_STR
);
1600 case LTTNG_SYSCALL_ABI_COMPAT
:
1601 prefix_len
= strlen(COMPAT_SYSCALL_EXIT_STR
);
1606 WARN_ON_ONCE(prefix_len
== 0);
1607 return desc_name
+ prefix_len
;
1611 int lttng_syscall_filter_enable(
1612 struct lttng_syscall_filter
*filter
,
1613 const char *desc_name
, enum lttng_syscall_abi abi
,
1614 enum lttng_syscall_entryexit entryexit
)
1616 const char *syscall_name
;
1617 unsigned long *bitmap
;
1620 syscall_name
= get_syscall_name(desc_name
, abi
, entryexit
);
1623 case LTTNG_SYSCALL_ABI_NATIVE
:
1624 syscall_nr
= get_syscall_nr(syscall_name
);
1626 case LTTNG_SYSCALL_ABI_COMPAT
:
1627 syscall_nr
= get_compat_syscall_nr(syscall_name
);
1635 switch (entryexit
) {
1636 case LTTNG_SYSCALL_ENTRY
:
1638 case LTTNG_SYSCALL_ABI_NATIVE
:
1639 bitmap
= filter
->sc_entry
;
1641 case LTTNG_SYSCALL_ABI_COMPAT
:
1642 bitmap
= filter
->sc_compat_entry
;
1648 case LTTNG_SYSCALL_EXIT
:
1650 case LTTNG_SYSCALL_ABI_NATIVE
:
1651 bitmap
= filter
->sc_exit
;
1653 case LTTNG_SYSCALL_ABI_COMPAT
:
1654 bitmap
= filter
->sc_compat_exit
;
1663 if (test_bit(syscall_nr
, bitmap
))
1665 bitmap_set(bitmap
, syscall_nr
, 1);
1669 int lttng_syscall_filter_enable_event_notifier(
1670 struct lttng_kernel_event_notifier
*event_notifier
)
1672 struct lttng_event_notifier_group
*group
= event_notifier
->priv
->group
;
1673 unsigned int syscall_id
= event_notifier
->priv
->parent
.u
.syscall
.syscall_id
;
1674 struct hlist_head
*dispatch_list
;
1677 WARN_ON_ONCE(event_notifier
->priv
->parent
.instrumentation
!= LTTNG_KERNEL_ABI_SYSCALL
);
1679 ret
= lttng_syscall_filter_enable(group
->sc_filter
,
1680 event_notifier
->priv
->parent
.desc
->event_name
,
1681 event_notifier
->priv
->parent
.u
.syscall
.abi
,
1682 event_notifier
->priv
->parent
.u
.syscall
.entryexit
);
1687 switch (event_notifier
->priv
->parent
.u
.syscall
.entryexit
) {
1688 case LTTNG_SYSCALL_ENTRY
:
1689 switch (event_notifier
->priv
->parent
.u
.syscall
.abi
) {
1690 case LTTNG_SYSCALL_ABI_NATIVE
:
1691 dispatch_list
= &group
->event_notifier_syscall_dispatch
[syscall_id
];
1693 case LTTNG_SYSCALL_ABI_COMPAT
:
1694 dispatch_list
= &group
->event_notifier_compat_syscall_dispatch
[syscall_id
];
1701 case LTTNG_SYSCALL_EXIT
:
1702 switch (event_notifier
->priv
->parent
.u
.syscall
.abi
) {
1703 case LTTNG_SYSCALL_ABI_NATIVE
:
1704 dispatch_list
= &group
->event_notifier_exit_syscall_dispatch
[syscall_id
];
1706 case LTTNG_SYSCALL_ABI_COMPAT
:
1707 dispatch_list
= &group
->event_notifier_exit_compat_syscall_dispatch
[syscall_id
];
1719 hlist_add_head_rcu(&event_notifier
->priv
->parent
.u
.syscall
.node
, dispatch_list
);
1725 int lttng_syscall_filter_enable_event(
1726 struct lttng_channel
*channel
,
1727 struct lttng_kernel_event_recorder
*event_recorder
)
1729 WARN_ON_ONCE(event_recorder
->priv
->parent
.instrumentation
!= LTTNG_KERNEL_ABI_SYSCALL
);
1731 return lttng_syscall_filter_enable(channel
->sc_filter
,
1732 event_recorder
->priv
->parent
.desc
->event_name
,
1733 event_recorder
->priv
->parent
.u
.syscall
.abi
,
1734 event_recorder
->priv
->parent
.u
.syscall
.entryexit
);
1738 int lttng_syscall_filter_disable(
1739 struct lttng_syscall_filter
*filter
,
1740 const char *desc_name
, enum lttng_syscall_abi abi
,
1741 enum lttng_syscall_entryexit entryexit
)
1743 const char *syscall_name
;
1744 unsigned long *bitmap
;
1747 syscall_name
= get_syscall_name(desc_name
, abi
, entryexit
);
1750 case LTTNG_SYSCALL_ABI_NATIVE
:
1751 syscall_nr
= get_syscall_nr(syscall_name
);
1753 case LTTNG_SYSCALL_ABI_COMPAT
:
1754 syscall_nr
= get_compat_syscall_nr(syscall_name
);
1762 switch (entryexit
) {
1763 case LTTNG_SYSCALL_ENTRY
:
1765 case LTTNG_SYSCALL_ABI_NATIVE
:
1766 bitmap
= filter
->sc_entry
;
1768 case LTTNG_SYSCALL_ABI_COMPAT
:
1769 bitmap
= filter
->sc_compat_entry
;
1775 case LTTNG_SYSCALL_EXIT
:
1777 case LTTNG_SYSCALL_ABI_NATIVE
:
1778 bitmap
= filter
->sc_exit
;
1780 case LTTNG_SYSCALL_ABI_COMPAT
:
1781 bitmap
= filter
->sc_compat_exit
;
1790 if (!test_bit(syscall_nr
, bitmap
))
1792 bitmap_clear(bitmap
, syscall_nr
, 1);
1797 int lttng_syscall_filter_disable_event_notifier(
1798 struct lttng_kernel_event_notifier
*event_notifier
)
1800 struct lttng_event_notifier_group
*group
= event_notifier
->priv
->group
;
1803 WARN_ON_ONCE(event_notifier
->priv
->parent
.instrumentation
!= LTTNG_KERNEL_ABI_SYSCALL
);
1805 ret
= lttng_syscall_filter_disable(group
->sc_filter
,
1806 event_notifier
->priv
->parent
.desc
->event_name
,
1807 event_notifier
->priv
->parent
.u
.syscall
.abi
,
1808 event_notifier
->priv
->parent
.u
.syscall
.entryexit
);
1809 WARN_ON_ONCE(ret
!= 0);
1811 hlist_del_rcu(&event_notifier
->priv
->parent
.u
.syscall
.node
);
1815 int lttng_syscall_filter_disable_event(
1816 struct lttng_channel
*channel
,
1817 struct lttng_kernel_event_recorder
*event_recorder
)
1819 return lttng_syscall_filter_disable(channel
->sc_filter
,
1820 event_recorder
->priv
->parent
.desc
->event_name
,
1821 event_recorder
->priv
->parent
.u
.syscall
.abi
,
1822 event_recorder
->priv
->parent
.u
.syscall
.entryexit
);
1826 const struct trace_syscall_entry
*syscall_list_get_entry(loff_t
*pos
)
1828 const struct trace_syscall_entry
*entry
;
1831 for (entry
= sc_table
;
1832 entry
< sc_table
+ ARRAY_SIZE(sc_table
);
1837 for (entry
= compat_sc_table
;
1838 entry
< compat_sc_table
+ ARRAY_SIZE(compat_sc_table
);
1848 void *syscall_list_start(struct seq_file
*m
, loff_t
*pos
)
1850 return (void *) syscall_list_get_entry(pos
);
1854 void *syscall_list_next(struct seq_file
*m
, void *p
, loff_t
*ppos
)
1857 return (void *) syscall_list_get_entry(ppos
);
1861 void syscall_list_stop(struct seq_file
*m
, void *p
)
1866 int get_sc_table(const struct trace_syscall_entry
*entry
,
1867 const struct trace_syscall_entry
**table
,
1868 unsigned int *bitness
)
1870 if (entry
>= sc_table
&& entry
< sc_table
+ ARRAY_SIZE(sc_table
)) {
1872 *bitness
= BITS_PER_LONG
;
1877 if (!(entry
>= compat_sc_table
1878 && entry
< compat_sc_table
+ ARRAY_SIZE(compat_sc_table
))) {
1884 *table
= compat_sc_table
;
1889 int syscall_list_show(struct seq_file
*m
, void *p
)
1891 const struct trace_syscall_entry
*table
, *entry
= p
;
1892 unsigned int bitness
;
1893 unsigned long index
;
1897 ret
= get_sc_table(entry
, &table
, &bitness
);
1902 if (table
== sc_table
) {
1903 index
= entry
- table
;
1904 name
= &entry
->desc
->event_name
[strlen(SYSCALL_ENTRY_STR
)];
1906 index
= (entry
- table
) + ARRAY_SIZE(sc_table
);
1907 name
= &entry
->desc
->event_name
[strlen(COMPAT_SYSCALL_ENTRY_STR
)];
1909 seq_printf(m
, "syscall { index = %lu; name = %s; bitness = %u; };\n",
1910 index
, name
, bitness
);
1915 const struct seq_operations lttng_syscall_list_seq_ops
= {
1916 .start
= syscall_list_start
,
1917 .next
= syscall_list_next
,
1918 .stop
= syscall_list_stop
,
1919 .show
= syscall_list_show
,
1923 int lttng_syscall_list_open(struct inode
*inode
, struct file
*file
)
1925 return seq_open(file
, <tng_syscall_list_seq_ops
);
1928 const struct file_operations lttng_syscall_list_fops
= {
1929 .owner
= THIS_MODULE
,
1930 .open
= lttng_syscall_list_open
,
1932 .llseek
= seq_lseek
,
1933 .release
= seq_release
,
1937 * A syscall is enabled if it is traced for either entry or exit.
1939 long lttng_channel_syscall_mask(struct lttng_channel
*channel
,
1940 struct lttng_kernel_abi_syscall_mask __user
*usyscall_mask
)
1942 uint32_t len
, sc_tables_len
, bitmask_len
;
1945 struct lttng_syscall_filter
*filter
;
1947 ret
= get_user(len
, &usyscall_mask
->len
);
1950 sc_tables_len
= get_sc_tables_len();
1951 bitmask_len
= ALIGN(sc_tables_len
, 8) >> 3;
1952 if (len
< sc_tables_len
) {
1953 return put_user(sc_tables_len
, &usyscall_mask
->len
);
1955 /* Array is large enough, we can copy array to user-space. */
1956 tmp_mask
= kzalloc(bitmask_len
, GFP_KERNEL
);
1959 filter
= channel
->sc_filter
;
1961 for (bit
= 0; bit
< ARRAY_SIZE(sc_table
); bit
++) {
1964 if (channel
->sc_table
) {
1965 if (!(READ_ONCE(channel
->syscall_all_entry
)
1966 || READ_ONCE(channel
->syscall_all_exit
)) && filter
)
1967 state
= test_bit(bit
, filter
->sc_entry
)
1968 || test_bit(bit
, filter
->sc_exit
);
1974 bt_bitfield_write_be(tmp_mask
, char, bit
, 1, state
);
1976 for (; bit
< sc_tables_len
; bit
++) {
1979 if (channel
->compat_sc_table
) {
1980 if (!(READ_ONCE(channel
->syscall_all_entry
)
1981 || READ_ONCE(channel
->syscall_all_exit
)) && filter
)
1982 state
= test_bit(bit
- ARRAY_SIZE(sc_table
),
1983 filter
->sc_compat_entry
)
1984 || test_bit(bit
- ARRAY_SIZE(sc_table
),
1985 filter
->sc_compat_exit
);
1991 bt_bitfield_write_be(tmp_mask
, char, bit
, 1, state
);
1993 if (copy_to_user(usyscall_mask
->mask
, tmp_mask
, bitmask_len
))
1999 int lttng_abi_syscall_list(void)
2001 struct file
*syscall_list_file
;
2004 file_fd
= lttng_get_unused_fd();
2010 syscall_list_file
= anon_inode_getfile("[lttng_syscall_list]",
2011 <tng_syscall_list_fops
,
2013 if (IS_ERR(syscall_list_file
)) {
2014 ret
= PTR_ERR(syscall_list_file
);
2017 ret
= lttng_syscall_list_fops
.open(NULL
, syscall_list_file
);
2020 fd_install(file_fd
, syscall_list_file
);
2024 fput(syscall_list_file
);
2026 put_unused_fd(file_fd
);