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_event_desc
*desc
;
298 const struct lttng_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_event
*event
;
397 lttng_syscall_get_arguments(current
, regs
, args
);
398 lttng_hlist_for_each_entry_rcu(event
, unknown_action_list_head
, u
.syscall
.node
) {
399 if (unlikely(in_compat_syscall()))
400 __event_probe__compat_syscall_entry_unknown(event
, id
, args
);
402 __event_probe__syscall_entry_unknown(event
, id
, args
);
406 static void syscall_entry_event_notifier_unknown(
407 struct hlist_head
*unknown_dispatch_list_head
,
408 struct pt_regs
*regs
, long id
)
410 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
411 struct lttng_event_notifier
*notifier
;
413 lttng_syscall_get_arguments(current
, regs
, args
);
414 lttng_hlist_for_each_entry_rcu(notifier
, unknown_dispatch_list_head
, u
.syscall
.node
) {
415 if (unlikely(in_compat_syscall()))
416 __event_notifier_probe__compat_syscall_entry_unknown(notifier
, id
, args
);
418 __event_notifier_probe__syscall_entry_unknown(notifier
, id
, args
);
422 static void syscall_exit_event_notifier_unknown(
423 struct hlist_head
*unknown_dispatch_list_head
,
424 struct pt_regs
*regs
, long id
, long ret
)
426 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
427 struct lttng_event_notifier
*notifier
;
429 lttng_syscall_get_arguments(current
, regs
, args
);
430 lttng_hlist_for_each_entry_rcu(notifier
, unknown_dispatch_list_head
, u
.syscall
.node
) {
431 if (unlikely(in_compat_syscall()))
432 __event_notifier_probe__compat_syscall_exit_unknown(notifier
, id
, ret
, args
);
434 __event_notifier_probe__syscall_exit_unknown(notifier
, id
, ret
, args
);
438 static __always_inline
439 void syscall_entry_call_func(struct hlist_head
*action_list
,
440 void *func
, unsigned int nrargs
,
441 struct pt_regs
*regs
)
443 struct lttng_event
*event
;
448 void (*fptr
)(void *__data
) = func
;
450 lttng_hlist_for_each_entry_rcu(event
, action_list
, u
.syscall
.node
)
456 void (*fptr
)(void *__data
, unsigned long arg0
) = func
;
457 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
459 lttng_syscall_get_arguments(current
, regs
, args
);
460 lttng_hlist_for_each_entry_rcu(event
, action_list
, u
.syscall
.node
)
461 fptr(event
, args
[0]);
466 void (*fptr
)(void *__data
,
468 unsigned long arg1
) = func
;
469 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
471 lttng_syscall_get_arguments(current
, regs
, args
);
472 lttng_hlist_for_each_entry_rcu(event
, action_list
, u
.syscall
.node
)
473 fptr(event
, args
[0], args
[1]);
478 void (*fptr
)(void *__data
,
481 unsigned long arg2
) = func
;
482 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
484 lttng_syscall_get_arguments(current
, regs
, args
);
485 lttng_hlist_for_each_entry_rcu(event
, action_list
, u
.syscall
.node
)
486 fptr(event
, args
[0], args
[1], args
[2]);
491 void (*fptr
)(void *__data
,
495 unsigned long arg3
) = func
;
496 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
498 lttng_syscall_get_arguments(current
, regs
, args
);
499 lttng_hlist_for_each_entry_rcu(event
, action_list
, u
.syscall
.node
)
500 fptr(event
, args
[0], args
[1], args
[2], args
[3]);
505 void (*fptr
)(void *__data
,
510 unsigned long arg4
) = func
;
511 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
513 lttng_syscall_get_arguments(current
, regs
, args
);
514 lttng_hlist_for_each_entry_rcu(event
, action_list
, u
.syscall
.node
)
515 fptr(event
, args
[0], args
[1], args
[2], args
[3], args
[4]);
520 void (*fptr
)(void *__data
,
526 unsigned long arg5
) = func
;
527 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
529 lttng_syscall_get_arguments(current
, regs
, args
);
530 lttng_hlist_for_each_entry_rcu(event
, action_list
, u
.syscall
.node
)
531 fptr(event
, args
[0], args
[1], args
[2],
532 args
[3], args
[4], args
[5]);
540 static __always_inline
541 void syscall_entry_event_notifier_call_func(struct hlist_head
*dispatch_list
,
542 void *func
, unsigned int nrargs
, struct pt_regs
*regs
)
544 struct lttng_event_notifier
*notifier
;
549 void (*fptr
)(void *__data
) = func
;
551 lttng_hlist_for_each_entry_rcu(notifier
, dispatch_list
, u
.syscall
.node
)
557 void (*fptr
)(void *__data
, unsigned long arg0
) = func
;
558 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
560 lttng_syscall_get_arguments(current
, regs
, args
);
561 lttng_hlist_for_each_entry_rcu(notifier
, dispatch_list
, u
.syscall
.node
)
562 fptr(notifier
, args
[0]);
567 void (*fptr
)(void *__data
,
569 unsigned long arg1
) = func
;
570 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
572 lttng_syscall_get_arguments(current
, regs
, args
);
573 lttng_hlist_for_each_entry_rcu(notifier
, dispatch_list
, u
.syscall
.node
)
574 fptr(notifier
, args
[0], args
[1]);
579 void (*fptr
)(void *__data
,
582 unsigned long arg2
) = func
;
583 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
585 lttng_syscall_get_arguments(current
, regs
, args
);
586 lttng_hlist_for_each_entry_rcu(notifier
, dispatch_list
, u
.syscall
.node
)
587 fptr(notifier
, args
[0], args
[1], args
[2]);
592 void (*fptr
)(void *__data
,
596 unsigned long arg3
) = func
;
597 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
599 lttng_syscall_get_arguments(current
, regs
, args
);
600 lttng_hlist_for_each_entry_rcu(notifier
, dispatch_list
, u
.syscall
.node
)
601 fptr(notifier
, args
[0], args
[1], args
[2], args
[3]);
606 void (*fptr
)(void *__data
,
611 unsigned long arg4
) = func
;
612 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
614 lttng_syscall_get_arguments(current
, regs
, args
);
615 lttng_hlist_for_each_entry_rcu(notifier
, dispatch_list
, u
.syscall
.node
)
616 fptr(notifier
, args
[0], args
[1], args
[2], args
[3], args
[4]);
621 void (*fptr
)(void *__data
,
627 unsigned long arg5
) = func
;
628 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
630 lttng_syscall_get_arguments(current
, regs
, args
);
631 lttng_hlist_for_each_entry_rcu(notifier
, dispatch_list
, u
.syscall
.node
)
632 fptr(notifier
, args
[0], args
[1], args
[2], args
[3], args
[4], args
[5]);
640 void syscall_entry_event_probe(void *__data
, struct pt_regs
*regs
, long id
)
642 struct lttng_event_container
*container
= __data
;
643 struct hlist_head
*action_list
, *unknown_action_list
;
644 const struct trace_syscall_entry
*table
, *entry
;
647 if (unlikely(in_compat_syscall())) {
648 struct lttng_syscall_filter
*filter
= container
->sc_filter
;
650 if (id
< 0 || id
>= NR_compat_syscalls
651 || (!READ_ONCE(container
->syscall_all_entry
) && !test_bit(id
, filter
->sc_compat_entry
))) {
652 /* System call filtered out. */
655 table
= compat_sc_table
;
656 table_len
= ARRAY_SIZE(compat_sc_table
);
657 unknown_action_list
= &container
->sc_compat_unknown
;
659 struct lttng_syscall_filter
*filter
= container
->sc_filter
;
661 if (id
< 0 || id
>= NR_syscalls
662 || (!READ_ONCE(container
->syscall_all_entry
) && !test_bit(id
, filter
->sc_entry
))) {
663 /* System call filtered out. */
667 table_len
= ARRAY_SIZE(sc_table
);
668 unknown_action_list
= &container
->sc_unknown
;
670 if (unlikely(id
< 0 || id
>= table_len
)) {
671 syscall_entry_event_unknown(unknown_action_list
, regs
, id
);
676 if (!entry
->event_func
) {
677 syscall_entry_event_unknown(unknown_action_list
, regs
, id
);
681 if (unlikely(in_compat_syscall())) {
682 action_list
= &container
->compat_sc_table
[id
];
684 action_list
= &container
->sc_table
[id
];
686 if (unlikely(hlist_empty(action_list
)))
689 syscall_entry_call_func(action_list
, entry
->event_func
, entry
->nrargs
, regs
);
692 void syscall_entry_event_notifier_probe(void *__data
, struct pt_regs
*regs
,
695 struct lttng_event_notifier_group
*group
= __data
;
696 const struct trace_syscall_entry
*table
, *entry
;
697 struct hlist_head
*dispatch_list
, *unknown_dispatch_list
;
700 if (unlikely(in_compat_syscall())) {
701 struct lttng_syscall_filter
*filter
= group
->sc_filter
;
703 if (id
< 0 || id
>= NR_compat_syscalls
704 || (!READ_ONCE(group
->syscall_all_entry
) &&
705 !test_bit(id
, filter
->sc_compat_entry
))) {
706 /* System call filtered out. */
709 table
= compat_sc_table
;
710 table_len
= ARRAY_SIZE(compat_sc_table
);
711 unknown_dispatch_list
= &group
->event_notifier_compat_unknown_syscall_dispatch
;
713 struct lttng_syscall_filter
*filter
= group
->sc_filter
;
715 if (id
< 0 || id
>= NR_syscalls
716 || (!READ_ONCE(group
->syscall_all_entry
) &&
717 !test_bit(id
, filter
->sc_entry
))) {
718 /* System call filtered out. */
722 table_len
= ARRAY_SIZE(sc_table
);
723 unknown_dispatch_list
= &group
->event_notifier_unknown_syscall_dispatch
;
725 /* Check if the syscall id is out of bound. */
726 if (unlikely(id
< 0 || id
>= table_len
)) {
727 syscall_entry_event_notifier_unknown(unknown_dispatch_list
,
733 if (!entry
->event_notifier_func
) {
734 syscall_entry_event_notifier_unknown(unknown_dispatch_list
,
739 if (unlikely(in_compat_syscall())) {
740 dispatch_list
= &group
->event_notifier_compat_syscall_dispatch
[id
];
742 dispatch_list
= &group
->event_notifier_syscall_dispatch
[id
];
744 if (unlikely(hlist_empty(dispatch_list
)))
747 syscall_entry_event_notifier_call_func(dispatch_list
,
748 entry
->event_notifier_func
, entry
->nrargs
, regs
);
751 static void syscall_exit_event_unknown(struct hlist_head
*unknown_action_list_head
,
752 struct pt_regs
*regs
, long id
, long ret
)
754 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
755 struct lttng_event
*event
;
757 lttng_syscall_get_arguments(current
, regs
, args
);
758 lttng_hlist_for_each_entry_rcu(event
, unknown_action_list_head
, u
.syscall
.node
) {
759 if (unlikely(in_compat_syscall()))
760 __event_probe__compat_syscall_exit_unknown(event
, id
, ret
,
763 __event_probe__syscall_exit_unknown(event
, id
, ret
, args
);
767 static __always_inline
768 void syscall_exit_call_func(struct hlist_head
*action_list
,
769 void *func
, unsigned int nrargs
,
770 struct pt_regs
*regs
, long ret
)
772 struct lttng_event
*event
;
777 void (*fptr
)(void *__data
, long ret
) = func
;
779 lttng_hlist_for_each_entry_rcu(event
, action_list
, u
.syscall
.node
)
785 void (*fptr
)(void *__data
,
787 unsigned long arg0
) = func
;
788 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
790 lttng_syscall_get_arguments(current
, regs
, args
);
791 lttng_hlist_for_each_entry_rcu(event
, action_list
, u
.syscall
.node
)
792 fptr(event
, ret
, args
[0]);
797 void (*fptr
)(void *__data
,
800 unsigned long arg1
) = func
;
801 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
803 lttng_syscall_get_arguments(current
, regs
, args
);
804 lttng_hlist_for_each_entry_rcu(event
, action_list
, u
.syscall
.node
)
805 fptr(event
, ret
, args
[0], args
[1]);
810 void (*fptr
)(void *__data
,
814 unsigned long arg2
) = func
;
815 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
817 lttng_syscall_get_arguments(current
, regs
, args
);
818 lttng_hlist_for_each_entry_rcu(event
, action_list
, u
.syscall
.node
)
819 fptr(event
, ret
, args
[0], args
[1], args
[2]);
824 void (*fptr
)(void *__data
,
829 unsigned long arg3
) = func
;
830 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
832 lttng_syscall_get_arguments(current
, regs
, args
);
833 lttng_hlist_for_each_entry_rcu(event
, action_list
, u
.syscall
.node
)
834 fptr(event
, ret
, args
[0], args
[1], args
[2], args
[3]);
839 void (*fptr
)(void *__data
,
845 unsigned long arg4
) = func
;
846 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
848 lttng_syscall_get_arguments(current
, regs
, args
);
849 lttng_hlist_for_each_entry_rcu(event
, action_list
, u
.syscall
.node
)
850 fptr(event
, ret
, args
[0], args
[1], args
[2], args
[3], args
[4]);
855 void (*fptr
)(void *__data
,
862 unsigned long arg5
) = func
;
863 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
865 lttng_syscall_get_arguments(current
, regs
, args
);
866 lttng_hlist_for_each_entry_rcu(event
, action_list
, u
.syscall
.node
)
867 fptr(event
, ret
, args
[0], args
[1], args
[2],
868 args
[3], args
[4], args
[5]);
876 void syscall_exit_event_probe(void *__data
, struct pt_regs
*regs
, long ret
)
878 struct lttng_event_container
*container
= __data
;
879 struct hlist_head
*action_list
, *unknown_action_list
;
880 const struct trace_syscall_entry
*table
, *entry
;
884 id
= syscall_get_nr(current
, regs
);
886 if (unlikely(in_compat_syscall())) {
887 struct lttng_syscall_filter
*filter
= container
->sc_filter
;
889 if (id
< 0 || id
>= NR_compat_syscalls
890 || (!READ_ONCE(container
->syscall_all_exit
) && !test_bit(id
, filter
->sc_compat_exit
))) {
891 /* System call filtered out. */
894 table
= compat_sc_exit_table
;
895 table_len
= ARRAY_SIZE(compat_sc_exit_table
);
896 unknown_action_list
= &container
->compat_sc_exit_unknown
;
898 struct lttng_syscall_filter
*filter
= container
->sc_filter
;
900 if (id
< 0 || id
>= NR_syscalls
901 || (!READ_ONCE(container
->syscall_all_exit
) && !test_bit(id
, filter
->sc_exit
))) {
902 /* System call filtered out. */
905 table
= sc_exit_table
;
906 table_len
= ARRAY_SIZE(sc_exit_table
);
907 unknown_action_list
= &container
->sc_exit_unknown
;
909 if (unlikely(id
< 0 || id
>= table_len
)) {
910 syscall_exit_event_unknown(unknown_action_list
, regs
, id
, ret
);
915 if (!entry
->event_func
) {
916 syscall_exit_event_unknown(unknown_action_list
, regs
, id
, ret
);
920 if (unlikely(in_compat_syscall())) {
921 action_list
= &container
->compat_sc_exit_table
[id
];
923 action_list
= &container
->sc_exit_table
[id
];
925 if (unlikely(hlist_empty(action_list
)))
928 syscall_exit_call_func(action_list
, entry
->event_func
, entry
->nrargs
,
932 static __always_inline
933 void syscall_exit_event_notifier_call_func(struct hlist_head
*dispatch_list
,
934 void *func
, unsigned int nrargs
, struct pt_regs
*regs
, long ret
)
936 struct lttng_event_notifier
*notifier
;
941 void (*fptr
)(void *__data
, long ret
) = func
;
943 lttng_hlist_for_each_entry_rcu(notifier
, dispatch_list
, u
.syscall
.node
)
949 void (*fptr
)(void *__data
, long ret
, unsigned long arg0
) = func
;
950 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
952 lttng_syscall_get_arguments(current
, regs
, args
);
953 lttng_hlist_for_each_entry_rcu(notifier
, dispatch_list
, u
.syscall
.node
)
954 fptr(notifier
, ret
, args
[0]);
959 void (*fptr
)(void *__data
,
962 unsigned long arg1
) = func
;
963 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
965 lttng_syscall_get_arguments(current
, regs
, args
);
966 lttng_hlist_for_each_entry_rcu(notifier
, dispatch_list
, u
.syscall
.node
)
967 fptr(notifier
, ret
, args
[0], args
[1]);
972 void (*fptr
)(void *__data
,
976 unsigned long arg2
) = func
;
977 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
979 lttng_syscall_get_arguments(current
, regs
, args
);
980 lttng_hlist_for_each_entry_rcu(notifier
, dispatch_list
, u
.syscall
.node
)
981 fptr(notifier
, ret
, args
[0], args
[1], args
[2]);
986 void (*fptr
)(void *__data
,
991 unsigned long arg3
) = func
;
992 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
994 lttng_syscall_get_arguments(current
, regs
, args
);
995 lttng_hlist_for_each_entry_rcu(notifier
, dispatch_list
, u
.syscall
.node
)
996 fptr(notifier
, ret
, args
[0], args
[1], args
[2], args
[3]);
1001 void (*fptr
)(void *__data
,
1007 unsigned long arg4
) = func
;
1008 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
1010 lttng_syscall_get_arguments(current
, regs
, args
);
1011 lttng_hlist_for_each_entry_rcu(notifier
, dispatch_list
, u
.syscall
.node
)
1012 fptr(notifier
, ret
, args
[0], args
[1], args
[2], args
[3], args
[4]);
1017 void (*fptr
)(void *__data
,
1024 unsigned long arg5
) = func
;
1025 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
1027 lttng_syscall_get_arguments(current
, regs
, args
);
1028 lttng_hlist_for_each_entry_rcu(notifier
, dispatch_list
, u
.syscall
.node
)
1029 fptr(notifier
, ret
, args
[0], args
[1], args
[2], args
[3], args
[4], args
[5]);
1038 void syscall_exit_event_notifier_probe(void *__data
, struct pt_regs
*regs
,
1041 struct lttng_event_notifier_group
*group
= __data
;
1042 const struct trace_syscall_entry
*table
, *entry
;
1043 struct hlist_head
*dispatch_list
, *unknown_dispatch_list
;
1047 id
= syscall_get_nr(current
, regs
);
1049 if (unlikely(in_compat_syscall())) {
1050 struct lttng_syscall_filter
*filter
= group
->sc_filter
;
1052 if (id
< 0 || id
>= NR_compat_syscalls
1053 || (!READ_ONCE(group
->syscall_all_exit
) &&
1054 !test_bit(id
, filter
->sc_compat_exit
))) {
1055 /* System call filtered out. */
1058 table
= compat_sc_exit_table
;
1059 table_len
= ARRAY_SIZE(compat_sc_exit_table
);
1060 unknown_dispatch_list
= &group
->event_notifier_exit_compat_unknown_syscall_dispatch
;
1062 struct lttng_syscall_filter
*filter
= group
->sc_filter
;
1064 if (id
< 0 || id
>= NR_syscalls
1065 || (!READ_ONCE(group
->syscall_all_exit
) &&
1066 !test_bit(id
, filter
->sc_exit
))) {
1067 /* System call filtered out. */
1070 table
= sc_exit_table
;
1071 table_len
= ARRAY_SIZE(sc_exit_table
);
1072 unknown_dispatch_list
= &group
->event_notifier_exit_unknown_syscall_dispatch
;
1074 /* Check if the syscall id is out of bound. */
1075 if (unlikely(id
< 0 || id
>= table_len
)) {
1076 syscall_exit_event_notifier_unknown(unknown_dispatch_list
,
1082 if (!entry
->event_notifier_func
) {
1083 syscall_entry_event_notifier_unknown(unknown_dispatch_list
,
1088 if (unlikely(in_compat_syscall())) {
1089 dispatch_list
= &group
->event_notifier_exit_compat_syscall_dispatch
[id
];
1091 dispatch_list
= &group
->event_notifier_exit_syscall_dispatch
[id
];
1093 if (unlikely(hlist_empty(dispatch_list
)))
1096 syscall_exit_event_notifier_call_func(dispatch_list
,
1097 entry
->event_notifier_func
, entry
->nrargs
, regs
, ret
);
1100 * noinline to diminish caller stack size.
1101 * Should be called with sessions lock held.
1104 int lttng_create_syscall_event_if_missing(const struct trace_syscall_entry
*table
, size_t table_len
,
1105 struct hlist_head
*container_table
, struct lttng_event_enabler
*event_enabler
,
1106 void *filter
, enum sc_type type
)
1108 struct lttng_event_container
*container
= event_enabler
->container
;
1111 /* Allocate events for each syscall matching enabler, insert into table */
1112 for (i
= 0; i
< table_len
; i
++) {
1113 const struct lttng_event_desc
*desc
= table
[i
].desc
;
1114 struct lttng_kernel_event ev
;
1115 struct lttng_event
*event
;
1118 /* Unknown syscall */
1121 if (lttng_desc_match_enabler(desc
,
1122 lttng_event_enabler_as_enabler(event_enabler
)) <= 0)
1125 /* We need to create an event for this syscall/enabler. */
1126 memset(&ev
, 0, sizeof(ev
));
1129 ev
.u
.syscall
.entryexit
= LTTNG_KERNEL_SYSCALL_ENTRY
;
1130 ev
.u
.syscall
.abi
= LTTNG_KERNEL_SYSCALL_ABI_NATIVE
;
1133 ev
.u
.syscall
.entryexit
= LTTNG_KERNEL_SYSCALL_EXIT
;
1134 ev
.u
.syscall
.abi
= LTTNG_KERNEL_SYSCALL_ABI_NATIVE
;
1136 case SC_TYPE_COMPAT_ENTRY
:
1137 ev
.u
.syscall
.entryexit
= LTTNG_KERNEL_SYSCALL_ENTRY
;
1138 ev
.u
.syscall
.abi
= LTTNG_KERNEL_SYSCALL_ABI_COMPAT
;
1140 case SC_TYPE_COMPAT_EXIT
:
1141 ev
.u
.syscall
.entryexit
= LTTNG_KERNEL_SYSCALL_EXIT
;
1142 ev
.u
.syscall
.abi
= LTTNG_KERNEL_SYSCALL_ABI_COMPAT
;
1145 strncpy(ev
.name
, desc
->name
, LTTNG_KERNEL_SYM_NAME_LEN
- 1);
1146 ev
.name
[LTTNG_KERNEL_SYM_NAME_LEN
- 1] = '\0';
1147 ev
.instrumentation
= LTTNG_KERNEL_SYSCALL
;
1148 event
= _lttng_event_create(container
, &ev
, &event_enabler
->key
, filter
,
1149 desc
, ev
.instrumentation
,
1150 event_enabler
->base
.user_token
);
1151 /* Skip if event is already found. */
1152 if (IS_ERR(event
) && PTR_ERR(event
) == -EEXIST
)
1154 if (IS_ERR(event
)) {
1156 * If something goes wrong in event registration
1157 * after the first one, we have no choice but to
1158 * leave the previous events in there, until
1159 * deleted by session teardown.
1161 return PTR_ERR(event
);
1163 hlist_add_head(&event
->u
.syscall
.node
, &container_table
[i
]);
1169 * Should be called with sessions lock held.
1171 int lttng_syscalls_register_event(struct lttng_event_enabler
*event_enabler
, void *filter
)
1173 struct lttng_event_container
*container
= event_enabler
->container
;
1174 struct lttng_kernel_event ev
;
1177 wrapper_vmalloc_sync_mappings();
1179 if (!container
->sc_table
) {
1180 /* create syscall table mapping syscall to events */
1181 container
->sc_table
= kzalloc(sizeof(struct hlist_head
)
1182 * ARRAY_SIZE(sc_table
), GFP_KERNEL
);
1183 if (!container
->sc_table
)
1186 if (!container
->sc_exit_table
) {
1187 /* create syscall table mapping syscall to events */
1188 container
->sc_exit_table
= kzalloc(sizeof(struct hlist_head
)
1189 * ARRAY_SIZE(sc_exit_table
), GFP_KERNEL
);
1190 if (!container
->sc_exit_table
)
1194 #ifdef CONFIG_COMPAT
1195 if (!container
->compat_sc_table
) {
1196 /* create syscall table mapping compat syscall to events */
1197 container
->compat_sc_table
= kzalloc(sizeof(struct hlist_head
)
1198 * ARRAY_SIZE(compat_sc_table
), GFP_KERNEL
);
1199 if (!container
->compat_sc_table
)
1203 if (!container
->compat_sc_exit_table
) {
1204 /* create syscall table mapping compat syscall to events */
1205 container
->compat_sc_exit_table
= kzalloc(sizeof(struct hlist_head
)
1206 * ARRAY_SIZE(compat_sc_exit_table
), GFP_KERNEL
);
1207 if (!container
->compat_sc_exit_table
)
1213 const struct lttng_event_desc
*desc
=
1214 &__event_desc___syscall_entry_unknown
;
1215 struct lttng_event
*event
;
1217 memset(&ev
, 0, sizeof(ev
));
1218 strncpy(ev
.name
, desc
->name
, LTTNG_KERNEL_SYM_NAME_LEN
);
1219 ev
.name
[LTTNG_KERNEL_SYM_NAME_LEN
- 1] = '\0';
1220 ev
.instrumentation
= LTTNG_KERNEL_SYSCALL
;
1221 ev
.u
.syscall
.entryexit
= LTTNG_KERNEL_SYSCALL_ENTRY
;
1222 ev
.u
.syscall
.abi
= LTTNG_KERNEL_SYSCALL_ABI_NATIVE
;
1223 event
= _lttng_event_create(container
, &ev
, &event_enabler
->key
, filter
,
1224 desc
, ev
.instrumentation
,
1225 event_enabler
->base
.user_token
);
1226 if (IS_ERR(event
)) {
1227 if (PTR_ERR(event
) != -EEXIST
)
1228 return PTR_ERR(event
);
1229 /* Skip if event is already found. */
1231 hlist_add_head(&event
->u
.syscall
.node
, &container
->sc_unknown
);
1236 const struct lttng_event_desc
*desc
=
1237 &__event_desc___compat_syscall_entry_unknown
;
1238 struct lttng_event
*event
;
1240 memset(&ev
, 0, sizeof(ev
));
1241 strncpy(ev
.name
, desc
->name
, LTTNG_KERNEL_SYM_NAME_LEN
);
1242 ev
.name
[LTTNG_KERNEL_SYM_NAME_LEN
- 1] = '\0';
1243 ev
.instrumentation
= LTTNG_KERNEL_SYSCALL
;
1244 ev
.u
.syscall
.entryexit
= LTTNG_KERNEL_SYSCALL_ENTRY
;
1245 ev
.u
.syscall
.abi
= LTTNG_KERNEL_SYSCALL_ABI_COMPAT
;
1246 event
= _lttng_event_create(container
, &ev
, &event_enabler
->key
, filter
,
1247 desc
, ev
.instrumentation
,
1248 event_enabler
->base
.user_token
);
1249 if (IS_ERR(event
)) {
1250 if (PTR_ERR(event
) != -EEXIST
)
1251 return PTR_ERR(event
);
1252 /* Skip if event is already found. */
1254 hlist_add_head(&event
->u
.syscall
.node
, &container
->sc_compat_unknown
);
1259 const struct lttng_event_desc
*desc
=
1260 &__event_desc___compat_syscall_exit_unknown
;
1261 struct lttng_event
*event
;
1263 memset(&ev
, 0, sizeof(ev
));
1264 strncpy(ev
.name
, desc
->name
, LTTNG_KERNEL_SYM_NAME_LEN
);
1265 ev
.name
[LTTNG_KERNEL_SYM_NAME_LEN
- 1] = '\0';
1266 ev
.instrumentation
= LTTNG_KERNEL_SYSCALL
;
1267 ev
.u
.syscall
.entryexit
= LTTNG_KERNEL_SYSCALL_EXIT
;
1268 ev
.u
.syscall
.abi
= LTTNG_KERNEL_SYSCALL_ABI_COMPAT
;
1269 event
= _lttng_event_create(container
, &ev
, &event_enabler
->key
,
1270 filter
, desc
, ev
.instrumentation
,
1271 event_enabler
->base
.user_token
);
1272 if (IS_ERR(event
)) {
1273 if (PTR_ERR(event
) != -EEXIST
)
1274 return PTR_ERR(event
);
1275 /* Skip if event is already found. */
1277 hlist_add_head(&event
->u
.syscall
.node
, &container
->compat_sc_exit_unknown
);
1282 const struct lttng_event_desc
*desc
=
1283 &__event_desc___syscall_exit_unknown
;
1284 struct lttng_event
*event
;
1286 memset(&ev
, 0, sizeof(ev
));
1287 strncpy(ev
.name
, desc
->name
, LTTNG_KERNEL_SYM_NAME_LEN
);
1288 ev
.name
[LTTNG_KERNEL_SYM_NAME_LEN
- 1] = '\0';
1289 ev
.instrumentation
= LTTNG_KERNEL_SYSCALL
;
1290 ev
.u
.syscall
.entryexit
= LTTNG_KERNEL_SYSCALL_EXIT
;
1291 ev
.u
.syscall
.abi
= LTTNG_KERNEL_SYSCALL_ABI_NATIVE
;
1292 event
= _lttng_event_create(container
, &ev
, &event_enabler
->key
, filter
,
1293 desc
, ev
.instrumentation
,
1294 event_enabler
->base
.user_token
);
1295 if (IS_ERR(event
)) {
1296 if (PTR_ERR(event
) != -EEXIST
)
1297 return PTR_ERR(event
);
1298 /* Skip if event is already found. */
1300 hlist_add_head(&event
->u
.syscall
.node
, &container
->sc_exit_unknown
);
1304 ret
= lttng_create_syscall_event_if_missing(sc_table
, ARRAY_SIZE(sc_table
),
1305 container
->sc_table
, event_enabler
, filter
, SC_TYPE_ENTRY
);
1308 ret
= lttng_create_syscall_event_if_missing(sc_exit_table
, ARRAY_SIZE(sc_exit_table
),
1309 container
->sc_exit_table
, event_enabler
, filter
, SC_TYPE_EXIT
);
1313 #ifdef CONFIG_COMPAT
1314 ret
= lttng_create_syscall_event_if_missing(compat_sc_table
, ARRAY_SIZE(compat_sc_table
),
1315 container
->compat_sc_table
, event_enabler
, filter
,
1316 SC_TYPE_COMPAT_ENTRY
);
1319 ret
= lttng_create_syscall_event_if_missing(compat_sc_exit_table
, ARRAY_SIZE(compat_sc_exit_table
),
1320 container
->compat_sc_exit_table
, event_enabler
, filter
,
1321 SC_TYPE_COMPAT_EXIT
);
1326 if (!container
->sc_filter
) {
1327 container
->sc_filter
= kzalloc(sizeof(struct lttng_syscall_filter
),
1329 if (!container
->sc_filter
)
1333 if (!container
->sys_enter_registered
) {
1334 ret
= lttng_wrapper_tracepoint_probe_register("sys_enter",
1335 (void *) syscall_entry_event_probe
, container
);
1338 container
->sys_enter_registered
= 1;
1341 * We change the name of sys_exit tracepoint due to namespace
1342 * conflict with sys_exit syscall entry.
1344 if (!container
->sys_exit_registered
) {
1345 ret
= lttng_wrapper_tracepoint_probe_register("sys_exit",
1346 (void *) syscall_exit_event_probe
, container
);
1348 WARN_ON_ONCE(lttng_wrapper_tracepoint_probe_unregister("sys_enter",
1349 (void *) syscall_entry_event_probe
, container
));
1352 container
->sys_exit_registered
= 1;
1358 * Should be called with sessions lock held.
1360 int lttng_syscalls_register_event_notifier(
1361 struct lttng_event_notifier_enabler
*event_notifier_enabler
,
1364 struct lttng_event_notifier_group
*group
= event_notifier_enabler
->group
;
1368 wrapper_vmalloc_sync_mappings();
1370 if (!group
->event_notifier_syscall_dispatch
) {
1371 group
->event_notifier_syscall_dispatch
=
1372 kzalloc(sizeof(struct hlist_head
) * ARRAY_SIZE(sc_table
),
1374 if (!group
->event_notifier_syscall_dispatch
)
1377 /* Initialize all list_head */
1378 for (i
= 0; i
< ARRAY_SIZE(sc_table
); i
++)
1379 INIT_HLIST_HEAD(&group
->event_notifier_syscall_dispatch
[i
]);
1381 /* Init the unknown syscall notifier list. */
1382 INIT_HLIST_HEAD(&group
->event_notifier_unknown_syscall_dispatch
);
1385 if (!group
->event_notifier_exit_syscall_dispatch
) {
1386 group
->event_notifier_exit_syscall_dispatch
=
1387 kzalloc(sizeof(struct hlist_head
) * ARRAY_SIZE(sc_table
),
1389 if (!group
->event_notifier_exit_syscall_dispatch
)
1392 /* Initialize all list_head */
1393 for (i
= 0; i
< ARRAY_SIZE(sc_table
); i
++)
1394 INIT_HLIST_HEAD(&group
->event_notifier_exit_syscall_dispatch
[i
]);
1396 /* Init the unknown exit syscall notifier list. */
1397 INIT_HLIST_HEAD(&group
->event_notifier_exit_unknown_syscall_dispatch
);
1400 #ifdef CONFIG_COMPAT
1401 if (!group
->event_notifier_compat_syscall_dispatch
) {
1402 group
->event_notifier_compat_syscall_dispatch
=
1403 kzalloc(sizeof(struct hlist_head
) * ARRAY_SIZE(compat_sc_table
),
1405 if (!group
->event_notifier_syscall_dispatch
)
1408 /* Initialize all list_head */
1409 for (i
= 0; i
< ARRAY_SIZE(compat_sc_table
); i
++)
1410 INIT_HLIST_HEAD(&group
->event_notifier_compat_syscall_dispatch
[i
]);
1412 /* Init the unknown syscall notifier list. */
1413 INIT_HLIST_HEAD(&group
->event_notifier_compat_unknown_syscall_dispatch
);
1416 if (!group
->event_notifier_exit_compat_syscall_dispatch
) {
1417 group
->event_notifier_exit_compat_syscall_dispatch
=
1418 kzalloc(sizeof(struct hlist_head
) * ARRAY_SIZE(compat_sc_exit_table
),
1420 if (!group
->event_notifier_exit_syscall_dispatch
)
1423 /* Initialize all list_head */
1424 for (i
= 0; i
< ARRAY_SIZE(compat_sc_exit_table
); i
++)
1425 INIT_HLIST_HEAD(&group
->event_notifier_exit_compat_syscall_dispatch
[i
]);
1427 /* Init the unknown exit syscall notifier list. */
1428 INIT_HLIST_HEAD(&group
->event_notifier_exit_compat_unknown_syscall_dispatch
);
1432 if (!group
->sc_filter
) {
1433 group
->sc_filter
= kzalloc(sizeof(struct lttng_syscall_filter
),
1435 if (!group
->sc_filter
)
1439 if (!group
->sys_enter_registered
) {
1440 ret
= lttng_wrapper_tracepoint_probe_register("sys_enter",
1441 (void *) syscall_entry_event_notifier_probe
, group
);
1444 group
->sys_enter_registered
= 1;
1447 if (!group
->sys_exit_registered
) {
1448 ret
= lttng_wrapper_tracepoint_probe_register("sys_exit",
1449 (void *) syscall_exit_event_notifier_probe
, group
);
1451 WARN_ON_ONCE(lttng_wrapper_tracepoint_probe_unregister("sys_enter",
1452 (void *) syscall_entry_event_notifier_probe
, group
));
1455 group
->sys_exit_registered
= 1;
1462 int create_unknown_event_notifier(
1463 struct lttng_event_notifier_enabler
*event_notifier_enabler
,
1466 struct lttng_event_notifier
*notifier
;
1467 const struct lttng_event_desc
*desc
;
1468 struct lttng_event_notifier_group
*group
= event_notifier_enabler
->group
;
1469 struct lttng_kernel_event_notifier event_notifier_param
;
1470 uint64_t user_token
= event_notifier_enabler
->base
.user_token
;
1471 uint64_t error_counter_index
= event_notifier_enabler
->error_counter_index
;
1472 struct lttng_enabler
*base_enabler
= lttng_event_notifier_enabler_as_enabler(
1473 event_notifier_enabler
);
1474 struct hlist_head
*unknown_dispatch_list
;
1477 enum lttng_kernel_syscall_abi abi
;
1478 enum lttng_kernel_syscall_entryexit entryexit
;
1479 struct hlist_head
*head
;
1483 desc
= &__event_desc___syscall_entry_unknown
;
1484 unknown_dispatch_list
= &group
->event_notifier_unknown_syscall_dispatch
;
1485 entryexit
= LTTNG_KERNEL_SYSCALL_ENTRY
;
1486 abi
= LTTNG_KERNEL_SYSCALL_ABI_NATIVE
;
1489 desc
= &__event_desc___syscall_exit_unknown
;
1490 unknown_dispatch_list
= &group
->event_notifier_exit_unknown_syscall_dispatch
;
1491 entryexit
= LTTNG_KERNEL_SYSCALL_EXIT
;
1492 abi
= LTTNG_KERNEL_SYSCALL_ABI_NATIVE
;
1494 case SC_TYPE_COMPAT_ENTRY
:
1495 desc
= &__event_desc___compat_syscall_entry_unknown
;
1496 unknown_dispatch_list
= &group
->event_notifier_compat_unknown_syscall_dispatch
;
1497 entryexit
= LTTNG_KERNEL_SYSCALL_ENTRY
;
1498 abi
= LTTNG_KERNEL_SYSCALL_ABI_COMPAT
;
1500 case SC_TYPE_COMPAT_EXIT
:
1501 desc
= &__event_desc___compat_syscall_exit_unknown
;
1502 unknown_dispatch_list
= &group
->event_notifier_exit_compat_unknown_syscall_dispatch
;
1503 entryexit
= LTTNG_KERNEL_SYSCALL_EXIT
;
1504 abi
= LTTNG_KERNEL_SYSCALL_ABI_COMPAT
;
1511 * Check if already created.
1513 head
= utils_borrow_hash_table_bucket(group
->event_notifiers_ht
.table
,
1514 LTTNG_EVENT_NOTIFIER_HT_SIZE
, desc
->name
);
1515 lttng_hlist_for_each_entry(notifier
, head
, hlist
) {
1516 if (notifier
->desc
== desc
&&
1517 notifier
->user_token
== base_enabler
->user_token
)
1523 memset(&event_notifier_param
, 0, sizeof(event_notifier_param
));
1524 strncat(event_notifier_param
.event
.name
, desc
->name
,
1525 LTTNG_KERNEL_SYM_NAME_LEN
- strlen(event_notifier_param
.event
.name
) - 1);
1527 event_notifier_param
.event
.name
[LTTNG_KERNEL_SYM_NAME_LEN
- 1] = '\0';
1529 event_notifier_param
.event
.instrumentation
= LTTNG_KERNEL_SYSCALL
;
1530 event_notifier_param
.event
.u
.syscall
.abi
= abi
;
1531 event_notifier_param
.event
.u
.syscall
.entryexit
= entryexit
;
1533 notifier
= _lttng_event_notifier_create(desc
, user_token
,
1534 error_counter_index
, group
, &event_notifier_param
, NULL
,
1535 event_notifier_param
.event
.instrumentation
);
1536 if (IS_ERR(notifier
)) {
1537 printk(KERN_INFO
"Unable to create unknown notifier %s\n",
1543 hlist_add_head_rcu(¬ifier
->u
.syscall
.node
, unknown_dispatch_list
);
1549 static int create_matching_event_notifiers(
1550 struct lttng_event_notifier_enabler
*event_notifier_enabler
,
1551 void *filter
, const struct trace_syscall_entry
*table
,
1552 size_t table_len
, enum sc_type type
)
1554 struct lttng_event_notifier_group
*group
= event_notifier_enabler
->group
;
1555 const struct lttng_event_desc
*desc
;
1556 uint64_t user_token
= event_notifier_enabler
->base
.user_token
;
1557 uint64_t error_counter_index
= event_notifier_enabler
->error_counter_index
;
1561 /* iterate over all syscall and create event_notifier that match */
1562 for (i
= 0; i
< table_len
; i
++) {
1563 struct lttng_event_notifier
*event_notifier
;
1564 struct lttng_kernel_event_notifier event_notifier_param
;
1565 struct hlist_head
*head
;
1568 desc
= table
[i
].desc
;
1570 /* Unknown syscall */
1574 if (lttng_desc_match_enabler(desc
,
1575 lttng_event_notifier_enabler_as_enabler(event_notifier_enabler
)) <= 0)
1579 * Check if already created.
1581 head
= utils_borrow_hash_table_bucket(group
->event_notifiers_ht
.table
,
1582 LTTNG_EVENT_NOTIFIER_HT_SIZE
, desc
->name
);
1583 lttng_hlist_for_each_entry(event_notifier
, head
, hlist
) {
1584 if (event_notifier
->desc
== desc
1585 && event_notifier
->user_token
== event_notifier_enabler
->base
.user_token
)
1591 memset(&event_notifier_param
, 0, sizeof(event_notifier_param
));
1594 event_notifier_param
.event
.u
.syscall
.entryexit
= LTTNG_KERNEL_SYSCALL_ENTRY
;
1595 event_notifier_param
.event
.u
.syscall
.abi
= LTTNG_KERNEL_SYSCALL_ABI_NATIVE
;
1598 event_notifier_param
.event
.u
.syscall
.entryexit
= LTTNG_KERNEL_SYSCALL_EXIT
;
1599 event_notifier_param
.event
.u
.syscall
.abi
= LTTNG_KERNEL_SYSCALL_ABI_NATIVE
;
1601 case SC_TYPE_COMPAT_ENTRY
:
1602 event_notifier_param
.event
.u
.syscall
.entryexit
= LTTNG_KERNEL_SYSCALL_ENTRY
;
1603 event_notifier_param
.event
.u
.syscall
.abi
= LTTNG_KERNEL_SYSCALL_ABI_COMPAT
;
1605 case SC_TYPE_COMPAT_EXIT
:
1606 event_notifier_param
.event
.u
.syscall
.entryexit
= LTTNG_KERNEL_SYSCALL_EXIT
;
1607 event_notifier_param
.event
.u
.syscall
.abi
= LTTNG_KERNEL_SYSCALL_ABI_COMPAT
;
1610 strncat(event_notifier_param
.event
.name
, desc
->name
,
1611 LTTNG_KERNEL_SYM_NAME_LEN
- strlen(event_notifier_param
.event
.name
) - 1);
1612 event_notifier_param
.event
.name
[LTTNG_KERNEL_SYM_NAME_LEN
- 1] = '\0';
1613 event_notifier_param
.event
.instrumentation
= LTTNG_KERNEL_SYSCALL
;
1615 event_notifier
= _lttng_event_notifier_create(desc
, user_token
,
1616 error_counter_index
, group
, &event_notifier_param
,
1617 filter
, event_notifier_param
.event
.instrumentation
);
1618 if (IS_ERR(event_notifier
)) {
1619 printk(KERN_INFO
"Unable to create event_notifier %s\n",
1625 event_notifier
->u
.syscall
.syscall_id
= i
;
1632 int lttng_syscals_create_matching_event_notifiers(
1633 struct lttng_event_notifier_enabler
*event_notifier_enabler
,
1637 struct lttng_enabler
*base_enabler
=
1638 lttng_event_notifier_enabler_as_enabler(event_notifier_enabler
);
1639 enum lttng_kernel_syscall_entryexit entryexit
=
1640 base_enabler
->event_param
.u
.syscall
.entryexit
;
1642 if (entryexit
== LTTNG_KERNEL_SYSCALL_ENTRY
|| entryexit
== LTTNG_KERNEL_SYSCALL_ENTRYEXIT
) {
1643 ret
= create_matching_event_notifiers(event_notifier_enabler
,
1644 filter
, sc_table
, ARRAY_SIZE(sc_table
), SC_TYPE_ENTRY
);
1648 ret
= create_matching_event_notifiers(event_notifier_enabler
,
1649 filter
, compat_sc_table
, ARRAY_SIZE(compat_sc_table
),
1650 SC_TYPE_COMPAT_ENTRY
);
1654 ret
= create_unknown_event_notifier(event_notifier_enabler
,
1659 ret
= create_unknown_event_notifier(event_notifier_enabler
,
1660 SC_TYPE_COMPAT_ENTRY
);
1665 if (entryexit
== LTTNG_KERNEL_SYSCALL_EXIT
|| entryexit
== LTTNG_KERNEL_SYSCALL_ENTRYEXIT
) {
1666 ret
= create_matching_event_notifiers(event_notifier_enabler
,
1667 filter
, sc_exit_table
, ARRAY_SIZE(sc_exit_table
),
1672 ret
= create_unknown_event_notifier(event_notifier_enabler
,
1677 ret
= create_matching_event_notifiers(event_notifier_enabler
,
1678 filter
, compat_sc_exit_table
, ARRAY_SIZE(compat_sc_exit_table
),
1679 SC_TYPE_COMPAT_EXIT
);
1683 ret
= create_unknown_event_notifier(event_notifier_enabler
,
1684 SC_TYPE_COMPAT_EXIT
);
1694 * Unregister the syscall event_notifier probes from the callsites.
1696 int lttng_syscalls_unregister_event_notifier_group(
1697 struct lttng_event_notifier_group
*event_notifier_group
)
1702 * Only register the event_notifier probe on the `sys_enter` callsite for now.
1703 * At the moment, we don't think it's desirable to have one fired
1704 * event_notifier for the entry and one for the exit of a syscall.
1706 if (event_notifier_group
->sys_enter_registered
) {
1707 ret
= lttng_wrapper_tracepoint_probe_unregister("sys_enter",
1708 (void *) syscall_entry_event_notifier_probe
, event_notifier_group
);
1711 event_notifier_group
->sys_enter_registered
= 0;
1713 if (event_notifier_group
->sys_exit_registered
) {
1714 ret
= lttng_wrapper_tracepoint_probe_unregister("sys_exit",
1715 (void *) syscall_exit_event_notifier_probe
, event_notifier_group
);
1718 event_notifier_group
->sys_enter_registered
= 0;
1721 kfree(event_notifier_group
->event_notifier_syscall_dispatch
);
1722 kfree(event_notifier_group
->event_notifier_exit_syscall_dispatch
);
1723 #ifdef CONFIG_COMPAT
1724 kfree(event_notifier_group
->event_notifier_compat_syscall_dispatch
);
1725 kfree(event_notifier_group
->event_notifier_exit_compat_syscall_dispatch
);
1730 int lttng_syscalls_unregister_event_container(struct lttng_event_container
*container
)
1734 if (!container
->sc_table
)
1736 if (container
->sys_enter_registered
) {
1737 ret
= lttng_wrapper_tracepoint_probe_unregister("sys_enter",
1738 (void *) syscall_entry_event_probe
, container
);
1741 container
->sys_enter_registered
= 0;
1743 if (container
->sys_exit_registered
) {
1744 ret
= lttng_wrapper_tracepoint_probe_unregister("sys_exit",
1745 (void *) syscall_exit_event_probe
, container
);
1748 container
->sys_exit_registered
= 0;
1753 int lttng_syscalls_destroy_event_container(struct lttng_event_container
*container
)
1755 kfree(container
->sc_table
);
1756 kfree(container
->sc_exit_table
);
1757 #ifdef CONFIG_COMPAT
1758 kfree(container
->compat_sc_table
);
1759 kfree(container
->compat_sc_exit_table
);
1761 kfree(container
->sc_filter
);
1766 int get_syscall_nr(const char *syscall_name
)
1768 int syscall_nr
= -1;
1771 for (i
= 0; i
< ARRAY_SIZE(sc_table
); i
++) {
1772 const struct trace_syscall_entry
*entry
;
1773 const char *it_name
;
1775 entry
= &sc_table
[i
];
1778 it_name
= entry
->desc
->name
;
1779 it_name
+= strlen(SYSCALL_ENTRY_STR
);
1780 if (!strcmp(syscall_name
, it_name
)) {
1789 int get_compat_syscall_nr(const char *syscall_name
)
1791 int syscall_nr
= -1;
1794 for (i
= 0; i
< ARRAY_SIZE(compat_sc_table
); i
++) {
1795 const struct trace_syscall_entry
*entry
;
1796 const char *it_name
;
1798 entry
= &compat_sc_table
[i
];
1801 it_name
= entry
->desc
->name
;
1802 it_name
+= strlen(COMPAT_SYSCALL_ENTRY_STR
);
1803 if (!strcmp(syscall_name
, it_name
)) {
1812 uint32_t get_sc_tables_len(void)
1814 return ARRAY_SIZE(sc_table
) + ARRAY_SIZE(compat_sc_table
);
1818 const char *get_syscall_name(const char *desc_name
,
1819 enum lttng_syscall_abi abi
,
1820 enum lttng_syscall_entryexit entryexit
)
1822 size_t prefix_len
= 0;
1825 switch (entryexit
) {
1826 case LTTNG_SYSCALL_ENTRY
:
1828 case LTTNG_SYSCALL_ABI_NATIVE
:
1829 prefix_len
= strlen(SYSCALL_ENTRY_STR
);
1831 case LTTNG_SYSCALL_ABI_COMPAT
:
1832 prefix_len
= strlen(COMPAT_SYSCALL_ENTRY_STR
);
1836 case LTTNG_SYSCALL_EXIT
:
1838 case LTTNG_SYSCALL_ABI_NATIVE
:
1839 prefix_len
= strlen(SYSCALL_EXIT_STR
);
1841 case LTTNG_SYSCALL_ABI_COMPAT
:
1842 prefix_len
= strlen(COMPAT_SYSCALL_EXIT_STR
);
1847 WARN_ON_ONCE(prefix_len
== 0);
1848 return desc_name
+ prefix_len
;
1852 int lttng_syscall_filter_enable(
1853 struct lttng_syscall_filter
*filter
,
1854 const char *desc_name
, enum lttng_syscall_abi abi
,
1855 enum lttng_syscall_entryexit entryexit
)
1857 const char *syscall_name
;
1858 unsigned long *bitmap
;
1861 syscall_name
= get_syscall_name(desc_name
, abi
, entryexit
);
1864 case LTTNG_SYSCALL_ABI_NATIVE
:
1865 syscall_nr
= get_syscall_nr(syscall_name
);
1867 case LTTNG_SYSCALL_ABI_COMPAT
:
1868 syscall_nr
= get_compat_syscall_nr(syscall_name
);
1876 switch (entryexit
) {
1877 case LTTNG_SYSCALL_ENTRY
:
1879 case LTTNG_SYSCALL_ABI_NATIVE
:
1880 bitmap
= filter
->sc_entry
;
1882 case LTTNG_SYSCALL_ABI_COMPAT
:
1883 bitmap
= filter
->sc_compat_entry
;
1889 case LTTNG_SYSCALL_EXIT
:
1891 case LTTNG_SYSCALL_ABI_NATIVE
:
1892 bitmap
= filter
->sc_exit
;
1894 case LTTNG_SYSCALL_ABI_COMPAT
:
1895 bitmap
= filter
->sc_compat_exit
;
1904 if (test_bit(syscall_nr
, bitmap
))
1906 bitmap_set(bitmap
, syscall_nr
, 1);
1910 int lttng_syscall_filter_enable_event_notifier(
1911 struct lttng_event_notifier
*notifier
)
1913 struct lttng_event_notifier_group
*group
= notifier
->group
;
1914 unsigned int syscall_id
= notifier
->u
.syscall
.syscall_id
;
1915 struct hlist_head
*dispatch_list
;
1918 WARN_ON_ONCE(notifier
->instrumentation
!= LTTNG_KERNEL_SYSCALL
);
1920 ret
= lttng_syscall_filter_enable(group
->sc_filter
,
1921 notifier
->desc
->name
, notifier
->u
.syscall
.abi
,
1922 notifier
->u
.syscall
.entryexit
);
1927 switch (notifier
->u
.syscall
.entryexit
) {
1928 case LTTNG_SYSCALL_ENTRY
:
1929 switch (notifier
->u
.syscall
.abi
) {
1930 case LTTNG_SYSCALL_ABI_NATIVE
:
1931 dispatch_list
= &group
->event_notifier_syscall_dispatch
[syscall_id
];
1933 case LTTNG_SYSCALL_ABI_COMPAT
:
1934 dispatch_list
= &group
->event_notifier_compat_syscall_dispatch
[syscall_id
];
1941 case LTTNG_SYSCALL_EXIT
:
1942 switch (notifier
->u
.syscall
.abi
) {
1943 case LTTNG_SYSCALL_ABI_NATIVE
:
1944 dispatch_list
= &group
->event_notifier_exit_syscall_dispatch
[syscall_id
];
1946 case LTTNG_SYSCALL_ABI_COMPAT
:
1947 dispatch_list
= &group
->event_notifier_exit_compat_syscall_dispatch
[syscall_id
];
1959 hlist_add_head_rcu(¬ifier
->u
.syscall
.node
, dispatch_list
);
1965 int lttng_syscall_filter_enable_event(
1966 struct lttng_event_container
*container
,
1967 struct lttng_event
*event
)
1969 WARN_ON_ONCE(event
->instrumentation
!= LTTNG_KERNEL_SYSCALL
);
1971 return lttng_syscall_filter_enable(container
->sc_filter
,
1972 event
->desc
->name
, event
->u
.syscall
.abi
,
1973 event
->u
.syscall
.entryexit
);
1977 int lttng_syscall_filter_disable(
1978 struct lttng_syscall_filter
*filter
,
1979 const char *desc_name
, enum lttng_syscall_abi abi
,
1980 enum lttng_syscall_entryexit entryexit
)
1982 const char *syscall_name
;
1983 unsigned long *bitmap
;
1986 syscall_name
= get_syscall_name(desc_name
, abi
, entryexit
);
1989 case LTTNG_SYSCALL_ABI_NATIVE
:
1990 syscall_nr
= get_syscall_nr(syscall_name
);
1992 case LTTNG_SYSCALL_ABI_COMPAT
:
1993 syscall_nr
= get_compat_syscall_nr(syscall_name
);
2001 switch (entryexit
) {
2002 case LTTNG_SYSCALL_ENTRY
:
2004 case LTTNG_SYSCALL_ABI_NATIVE
:
2005 bitmap
= filter
->sc_entry
;
2007 case LTTNG_SYSCALL_ABI_COMPAT
:
2008 bitmap
= filter
->sc_compat_entry
;
2014 case LTTNG_SYSCALL_EXIT
:
2016 case LTTNG_SYSCALL_ABI_NATIVE
:
2017 bitmap
= filter
->sc_exit
;
2019 case LTTNG_SYSCALL_ABI_COMPAT
:
2020 bitmap
= filter
->sc_compat_exit
;
2029 if (!test_bit(syscall_nr
, bitmap
))
2031 bitmap_clear(bitmap
, syscall_nr
, 1);
2036 int lttng_syscall_filter_disable_event_notifier(
2037 struct lttng_event_notifier
*notifier
)
2039 struct lttng_event_notifier_group
*group
= notifier
->group
;
2042 WARN_ON_ONCE(notifier
->instrumentation
!= LTTNG_KERNEL_SYSCALL
);
2044 ret
= lttng_syscall_filter_disable(group
->sc_filter
,
2045 notifier
->desc
->name
, notifier
->u
.syscall
.abi
,
2046 notifier
->u
.syscall
.entryexit
);
2047 WARN_ON_ONCE(ret
!= 0);
2049 hlist_del_rcu(¬ifier
->u
.syscall
.node
);
2053 int lttng_syscall_filter_disable_event(
2054 struct lttng_event_container
*container
,
2055 struct lttng_event
*event
)
2057 return lttng_syscall_filter_disable(container
->sc_filter
,
2058 event
->desc
->name
, event
->u
.syscall
.abi
,
2059 event
->u
.syscall
.entryexit
);
2063 const struct trace_syscall_entry
*syscall_list_get_entry(loff_t
*pos
)
2065 const struct trace_syscall_entry
*entry
;
2068 for (entry
= sc_table
;
2069 entry
< sc_table
+ ARRAY_SIZE(sc_table
);
2074 for (entry
= compat_sc_table
;
2075 entry
< compat_sc_table
+ ARRAY_SIZE(compat_sc_table
);
2085 void *syscall_list_start(struct seq_file
*m
, loff_t
*pos
)
2087 return (void *) syscall_list_get_entry(pos
);
2091 void *syscall_list_next(struct seq_file
*m
, void *p
, loff_t
*ppos
)
2094 return (void *) syscall_list_get_entry(ppos
);
2098 void syscall_list_stop(struct seq_file
*m
, void *p
)
2103 int get_sc_table(const struct trace_syscall_entry
*entry
,
2104 const struct trace_syscall_entry
**table
,
2105 unsigned int *bitness
)
2107 if (entry
>= sc_table
&& entry
< sc_table
+ ARRAY_SIZE(sc_table
)) {
2109 *bitness
= BITS_PER_LONG
;
2114 if (!(entry
>= compat_sc_table
2115 && entry
< compat_sc_table
+ ARRAY_SIZE(compat_sc_table
))) {
2121 *table
= compat_sc_table
;
2126 int syscall_list_show(struct seq_file
*m
, void *p
)
2128 const struct trace_syscall_entry
*table
, *entry
= p
;
2129 unsigned int bitness
;
2130 unsigned long index
;
2134 ret
= get_sc_table(entry
, &table
, &bitness
);
2139 if (table
== sc_table
) {
2140 index
= entry
- table
;
2141 name
= &entry
->desc
->name
[strlen(SYSCALL_ENTRY_STR
)];
2143 index
= (entry
- table
) + ARRAY_SIZE(sc_table
);
2144 name
= &entry
->desc
->name
[strlen(COMPAT_SYSCALL_ENTRY_STR
)];
2146 seq_printf(m
, "syscall { index = %lu; name = %s; bitness = %u; };\n",
2147 index
, name
, bitness
);
2152 const struct seq_operations lttng_syscall_list_seq_ops
= {
2153 .start
= syscall_list_start
,
2154 .next
= syscall_list_next
,
2155 .stop
= syscall_list_stop
,
2156 .show
= syscall_list_show
,
2160 int lttng_syscall_list_open(struct inode
*inode
, struct file
*file
)
2162 return seq_open(file
, <tng_syscall_list_seq_ops
);
2165 const struct file_operations lttng_syscall_list_fops
= {
2166 .owner
= THIS_MODULE
,
2167 .open
= lttng_syscall_list_open
,
2169 .llseek
= seq_lseek
,
2170 .release
= seq_release
,
2174 * A syscall is enabled if it is traced for either entry or exit.
2176 long lttng_event_container_syscall_mask(struct lttng_event_container
*container
,
2177 struct lttng_kernel_syscall_mask __user
*usyscall_mask
)
2179 uint32_t len
, sc_tables_len
, bitmask_len
;
2182 struct lttng_syscall_filter
*filter
;
2184 ret
= get_user(len
, &usyscall_mask
->len
);
2187 sc_tables_len
= get_sc_tables_len();
2188 bitmask_len
= ALIGN(sc_tables_len
, 8) >> 3;
2189 if (len
< sc_tables_len
) {
2190 return put_user(sc_tables_len
, &usyscall_mask
->len
);
2192 /* Array is large enough, we can copy array to user-space. */
2193 tmp_mask
= kzalloc(bitmask_len
, GFP_KERNEL
);
2196 filter
= container
->sc_filter
;
2198 for (bit
= 0; bit
< ARRAY_SIZE(sc_table
); bit
++) {
2201 if (container
->sc_table
) {
2202 if (!(READ_ONCE(container
->syscall_all_entry
)
2203 || READ_ONCE(container
->syscall_all_exit
)) && filter
)
2204 state
= test_bit(bit
, filter
->sc_entry
)
2205 || test_bit(bit
, filter
->sc_exit
);
2211 bt_bitfield_write_be(tmp_mask
, char, bit
, 1, state
);
2213 for (; bit
< sc_tables_len
; bit
++) {
2216 if (container
->compat_sc_table
) {
2217 if (!(READ_ONCE(container
->syscall_all_entry
)
2218 || READ_ONCE(container
->syscall_all_exit
)) && filter
)
2219 state
= test_bit(bit
- ARRAY_SIZE(sc_table
),
2220 filter
->sc_compat_entry
)
2221 || test_bit(bit
- ARRAY_SIZE(sc_table
),
2222 filter
->sc_compat_exit
);
2228 bt_bitfield_write_be(tmp_mask
, char, bit
, 1, state
);
2230 if (copy_to_user(usyscall_mask
->mask
, tmp_mask
, bitmask_len
))
2236 int lttng_abi_syscall_list(void)
2238 struct file
*syscall_list_file
;
2241 file_fd
= lttng_get_unused_fd();
2247 syscall_list_file
= anon_inode_getfile("[lttng_syscall_list]",
2248 <tng_syscall_list_fops
,
2250 if (IS_ERR(syscall_list_file
)) {
2251 ret
= PTR_ERR(syscall_list_file
);
2254 ret
= lttng_syscall_list_fops
.open(NULL
, syscall_list_file
);
2257 fd_install(file_fd
, syscall_list_file
);
2261 fput(syscall_list_file
);
2263 put_unused_fd(file_fd
);