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 (LINUX_VERSION_CODE >= 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 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 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 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 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 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 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 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 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_channel
*chan
= __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
= chan
->sc_filter
;
650 if (id
< 0 || id
>= NR_compat_syscalls
651 || (!READ_ONCE(chan
->syscall_all_entry
) && !test_bit(id
, filter
->sc_compat_entry
))) {
652 /* System call filtered out. */
655 table
= compat_sc_table
;
656 table_len
= ARRAY_SIZE(compat_sc_table
);
657 unknown_action_list
= &chan
->sc_compat_unknown
;
659 struct lttng_syscall_filter
*filter
= chan
->sc_filter
;
661 if (id
< 0 || id
>= NR_syscalls
662 || (!READ_ONCE(chan
->syscall_all_entry
) && !test_bit(id
, filter
->sc_entry
))) {
663 /* System call filtered out. */
667 table_len
= ARRAY_SIZE(sc_table
);
668 unknown_action_list
= &chan
->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
= &chan
->compat_sc_table
[id
];
684 action_list
= &chan
->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 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 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 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 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 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 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 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 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_channel
*chan
= __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
= chan
->sc_filter
;
889 if (id
< 0 || id
>= NR_compat_syscalls
890 || (!READ_ONCE(chan
->syscall_all_exit
) && !test_bit(id
, filter
->sc_compat_exit
))) {
891 /* System call filtered out. */
894 table
= compat_sc_exit_table
;
895 table_len
= ARRAY_SIZE(compat_sc_exit_table
);
896 unknown_action_list
= &chan
->compat_sc_exit_unknown
;
898 struct lttng_syscall_filter
*filter
= chan
->sc_filter
;
900 if (id
< 0 || id
>= NR_syscalls
901 || (!READ_ONCE(chan
->syscall_all_exit
) && !test_bit(id
, filter
->sc_exit
))) {
902 /* System call filtered out. */
905 table
= sc_exit_table
;
906 table_len
= ARRAY_SIZE(sc_exit_table
);
907 unknown_action_list
= &chan
->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
= &chan
->compat_sc_exit_table
[id
];
923 action_list
= &chan
->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
*chan_table
, struct lttng_event_enabler
*event_enabler
,
1106 void *filter
, enum sc_type type
)
1108 struct lttng_channel
*chan
= event_enabler
->chan
;
1109 struct lttng_session
*session
= chan
->session
;
1112 /* Allocate events for each syscall matching enabler, insert into table */
1113 for (i
= 0; i
< table_len
; i
++) {
1114 const struct lttng_event_desc
*desc
= table
[i
].desc
;
1115 struct lttng_kernel_event ev
;
1116 struct lttng_event
*event
;
1117 struct hlist_head
*head
;
1121 /* Unknown syscall */
1124 if (lttng_desc_match_enabler(desc
,
1125 lttng_event_enabler_as_enabler(event_enabler
)) <= 0)
1128 * Check if already created.
1130 head
= utils_borrow_hash_table_bucket(
1131 session
->events_ht
.table
, LTTNG_EVENT_HT_SIZE
,
1133 lttng_hlist_for_each_entry(event
, head
, hlist
) {
1134 if (event
->desc
== desc
1135 && event
->chan
== event_enabler
->chan
)
1141 /* We need to create an event for this syscall/enabler. */
1142 memset(&ev
, 0, sizeof(ev
));
1145 ev
.u
.syscall
.entryexit
= LTTNG_KERNEL_SYSCALL_ENTRY
;
1146 ev
.u
.syscall
.abi
= LTTNG_KERNEL_SYSCALL_ABI_NATIVE
;
1149 ev
.u
.syscall
.entryexit
= LTTNG_KERNEL_SYSCALL_EXIT
;
1150 ev
.u
.syscall
.abi
= LTTNG_KERNEL_SYSCALL_ABI_NATIVE
;
1152 case SC_TYPE_COMPAT_ENTRY
:
1153 ev
.u
.syscall
.entryexit
= LTTNG_KERNEL_SYSCALL_ENTRY
;
1154 ev
.u
.syscall
.abi
= LTTNG_KERNEL_SYSCALL_ABI_COMPAT
;
1156 case SC_TYPE_COMPAT_EXIT
:
1157 ev
.u
.syscall
.entryexit
= LTTNG_KERNEL_SYSCALL_EXIT
;
1158 ev
.u
.syscall
.abi
= LTTNG_KERNEL_SYSCALL_ABI_COMPAT
;
1161 strncpy(ev
.name
, desc
->name
, LTTNG_KERNEL_SYM_NAME_LEN
- 1);
1162 ev
.name
[LTTNG_KERNEL_SYM_NAME_LEN
- 1] = '\0';
1163 ev
.instrumentation
= LTTNG_KERNEL_SYSCALL
;
1164 event
= _lttng_event_create(chan
, &ev
, filter
,
1165 desc
, ev
.instrumentation
);
1166 WARN_ON_ONCE(!event
);
1167 if (IS_ERR(event
)) {
1169 * If something goes wrong in event registration
1170 * after the first one, we have no choice but to
1171 * leave the previous events in there, until
1172 * deleted by session teardown.
1174 return PTR_ERR(event
);
1176 hlist_add_head(&event
->u
.syscall
.node
, &chan_table
[i
]);
1182 * Should be called with sessions lock held.
1184 int lttng_syscalls_register_event(struct lttng_event_enabler
*event_enabler
, void *filter
)
1186 struct lttng_channel
*chan
= event_enabler
->chan
;
1187 struct lttng_kernel_event ev
;
1190 wrapper_vmalloc_sync_mappings();
1192 if (!chan
->sc_table
) {
1193 /* create syscall table mapping syscall to events */
1194 chan
->sc_table
= kzalloc(sizeof(struct lttng_event
*)
1195 * ARRAY_SIZE(sc_table
), GFP_KERNEL
);
1196 if (!chan
->sc_table
)
1199 if (!chan
->sc_exit_table
) {
1200 /* create syscall table mapping syscall to events */
1201 chan
->sc_exit_table
= kzalloc(sizeof(struct lttng_event
*)
1202 * ARRAY_SIZE(sc_exit_table
), GFP_KERNEL
);
1203 if (!chan
->sc_exit_table
)
1208 #ifdef CONFIG_COMPAT
1209 if (!chan
->compat_sc_table
) {
1210 /* create syscall table mapping compat syscall to events */
1211 chan
->compat_sc_table
= kzalloc(sizeof(struct lttng_event
*)
1212 * ARRAY_SIZE(compat_sc_table
), GFP_KERNEL
);
1213 if (!chan
->compat_sc_table
)
1217 if (!chan
->compat_sc_exit_table
) {
1218 /* create syscall table mapping compat syscall to events */
1219 chan
->compat_sc_exit_table
= kzalloc(sizeof(struct lttng_event
*)
1220 * ARRAY_SIZE(compat_sc_exit_table
), GFP_KERNEL
);
1221 if (!chan
->compat_sc_exit_table
)
1225 if (hlist_empty(&chan
->sc_unknown
)) {
1226 const struct lttng_event_desc
*desc
=
1227 &__event_desc___syscall_entry_unknown
;
1228 struct lttng_event
*event
;
1230 memset(&ev
, 0, sizeof(ev
));
1231 strncpy(ev
.name
, desc
->name
, LTTNG_KERNEL_SYM_NAME_LEN
);
1232 ev
.name
[LTTNG_KERNEL_SYM_NAME_LEN
- 1] = '\0';
1233 ev
.instrumentation
= LTTNG_KERNEL_SYSCALL
;
1234 ev
.u
.syscall
.entryexit
= LTTNG_KERNEL_SYSCALL_ENTRY
;
1235 ev
.u
.syscall
.abi
= LTTNG_KERNEL_SYSCALL_ABI_NATIVE
;
1236 event
= _lttng_event_create(chan
, &ev
, filter
, desc
,
1237 ev
.instrumentation
);
1238 WARN_ON_ONCE(!event
);
1239 if (IS_ERR(event
)) {
1240 return PTR_ERR(event
);
1242 hlist_add_head(&event
->u
.syscall
.node
, &chan
->sc_unknown
);
1245 if (hlist_empty(&chan
->sc_compat_unknown
)) {
1246 const struct lttng_event_desc
*desc
=
1247 &__event_desc___compat_syscall_entry_unknown
;
1248 struct lttng_event
*event
;
1250 memset(&ev
, 0, sizeof(ev
));
1251 strncpy(ev
.name
, desc
->name
, LTTNG_KERNEL_SYM_NAME_LEN
);
1252 ev
.name
[LTTNG_KERNEL_SYM_NAME_LEN
- 1] = '\0';
1253 ev
.instrumentation
= LTTNG_KERNEL_SYSCALL
;
1254 ev
.u
.syscall
.entryexit
= LTTNG_KERNEL_SYSCALL_ENTRY
;
1255 ev
.u
.syscall
.abi
= LTTNG_KERNEL_SYSCALL_ABI_COMPAT
;
1256 event
= _lttng_event_create(chan
, &ev
, filter
, desc
,
1257 ev
.instrumentation
);
1258 WARN_ON_ONCE(!event
);
1259 if (IS_ERR(event
)) {
1260 return PTR_ERR(event
);
1262 hlist_add_head(&event
->u
.syscall
.node
, &chan
->sc_compat_unknown
);
1265 if (hlist_empty(&chan
->compat_sc_exit_unknown
)) {
1266 const struct lttng_event_desc
*desc
=
1267 &__event_desc___compat_syscall_exit_unknown
;
1268 struct lttng_event
*event
;
1270 memset(&ev
, 0, sizeof(ev
));
1271 strncpy(ev
.name
, desc
->name
, LTTNG_KERNEL_SYM_NAME_LEN
);
1272 ev
.name
[LTTNG_KERNEL_SYM_NAME_LEN
- 1] = '\0';
1273 ev
.instrumentation
= LTTNG_KERNEL_SYSCALL
;
1274 ev
.u
.syscall
.entryexit
= LTTNG_KERNEL_SYSCALL_EXIT
;
1275 ev
.u
.syscall
.abi
= LTTNG_KERNEL_SYSCALL_ABI_COMPAT
;
1276 event
= _lttng_event_create(chan
, &ev
, filter
, desc
,
1277 ev
.instrumentation
);
1278 WARN_ON_ONCE(!event
);
1279 if (IS_ERR(event
)) {
1280 return PTR_ERR(event
);
1282 hlist_add_head(&event
->u
.syscall
.node
, &chan
->compat_sc_exit_unknown
);
1285 if (hlist_empty(&chan
->sc_exit_unknown
)) {
1286 const struct lttng_event_desc
*desc
=
1287 &__event_desc___syscall_exit_unknown
;
1288 struct lttng_event
*event
;
1290 memset(&ev
, 0, sizeof(ev
));
1291 strncpy(ev
.name
, desc
->name
, LTTNG_KERNEL_SYM_NAME_LEN
);
1292 ev
.name
[LTTNG_KERNEL_SYM_NAME_LEN
- 1] = '\0';
1293 ev
.instrumentation
= LTTNG_KERNEL_SYSCALL
;
1294 ev
.u
.syscall
.entryexit
= LTTNG_KERNEL_SYSCALL_EXIT
;
1295 ev
.u
.syscall
.abi
= LTTNG_KERNEL_SYSCALL_ABI_NATIVE
;
1296 event
= _lttng_event_create(chan
, &ev
, filter
, desc
,
1297 ev
.instrumentation
);
1298 WARN_ON_ONCE(!event
);
1299 if (IS_ERR(event
)) {
1300 return PTR_ERR(event
);
1302 hlist_add_head(&event
->u
.syscall
.node
, &chan
->sc_exit_unknown
);
1305 ret
= lttng_create_syscall_event_if_missing(sc_table
, ARRAY_SIZE(sc_table
),
1306 chan
->sc_table
, event_enabler
, filter
, SC_TYPE_ENTRY
);
1309 ret
= lttng_create_syscall_event_if_missing(sc_exit_table
, ARRAY_SIZE(sc_exit_table
),
1310 chan
->sc_exit_table
, event_enabler
, filter
, SC_TYPE_EXIT
);
1314 #ifdef CONFIG_COMPAT
1315 ret
= lttng_create_syscall_event_if_missing(compat_sc_table
, ARRAY_SIZE(compat_sc_table
),
1316 chan
->compat_sc_table
, event_enabler
, filter
,
1317 SC_TYPE_COMPAT_ENTRY
);
1320 ret
= lttng_create_syscall_event_if_missing(compat_sc_exit_table
, ARRAY_SIZE(compat_sc_exit_table
),
1321 chan
->compat_sc_exit_table
, event_enabler
, filter
,
1322 SC_TYPE_COMPAT_EXIT
);
1327 if (!chan
->sc_filter
) {
1328 chan
->sc_filter
= kzalloc(sizeof(struct lttng_syscall_filter
),
1330 if (!chan
->sc_filter
)
1334 if (!chan
->sys_enter_registered
) {
1335 ret
= lttng_wrapper_tracepoint_probe_register("sys_enter",
1336 (void *) syscall_entry_event_probe
, chan
);
1339 chan
->sys_enter_registered
= 1;
1342 * We change the name of sys_exit tracepoint due to namespace
1343 * conflict with sys_exit syscall entry.
1345 if (!chan
->sys_exit_registered
) {
1346 ret
= lttng_wrapper_tracepoint_probe_register("sys_exit",
1347 (void *) syscall_exit_event_probe
, chan
);
1349 WARN_ON_ONCE(lttng_wrapper_tracepoint_probe_unregister("sys_enter",
1350 (void *) syscall_entry_event_probe
, chan
));
1353 chan
->sys_exit_registered
= 1;
1359 * Should be called with sessions lock held.
1361 int lttng_syscalls_register_event_notifier(
1362 struct lttng_event_notifier_enabler
*event_notifier_enabler
,
1365 struct lttng_event_notifier_group
*group
= event_notifier_enabler
->group
;
1369 wrapper_vmalloc_sync_mappings();
1371 if (!group
->event_notifier_syscall_dispatch
) {
1372 group
->event_notifier_syscall_dispatch
=
1373 kzalloc(sizeof(struct hlist_head
) * ARRAY_SIZE(sc_table
),
1375 if (!group
->event_notifier_syscall_dispatch
)
1378 /* Initialize all list_head */
1379 for (i
= 0; i
< ARRAY_SIZE(sc_table
); i
++)
1380 INIT_HLIST_HEAD(&group
->event_notifier_syscall_dispatch
[i
]);
1382 /* Init the unknown syscall notifier list. */
1383 INIT_HLIST_HEAD(&group
->event_notifier_unknown_syscall_dispatch
);
1386 if (!group
->event_notifier_exit_syscall_dispatch
) {
1387 group
->event_notifier_exit_syscall_dispatch
=
1388 kzalloc(sizeof(struct hlist_head
) * ARRAY_SIZE(sc_table
),
1390 if (!group
->event_notifier_exit_syscall_dispatch
)
1393 /* Initialize all list_head */
1394 for (i
= 0; i
< ARRAY_SIZE(sc_table
); i
++)
1395 INIT_HLIST_HEAD(&group
->event_notifier_exit_syscall_dispatch
[i
]);
1397 /* Init the unknown exit syscall notifier list. */
1398 INIT_HLIST_HEAD(&group
->event_notifier_exit_unknown_syscall_dispatch
);
1401 #ifdef CONFIG_COMPAT
1402 if (!group
->event_notifier_compat_syscall_dispatch
) {
1403 group
->event_notifier_compat_syscall_dispatch
=
1404 kzalloc(sizeof(struct hlist_head
) * ARRAY_SIZE(compat_sc_table
),
1406 if (!group
->event_notifier_syscall_dispatch
)
1409 /* Initialize all list_head */
1410 for (i
= 0; i
< ARRAY_SIZE(compat_sc_table
); i
++)
1411 INIT_HLIST_HEAD(&group
->event_notifier_compat_syscall_dispatch
[i
]);
1413 /* Init the unknown syscall notifier list. */
1414 INIT_HLIST_HEAD(&group
->event_notifier_compat_unknown_syscall_dispatch
);
1417 if (!group
->event_notifier_exit_compat_syscall_dispatch
) {
1418 group
->event_notifier_exit_compat_syscall_dispatch
=
1419 kzalloc(sizeof(struct hlist_head
) * ARRAY_SIZE(compat_sc_exit_table
),
1421 if (!group
->event_notifier_exit_syscall_dispatch
)
1424 /* Initialize all list_head */
1425 for (i
= 0; i
< ARRAY_SIZE(compat_sc_exit_table
); i
++)
1426 INIT_HLIST_HEAD(&group
->event_notifier_exit_compat_syscall_dispatch
[i
]);
1428 /* Init the unknown exit syscall notifier list. */
1429 INIT_HLIST_HEAD(&group
->event_notifier_exit_compat_unknown_syscall_dispatch
);
1433 if (!group
->sc_filter
) {
1434 group
->sc_filter
= kzalloc(sizeof(struct lttng_syscall_filter
),
1436 if (!group
->sc_filter
)
1440 if (!group
->sys_enter_registered
) {
1441 ret
= lttng_wrapper_tracepoint_probe_register("sys_enter",
1442 (void *) syscall_entry_event_notifier_probe
, group
);
1445 group
->sys_enter_registered
= 1;
1448 if (!group
->sys_exit_registered
) {
1449 ret
= lttng_wrapper_tracepoint_probe_register("sys_exit",
1450 (void *) syscall_exit_event_notifier_probe
, group
);
1452 WARN_ON_ONCE(lttng_wrapper_tracepoint_probe_unregister("sys_enter",
1453 (void *) syscall_entry_event_notifier_probe
, group
));
1456 group
->sys_exit_registered
= 1;
1463 int create_unknown_event_notifier(
1464 struct lttng_event_notifier_enabler
*event_notifier_enabler
,
1467 struct lttng_event_notifier
*notifier
;
1468 const struct lttng_event_desc
*desc
;
1469 struct lttng_event_notifier_group
*group
= event_notifier_enabler
->group
;
1470 struct lttng_kernel_event_notifier event_notifier_param
;
1471 uint64_t user_token
= event_notifier_enabler
->base
.user_token
;
1472 uint64_t error_counter_index
= event_notifier_enabler
->error_counter_index
;
1473 struct lttng_enabler
*base_enabler
= lttng_event_notifier_enabler_as_enabler(
1474 event_notifier_enabler
);
1475 struct hlist_head
*unknown_dispatch_list
;
1478 enum lttng_kernel_syscall_abi abi
;
1479 enum lttng_kernel_syscall_entryexit entryexit
;
1480 struct hlist_head
*head
;
1484 desc
= &__event_desc___syscall_entry_unknown
;
1485 unknown_dispatch_list
= &group
->event_notifier_unknown_syscall_dispatch
;
1486 entryexit
= LTTNG_KERNEL_SYSCALL_ENTRY
;
1487 abi
= LTTNG_KERNEL_SYSCALL_ABI_NATIVE
;
1490 desc
= &__event_desc___syscall_exit_unknown
;
1491 unknown_dispatch_list
= &group
->event_notifier_exit_unknown_syscall_dispatch
;
1492 entryexit
= LTTNG_KERNEL_SYSCALL_EXIT
;
1493 abi
= LTTNG_KERNEL_SYSCALL_ABI_NATIVE
;
1495 case SC_TYPE_COMPAT_ENTRY
:
1496 desc
= &__event_desc___compat_syscall_entry_unknown
;
1497 unknown_dispatch_list
= &group
->event_notifier_compat_unknown_syscall_dispatch
;
1498 entryexit
= LTTNG_KERNEL_SYSCALL_ENTRY
;
1499 abi
= LTTNG_KERNEL_SYSCALL_ABI_COMPAT
;
1501 case SC_TYPE_COMPAT_EXIT
:
1502 desc
= &__event_desc___compat_syscall_exit_unknown
;
1503 unknown_dispatch_list
= &group
->event_notifier_exit_compat_unknown_syscall_dispatch
;
1504 entryexit
= LTTNG_KERNEL_SYSCALL_EXIT
;
1505 abi
= LTTNG_KERNEL_SYSCALL_ABI_COMPAT
;
1512 * Check if already created.
1514 head
= utils_borrow_hash_table_bucket(group
->event_notifiers_ht
.table
,
1515 LTTNG_EVENT_NOTIFIER_HT_SIZE
, desc
->name
);
1516 lttng_hlist_for_each_entry(notifier
, head
, hlist
) {
1517 if (notifier
->desc
== desc
&&
1518 notifier
->user_token
== base_enabler
->user_token
)
1524 memset(&event_notifier_param
, 0, sizeof(event_notifier_param
));
1525 strncat(event_notifier_param
.event
.name
, desc
->name
,
1526 LTTNG_KERNEL_SYM_NAME_LEN
- strlen(event_notifier_param
.event
.name
) - 1);
1528 event_notifier_param
.event
.name
[LTTNG_KERNEL_SYM_NAME_LEN
- 1] = '\0';
1530 event_notifier_param
.event
.instrumentation
= LTTNG_KERNEL_SYSCALL
;
1531 event_notifier_param
.event
.u
.syscall
.abi
= abi
;
1532 event_notifier_param
.event
.u
.syscall
.entryexit
= entryexit
;
1534 notifier
= _lttng_event_notifier_create(desc
, user_token
,
1535 error_counter_index
, group
, &event_notifier_param
, NULL
,
1536 event_notifier_param
.event
.instrumentation
);
1537 if (IS_ERR(notifier
)) {
1538 printk(KERN_INFO
"Unable to create unknown notifier %s\n",
1544 hlist_add_head_rcu(¬ifier
->u
.syscall
.node
, unknown_dispatch_list
);
1550 static int create_matching_event_notifiers(
1551 struct lttng_event_notifier_enabler
*event_notifier_enabler
,
1552 void *filter
, const struct trace_syscall_entry
*table
,
1553 size_t table_len
, enum sc_type type
)
1555 struct lttng_event_notifier_group
*group
= event_notifier_enabler
->group
;
1556 const struct lttng_event_desc
*desc
;
1557 uint64_t user_token
= event_notifier_enabler
->base
.user_token
;
1558 uint64_t error_counter_index
= event_notifier_enabler
->error_counter_index
;
1562 /* iterate over all syscall and create event_notifier that match */
1563 for (i
= 0; i
< table_len
; i
++) {
1564 struct lttng_event_notifier
*event_notifier
;
1565 struct lttng_kernel_event_notifier event_notifier_param
;
1566 struct hlist_head
*head
;
1569 desc
= table
[i
].desc
;
1571 /* Unknown syscall */
1575 if (!lttng_desc_match_enabler(desc
,
1576 lttng_event_notifier_enabler_as_enabler(event_notifier_enabler
)))
1580 * Check if already created.
1582 head
= utils_borrow_hash_table_bucket(group
->event_notifiers_ht
.table
,
1583 LTTNG_EVENT_NOTIFIER_HT_SIZE
, desc
->name
);
1584 lttng_hlist_for_each_entry(event_notifier
, head
, hlist
) {
1585 if (event_notifier
->desc
== desc
1586 && event_notifier
->user_token
== event_notifier_enabler
->base
.user_token
)
1592 memset(&event_notifier_param
, 0, sizeof(event_notifier_param
));
1595 event_notifier_param
.event
.u
.syscall
.entryexit
= LTTNG_KERNEL_SYSCALL_ENTRY
;
1596 event_notifier_param
.event
.u
.syscall
.abi
= LTTNG_KERNEL_SYSCALL_ABI_NATIVE
;
1599 event_notifier_param
.event
.u
.syscall
.entryexit
= LTTNG_KERNEL_SYSCALL_EXIT
;
1600 event_notifier_param
.event
.u
.syscall
.abi
= LTTNG_KERNEL_SYSCALL_ABI_NATIVE
;
1602 case SC_TYPE_COMPAT_ENTRY
:
1603 event_notifier_param
.event
.u
.syscall
.entryexit
= LTTNG_KERNEL_SYSCALL_ENTRY
;
1604 event_notifier_param
.event
.u
.syscall
.abi
= LTTNG_KERNEL_SYSCALL_ABI_COMPAT
;
1606 case SC_TYPE_COMPAT_EXIT
:
1607 event_notifier_param
.event
.u
.syscall
.entryexit
= LTTNG_KERNEL_SYSCALL_EXIT
;
1608 event_notifier_param
.event
.u
.syscall
.abi
= LTTNG_KERNEL_SYSCALL_ABI_COMPAT
;
1611 strncat(event_notifier_param
.event
.name
, desc
->name
,
1612 LTTNG_KERNEL_SYM_NAME_LEN
- strlen(event_notifier_param
.event
.name
) - 1);
1613 event_notifier_param
.event
.name
[LTTNG_KERNEL_SYM_NAME_LEN
- 1] = '\0';
1614 event_notifier_param
.event
.instrumentation
= LTTNG_KERNEL_SYSCALL
;
1616 event_notifier
= _lttng_event_notifier_create(desc
, user_token
,
1617 error_counter_index
, group
, &event_notifier_param
,
1618 filter
, event_notifier_param
.event
.instrumentation
);
1619 if (IS_ERR(event_notifier
)) {
1620 printk(KERN_INFO
"Unable to create event_notifier %s\n",
1626 event_notifier
->u
.syscall
.syscall_id
= i
;
1634 int lttng_syscals_create_matching_event_notifiers(
1635 struct lttng_event_notifier_enabler
*event_notifier_enabler
,
1639 struct lttng_enabler
*base_enabler
=
1640 lttng_event_notifier_enabler_as_enabler(event_notifier_enabler
);
1641 enum lttng_kernel_syscall_entryexit entryexit
=
1642 base_enabler
->event_param
.u
.syscall
.entryexit
;
1644 if (entryexit
== LTTNG_KERNEL_SYSCALL_ENTRY
|| entryexit
== LTTNG_KERNEL_SYSCALL_ENTRYEXIT
) {
1645 ret
= create_matching_event_notifiers(event_notifier_enabler
,
1646 filter
, sc_table
, ARRAY_SIZE(sc_table
), SC_TYPE_ENTRY
);
1650 ret
= create_matching_event_notifiers(event_notifier_enabler
,
1651 filter
, compat_sc_table
, ARRAY_SIZE(compat_sc_table
),
1652 SC_TYPE_COMPAT_ENTRY
);
1656 ret
= create_unknown_event_notifier(event_notifier_enabler
,
1661 ret
= create_unknown_event_notifier(event_notifier_enabler
,
1662 SC_TYPE_COMPAT_ENTRY
);
1667 if (entryexit
== LTTNG_KERNEL_SYSCALL_EXIT
|| entryexit
== LTTNG_KERNEL_SYSCALL_ENTRYEXIT
) {
1668 ret
= create_matching_event_notifiers(event_notifier_enabler
,
1669 filter
, sc_exit_table
, ARRAY_SIZE(sc_exit_table
),
1674 ret
= create_unknown_event_notifier(event_notifier_enabler
,
1679 ret
= create_matching_event_notifiers(event_notifier_enabler
,
1680 filter
, compat_sc_exit_table
, ARRAY_SIZE(compat_sc_exit_table
),
1681 SC_TYPE_COMPAT_EXIT
);
1685 ret
= create_unknown_event_notifier(event_notifier_enabler
,
1686 SC_TYPE_COMPAT_EXIT
);
1696 * Unregister the syscall event_notifier probes from the callsites.
1698 int lttng_syscalls_unregister_event_notifier_group(
1699 struct lttng_event_notifier_group
*event_notifier_group
)
1704 * Only register the event_notifier probe on the `sys_enter` callsite for now.
1705 * At the moment, we don't think it's desirable to have one fired
1706 * event_notifier for the entry and one for the exit of a syscall.
1708 if (event_notifier_group
->sys_enter_registered
) {
1709 ret
= lttng_wrapper_tracepoint_probe_unregister("sys_enter",
1710 (void *) syscall_entry_event_notifier_probe
, event_notifier_group
);
1713 event_notifier_group
->sys_enter_registered
= 0;
1715 if (event_notifier_group
->sys_exit_registered
) {
1716 ret
= lttng_wrapper_tracepoint_probe_unregister("sys_exit",
1717 (void *) syscall_exit_event_notifier_probe
, event_notifier_group
);
1720 event_notifier_group
->sys_enter_registered
= 0;
1723 kfree(event_notifier_group
->event_notifier_syscall_dispatch
);
1724 kfree(event_notifier_group
->event_notifier_exit_syscall_dispatch
);
1725 #ifdef CONFIG_COMPAT
1726 kfree(event_notifier_group
->event_notifier_compat_syscall_dispatch
);
1727 kfree(event_notifier_group
->event_notifier_exit_compat_syscall_dispatch
);
1732 int lttng_syscalls_unregister_channel(struct lttng_channel
*chan
)
1736 if (!chan
->sc_table
)
1738 if (chan
->sys_enter_registered
) {
1739 ret
= lttng_wrapper_tracepoint_probe_unregister("sys_enter",
1740 (void *) syscall_entry_event_probe
, chan
);
1743 chan
->sys_enter_registered
= 0;
1745 if (chan
->sys_exit_registered
) {
1746 ret
= lttng_wrapper_tracepoint_probe_unregister("sys_exit",
1747 (void *) syscall_exit_event_probe
, chan
);
1750 chan
->sys_exit_registered
= 0;
1755 int lttng_syscalls_destroy_event(struct lttng_channel
*chan
)
1757 kfree(chan
->sc_table
);
1758 kfree(chan
->sc_exit_table
);
1759 #ifdef CONFIG_COMPAT
1760 kfree(chan
->compat_sc_table
);
1761 kfree(chan
->compat_sc_exit_table
);
1763 kfree(chan
->sc_filter
);
1768 int get_syscall_nr(const char *syscall_name
)
1770 int syscall_nr
= -1;
1773 for (i
= 0; i
< ARRAY_SIZE(sc_table
); i
++) {
1774 const struct trace_syscall_entry
*entry
;
1775 const char *it_name
;
1777 entry
= &sc_table
[i
];
1780 it_name
= entry
->desc
->name
;
1781 it_name
+= strlen(SYSCALL_ENTRY_STR
);
1782 if (!strcmp(syscall_name
, it_name
)) {
1791 int get_compat_syscall_nr(const char *syscall_name
)
1793 int syscall_nr
= -1;
1796 for (i
= 0; i
< ARRAY_SIZE(compat_sc_table
); i
++) {
1797 const struct trace_syscall_entry
*entry
;
1798 const char *it_name
;
1800 entry
= &compat_sc_table
[i
];
1803 it_name
= entry
->desc
->name
;
1804 it_name
+= strlen(COMPAT_SYSCALL_ENTRY_STR
);
1805 if (!strcmp(syscall_name
, it_name
)) {
1814 uint32_t get_sc_tables_len(void)
1816 return ARRAY_SIZE(sc_table
) + ARRAY_SIZE(compat_sc_table
);
1820 const char *get_syscall_name(const char *desc_name
,
1821 enum lttng_syscall_abi abi
,
1822 enum lttng_syscall_entryexit entryexit
)
1824 size_t prefix_len
= 0;
1827 switch (entryexit
) {
1828 case LTTNG_SYSCALL_ENTRY
:
1830 case LTTNG_SYSCALL_ABI_NATIVE
:
1831 prefix_len
= strlen(SYSCALL_ENTRY_STR
);
1833 case LTTNG_SYSCALL_ABI_COMPAT
:
1834 prefix_len
= strlen(COMPAT_SYSCALL_ENTRY_STR
);
1838 case LTTNG_SYSCALL_EXIT
:
1840 case LTTNG_SYSCALL_ABI_NATIVE
:
1841 prefix_len
= strlen(SYSCALL_EXIT_STR
);
1843 case LTTNG_SYSCALL_ABI_COMPAT
:
1844 prefix_len
= strlen(COMPAT_SYSCALL_EXIT_STR
);
1849 WARN_ON_ONCE(prefix_len
== 0);
1850 return desc_name
+ prefix_len
;
1854 int lttng_syscall_filter_enable(
1855 struct lttng_syscall_filter
*filter
,
1856 const char *desc_name
, enum lttng_syscall_abi abi
,
1857 enum lttng_syscall_entryexit entryexit
)
1859 const char *syscall_name
;
1860 unsigned long *bitmap
;
1863 syscall_name
= get_syscall_name(desc_name
, abi
, entryexit
);
1866 case LTTNG_SYSCALL_ABI_NATIVE
:
1867 syscall_nr
= get_syscall_nr(syscall_name
);
1869 case LTTNG_SYSCALL_ABI_COMPAT
:
1870 syscall_nr
= get_compat_syscall_nr(syscall_name
);
1878 switch (entryexit
) {
1879 case LTTNG_SYSCALL_ENTRY
:
1881 case LTTNG_SYSCALL_ABI_NATIVE
:
1882 bitmap
= filter
->sc_entry
;
1884 case LTTNG_SYSCALL_ABI_COMPAT
:
1885 bitmap
= filter
->sc_compat_entry
;
1891 case LTTNG_SYSCALL_EXIT
:
1893 case LTTNG_SYSCALL_ABI_NATIVE
:
1894 bitmap
= filter
->sc_exit
;
1896 case LTTNG_SYSCALL_ABI_COMPAT
:
1897 bitmap
= filter
->sc_compat_exit
;
1906 if (test_bit(syscall_nr
, bitmap
))
1908 bitmap_set(bitmap
, syscall_nr
, 1);
1912 int lttng_syscall_filter_enable_event_notifier(
1913 struct lttng_event_notifier
*notifier
)
1915 struct lttng_event_notifier_group
*group
= notifier
->group
;
1916 unsigned int syscall_id
= notifier
->u
.syscall
.syscall_id
;
1917 struct hlist_head
*dispatch_list
;
1920 WARN_ON_ONCE(notifier
->instrumentation
!= LTTNG_KERNEL_SYSCALL
);
1922 ret
= lttng_syscall_filter_enable(group
->sc_filter
,
1923 notifier
->desc
->name
, notifier
->u
.syscall
.abi
,
1924 notifier
->u
.syscall
.entryexit
);
1929 switch (notifier
->u
.syscall
.entryexit
) {
1930 case LTTNG_SYSCALL_ENTRY
:
1931 switch (notifier
->u
.syscall
.abi
) {
1932 case LTTNG_SYSCALL_ABI_NATIVE
:
1933 dispatch_list
= &group
->event_notifier_syscall_dispatch
[syscall_id
];
1935 case LTTNG_SYSCALL_ABI_COMPAT
:
1936 dispatch_list
= &group
->event_notifier_compat_syscall_dispatch
[syscall_id
];
1940 case LTTNG_SYSCALL_EXIT
:
1941 switch (notifier
->u
.syscall
.abi
) {
1942 case LTTNG_SYSCALL_ABI_NATIVE
:
1943 dispatch_list
= &group
->event_notifier_exit_syscall_dispatch
[syscall_id
];
1945 case LTTNG_SYSCALL_ABI_COMPAT
:
1946 dispatch_list
= &group
->event_notifier_exit_compat_syscall_dispatch
[syscall_id
];
1952 hlist_add_head_rcu(¬ifier
->u
.syscall
.node
, dispatch_list
);
1958 int lttng_syscall_filter_enable_event(
1959 struct lttng_channel
*channel
,
1960 struct lttng_event
*event
)
1962 WARN_ON_ONCE(event
->instrumentation
!= LTTNG_KERNEL_SYSCALL
);
1964 return lttng_syscall_filter_enable(channel
->sc_filter
,
1965 event
->desc
->name
, event
->u
.syscall
.abi
,
1966 event
->u
.syscall
.entryexit
);
1970 int lttng_syscall_filter_disable(
1971 struct lttng_syscall_filter
*filter
,
1972 const char *desc_name
, enum lttng_syscall_abi abi
,
1973 enum lttng_syscall_entryexit entryexit
)
1975 const char *syscall_name
;
1976 unsigned long *bitmap
;
1979 syscall_name
= get_syscall_name(desc_name
, abi
, entryexit
);
1982 case LTTNG_SYSCALL_ABI_NATIVE
:
1983 syscall_nr
= get_syscall_nr(syscall_name
);
1985 case LTTNG_SYSCALL_ABI_COMPAT
:
1986 syscall_nr
= get_compat_syscall_nr(syscall_name
);
1994 switch (entryexit
) {
1995 case LTTNG_SYSCALL_ENTRY
:
1997 case LTTNG_SYSCALL_ABI_NATIVE
:
1998 bitmap
= filter
->sc_entry
;
2000 case LTTNG_SYSCALL_ABI_COMPAT
:
2001 bitmap
= filter
->sc_compat_entry
;
2007 case LTTNG_SYSCALL_EXIT
:
2009 case LTTNG_SYSCALL_ABI_NATIVE
:
2010 bitmap
= filter
->sc_exit
;
2012 case LTTNG_SYSCALL_ABI_COMPAT
:
2013 bitmap
= filter
->sc_compat_exit
;
2022 if (!test_bit(syscall_nr
, bitmap
))
2024 bitmap_clear(bitmap
, syscall_nr
, 1);
2029 int lttng_syscall_filter_disable_event_notifier(
2030 struct lttng_event_notifier
*notifier
)
2032 struct lttng_event_notifier_group
*group
= notifier
->group
;
2035 WARN_ON_ONCE(notifier
->instrumentation
!= LTTNG_KERNEL_SYSCALL
);
2037 ret
= lttng_syscall_filter_disable(group
->sc_filter
,
2038 notifier
->desc
->name
, notifier
->u
.syscall
.abi
,
2039 notifier
->u
.syscall
.entryexit
);
2040 WARN_ON_ONCE(ret
!= 0);
2042 hlist_del_rcu(¬ifier
->u
.syscall
.node
);
2046 int lttng_syscall_filter_disable_event(
2047 struct lttng_channel
*channel
,
2048 struct lttng_event
*event
)
2050 return lttng_syscall_filter_disable(channel
->sc_filter
,
2051 event
->desc
->name
, event
->u
.syscall
.abi
,
2052 event
->u
.syscall
.entryexit
);
2056 const struct trace_syscall_entry
*syscall_list_get_entry(loff_t
*pos
)
2058 const struct trace_syscall_entry
*entry
;
2061 for (entry
= sc_table
;
2062 entry
< sc_table
+ ARRAY_SIZE(sc_table
);
2067 for (entry
= compat_sc_table
;
2068 entry
< compat_sc_table
+ ARRAY_SIZE(compat_sc_table
);
2078 void *syscall_list_start(struct seq_file
*m
, loff_t
*pos
)
2080 return (void *) syscall_list_get_entry(pos
);
2084 void *syscall_list_next(struct seq_file
*m
, void *p
, loff_t
*ppos
)
2087 return (void *) syscall_list_get_entry(ppos
);
2091 void syscall_list_stop(struct seq_file
*m
, void *p
)
2096 int get_sc_table(const struct trace_syscall_entry
*entry
,
2097 const struct trace_syscall_entry
**table
,
2098 unsigned int *bitness
)
2100 if (entry
>= sc_table
&& entry
< sc_table
+ ARRAY_SIZE(sc_table
)) {
2102 *bitness
= BITS_PER_LONG
;
2107 if (!(entry
>= compat_sc_table
2108 && entry
< compat_sc_table
+ ARRAY_SIZE(compat_sc_table
))) {
2114 *table
= compat_sc_table
;
2119 int syscall_list_show(struct seq_file
*m
, void *p
)
2121 const struct trace_syscall_entry
*table
, *entry
= p
;
2122 unsigned int bitness
;
2123 unsigned long index
;
2127 ret
= get_sc_table(entry
, &table
, &bitness
);
2132 if (table
== sc_table
) {
2133 index
= entry
- table
;
2134 name
= &entry
->desc
->name
[strlen(SYSCALL_ENTRY_STR
)];
2136 index
= (entry
- table
) + ARRAY_SIZE(sc_table
);
2137 name
= &entry
->desc
->name
[strlen(COMPAT_SYSCALL_ENTRY_STR
)];
2139 seq_printf(m
, "syscall { index = %lu; name = %s; bitness = %u; };\n",
2140 index
, name
, bitness
);
2145 const struct seq_operations lttng_syscall_list_seq_ops
= {
2146 .start
= syscall_list_start
,
2147 .next
= syscall_list_next
,
2148 .stop
= syscall_list_stop
,
2149 .show
= syscall_list_show
,
2153 int lttng_syscall_list_open(struct inode
*inode
, struct file
*file
)
2155 return seq_open(file
, <tng_syscall_list_seq_ops
);
2158 const struct file_operations lttng_syscall_list_fops
= {
2159 .owner
= THIS_MODULE
,
2160 .open
= lttng_syscall_list_open
,
2162 .llseek
= seq_lseek
,
2163 .release
= seq_release
,
2167 * A syscall is enabled if it is traced for either entry or exit.
2169 long lttng_channel_syscall_mask(struct lttng_channel
*channel
,
2170 struct lttng_kernel_syscall_mask __user
*usyscall_mask
)
2172 uint32_t len
, sc_tables_len
, bitmask_len
;
2175 struct lttng_syscall_filter
*filter
;
2177 ret
= get_user(len
, &usyscall_mask
->len
);
2180 sc_tables_len
= get_sc_tables_len();
2181 bitmask_len
= ALIGN(sc_tables_len
, 8) >> 3;
2182 if (len
< sc_tables_len
) {
2183 return put_user(sc_tables_len
, &usyscall_mask
->len
);
2185 /* Array is large enough, we can copy array to user-space. */
2186 tmp_mask
= kzalloc(bitmask_len
, GFP_KERNEL
);
2189 filter
= channel
->sc_filter
;
2191 for (bit
= 0; bit
< ARRAY_SIZE(sc_table
); bit
++) {
2194 if (channel
->sc_table
) {
2195 if (!(READ_ONCE(channel
->syscall_all_entry
)
2196 || READ_ONCE(channel
->syscall_all_exit
)) && filter
)
2197 state
= test_bit(bit
, filter
->sc_entry
)
2198 || test_bit(bit
, filter
->sc_exit
);
2204 bt_bitfield_write_be(tmp_mask
, char, bit
, 1, state
);
2206 for (; bit
< sc_tables_len
; bit
++) {
2209 if (channel
->compat_sc_table
) {
2210 if (!(READ_ONCE(channel
->syscall_all_entry
)
2211 || READ_ONCE(channel
->syscall_all_exit
)) && filter
)
2212 state
= test_bit(bit
- ARRAY_SIZE(sc_table
),
2213 filter
->sc_compat_entry
)
2214 || test_bit(bit
- ARRAY_SIZE(sc_table
),
2215 filter
->sc_compat_exit
);
2221 bt_bitfield_write_be(tmp_mask
, char, bit
, 1, state
);
2223 if (copy_to_user(usyscall_mask
->mask
, tmp_mask
, bitmask_len
))
2229 int lttng_abi_syscall_list(void)
2231 struct file
*syscall_list_file
;
2234 file_fd
= lttng_get_unused_fd();
2240 syscall_list_file
= anon_inode_getfile("[lttng_syscall_list]",
2241 <tng_syscall_list_fops
,
2243 if (IS_ERR(syscall_list_file
)) {
2244 ret
= PTR_ERR(syscall_list_file
);
2247 ret
= lttng_syscall_list_fops
.open(NULL
, syscall_list_file
);
2250 fd_install(file_fd
, syscall_list_file
);
2254 fput(syscall_list_file
);
2256 put_unused_fd(file_fd
);