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 lttng_event
*event
,
392 struct pt_regs
*regs
, long id
)
394 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
396 lttng_syscall_get_arguments(current
, regs
, args
);
397 if (unlikely(in_compat_syscall()))
398 __event_probe__compat_syscall_entry_unknown(event
, id
, args
);
400 __event_probe__syscall_entry_unknown(event
, id
, args
);
403 static void syscall_entry_event_notifier_unknown(
404 struct hlist_head
*unknown_dispatch_list_head
,
405 struct pt_regs
*regs
, long id
)
407 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
408 struct lttng_event_notifier
*notifier
;
410 lttng_syscall_get_arguments(current
, regs
, args
);
411 lttng_hlist_for_each_entry_rcu(notifier
, unknown_dispatch_list_head
, u
.syscall
.node
) {
412 if (unlikely(in_compat_syscall()))
413 __event_notifier_probe__compat_syscall_entry_unknown(notifier
, id
, args
);
415 __event_notifier_probe__syscall_entry_unknown(notifier
, id
, args
);
419 static void syscall_exit_event_notifier_unknown(
420 struct hlist_head
*unknown_dispatch_list_head
,
421 struct pt_regs
*regs
, long id
, long ret
)
423 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
424 struct lttng_event_notifier
*notifier
;
426 lttng_syscall_get_arguments(current
, regs
, args
);
427 lttng_hlist_for_each_entry_rcu(notifier
, unknown_dispatch_list_head
, u
.syscall
.node
) {
428 if (unlikely(in_compat_syscall()))
429 __event_notifier_probe__compat_syscall_exit_unknown(notifier
, id
, ret
, args
);
431 __event_notifier_probe__syscall_exit_unknown(notifier
, id
, ret
, args
);
435 static __always_inline
436 void syscall_entry_call_func(void *func
, unsigned int nrargs
, void *data
,
437 struct pt_regs
*regs
)
442 void (*fptr
)(void *__data
) = func
;
449 void (*fptr
)(void *__data
, unsigned long arg0
) = func
;
450 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
452 lttng_syscall_get_arguments(current
, regs
, args
);
458 void (*fptr
)(void *__data
,
460 unsigned long arg1
) = func
;
461 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
463 lttng_syscall_get_arguments(current
, regs
, args
);
464 fptr(data
, args
[0], args
[1]);
469 void (*fptr
)(void *__data
,
472 unsigned long arg2
) = func
;
473 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
475 lttng_syscall_get_arguments(current
, regs
, args
);
476 fptr(data
, args
[0], args
[1], args
[2]);
481 void (*fptr
)(void *__data
,
485 unsigned long arg3
) = func
;
486 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
488 lttng_syscall_get_arguments(current
, regs
, args
);
489 fptr(data
, args
[0], args
[1], args
[2], args
[3]);
494 void (*fptr
)(void *__data
,
499 unsigned long arg4
) = func
;
500 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
502 lttng_syscall_get_arguments(current
, regs
, args
);
503 fptr(data
, args
[0], args
[1], args
[2], args
[3], args
[4]);
508 void (*fptr
)(void *__data
,
514 unsigned long arg5
) = func
;
515 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
517 lttng_syscall_get_arguments(current
, regs
, args
);
518 fptr(data
, args
[0], args
[1], args
[2],
519 args
[3], args
[4], args
[5]);
527 static __always_inline
528 void syscall_entry_event_notifier_call_func(struct hlist_head
*dispatch_list
,
529 void *func
, unsigned int nrargs
, struct pt_regs
*regs
)
531 struct lttng_event_notifier
*notifier
;
536 void (*fptr
)(void *__data
) = func
;
538 lttng_hlist_for_each_entry_rcu(notifier
, dispatch_list
, u
.syscall
.node
)
544 void (*fptr
)(void *__data
, unsigned long arg0
) = func
;
545 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
547 lttng_syscall_get_arguments(current
, regs
, args
);
548 lttng_hlist_for_each_entry_rcu(notifier
, dispatch_list
, u
.syscall
.node
)
549 fptr(notifier
, args
[0]);
554 void (*fptr
)(void *__data
,
556 unsigned long arg1
) = func
;
557 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
559 lttng_syscall_get_arguments(current
, regs
, args
);
560 lttng_hlist_for_each_entry_rcu(notifier
, dispatch_list
, u
.syscall
.node
)
561 fptr(notifier
, args
[0], args
[1]);
566 void (*fptr
)(void *__data
,
569 unsigned long arg2
) = 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], args
[2]);
579 void (*fptr
)(void *__data
,
583 unsigned long arg3
) = func
;
584 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
586 lttng_syscall_get_arguments(current
, regs
, args
);
587 lttng_hlist_for_each_entry_rcu(notifier
, dispatch_list
, u
.syscall
.node
)
588 fptr(notifier
, args
[0], args
[1], args
[2], args
[3]);
593 void (*fptr
)(void *__data
,
598 unsigned long arg4
) = func
;
599 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
601 lttng_syscall_get_arguments(current
, regs
, args
);
602 lttng_hlist_for_each_entry_rcu(notifier
, dispatch_list
, u
.syscall
.node
)
603 fptr(notifier
, args
[0], args
[1], args
[2], args
[3], args
[4]);
608 void (*fptr
)(void *__data
,
614 unsigned long arg5
) = func
;
615 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
617 lttng_syscall_get_arguments(current
, regs
, args
);
618 lttng_hlist_for_each_entry_rcu(notifier
, dispatch_list
, u
.syscall
.node
)
619 fptr(notifier
, args
[0], args
[1], args
[2], args
[3], args
[4], args
[5]);
627 void syscall_entry_event_probe(void *__data
, struct pt_regs
*regs
, long id
)
629 struct lttng_channel
*chan
= __data
;
630 struct lttng_event
*event
, *unknown_event
;
631 const struct trace_syscall_entry
*table
, *entry
;
634 if (unlikely(in_compat_syscall())) {
635 struct lttng_syscall_filter
*filter
= chan
->sc_filter
;
637 if (id
< 0 || id
>= NR_compat_syscalls
638 || (!READ_ONCE(chan
->syscall_all
) && !test_bit(id
, filter
->sc_compat_entry
))) {
639 /* System call filtered out. */
642 table
= compat_sc_table
;
643 table_len
= ARRAY_SIZE(compat_sc_table
);
644 unknown_event
= chan
->sc_compat_unknown
;
646 struct lttng_syscall_filter
*filter
= chan
->sc_filter
;
648 if (id
< 0 || id
>= NR_syscalls
649 || (!READ_ONCE(chan
->syscall_all
) && !test_bit(id
, filter
->sc_entry
))) {
650 /* System call filtered out. */
654 table_len
= ARRAY_SIZE(sc_table
);
655 unknown_event
= chan
->sc_unknown
;
657 if (unlikely(id
< 0 || id
>= table_len
)) {
658 syscall_entry_event_unknown(unknown_event
, regs
, id
);
661 if (unlikely(in_compat_syscall()))
662 event
= chan
->compat_sc_table
[id
];
664 event
= chan
->sc_table
[id
];
665 if (unlikely(!event
)) {
666 syscall_entry_event_unknown(unknown_event
, regs
, id
);
670 WARN_ON_ONCE(!entry
->event_func
);
671 syscall_entry_call_func(entry
->event_func
, entry
->nrargs
, event
, regs
);
674 void syscall_entry_event_notifier_probe(void *__data
, struct pt_regs
*regs
,
677 struct lttng_event_notifier_group
*group
= __data
;
678 const struct trace_syscall_entry
*table
, *entry
;
679 struct hlist_head
*dispatch_list
, *unknown_dispatch_list
;
682 if (unlikely(in_compat_syscall())) {
683 struct lttng_syscall_filter
*filter
= group
->sc_filter
;
685 if (id
< 0 || id
>= NR_compat_syscalls
686 || (!READ_ONCE(group
->syscall_all_entry
) &&
687 !test_bit(id
, filter
->sc_compat_entry
))) {
688 /* System call filtered out. */
691 table
= compat_sc_table
;
692 table_len
= ARRAY_SIZE(compat_sc_table
);
693 unknown_dispatch_list
= &group
->event_notifier_compat_unknown_syscall_dispatch
;
695 struct lttng_syscall_filter
*filter
= group
->sc_filter
;
697 if (id
< 0 || id
>= NR_syscalls
698 || (!READ_ONCE(group
->syscall_all_entry
) &&
699 !test_bit(id
, filter
->sc_entry
))) {
700 /* System call filtered out. */
704 table_len
= ARRAY_SIZE(sc_table
);
705 unknown_dispatch_list
= &group
->event_notifier_unknown_syscall_dispatch
;
707 /* Check if the syscall id is out of bound. */
708 if (unlikely(id
< 0 || id
>= table_len
)) {
709 syscall_entry_event_notifier_unknown(unknown_dispatch_list
,
715 if (!entry
->event_notifier_func
) {
716 syscall_entry_event_notifier_unknown(unknown_dispatch_list
,
721 if (unlikely(in_compat_syscall())) {
722 dispatch_list
= &group
->event_notifier_compat_syscall_dispatch
[id
];
724 dispatch_list
= &group
->event_notifier_syscall_dispatch
[id
];
726 if (unlikely(hlist_empty(dispatch_list
)))
729 syscall_entry_event_notifier_call_func(dispatch_list
,
730 entry
->event_notifier_func
, entry
->nrargs
, regs
);
733 static void syscall_exit_event_unknown(struct lttng_event
*event
,
734 struct pt_regs
*regs
, long id
, long ret
)
736 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
738 lttng_syscall_get_arguments(current
, regs
, args
);
739 if (unlikely(in_compat_syscall()))
740 __event_probe__compat_syscall_exit_unknown(event
, id
, ret
,
743 __event_probe__syscall_exit_unknown(event
, id
, ret
, args
);
746 void syscall_exit_event_probe(void *__data
, struct pt_regs
*regs
, long ret
)
748 struct lttng_channel
*chan
= __data
;
749 struct lttng_event
*event
, *unknown_event
;
750 const struct trace_syscall_entry
*table
, *entry
;
754 id
= syscall_get_nr(current
, regs
);
755 if (unlikely(in_compat_syscall())) {
756 struct lttng_syscall_filter
*filter
= chan
->sc_filter
;
758 if (id
< 0 || id
>= NR_compat_syscalls
759 || (!READ_ONCE(chan
->syscall_all
) && !test_bit(id
, filter
->sc_compat_exit
))) {
760 /* System call filtered out. */
763 table
= compat_sc_exit_table
;
764 table_len
= ARRAY_SIZE(compat_sc_exit_table
);
765 unknown_event
= chan
->compat_sc_exit_unknown
;
767 struct lttng_syscall_filter
*filter
= chan
->sc_filter
;
769 if (id
< 0 || id
>= NR_syscalls
770 || (!READ_ONCE(chan
->syscall_all
) && !test_bit(id
, filter
->sc_exit
))) {
771 /* System call filtered out. */
774 table
= sc_exit_table
;
775 table_len
= ARRAY_SIZE(sc_exit_table
);
776 unknown_event
= chan
->sc_exit_unknown
;
778 if (unlikely(id
< 0 || id
>= table_len
)) {
779 syscall_exit_event_unknown(unknown_event
, regs
, id
, ret
);
782 if (unlikely(in_compat_syscall()))
783 event
= chan
->compat_sc_exit_table
[id
];
785 event
= chan
->sc_exit_table
[id
];
786 if (unlikely(!event
)) {
787 syscall_exit_event_unknown(unknown_event
, regs
, id
, ret
);
791 WARN_ON_ONCE(!entry
->event_func
);
793 switch (entry
->nrargs
) {
796 void (*fptr
)(void *__data
, long ret
) = entry
->event_func
;
803 void (*fptr
)(void *__data
,
805 unsigned long arg0
) = entry
->event_func
;
806 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
808 lttng_syscall_get_arguments(current
, regs
, args
);
809 fptr(event
, ret
, args
[0]);
814 void (*fptr
)(void *__data
,
817 unsigned long arg1
) = entry
->event_func
;
818 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
820 lttng_syscall_get_arguments(current
, regs
, args
);
821 fptr(event
, ret
, args
[0], args
[1]);
826 void (*fptr
)(void *__data
,
830 unsigned long arg2
) = entry
->event_func
;
831 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
833 lttng_syscall_get_arguments(current
, regs
, args
);
834 fptr(event
, ret
, args
[0], args
[1], args
[2]);
839 void (*fptr
)(void *__data
,
844 unsigned long arg3
) = entry
->event_func
;
845 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
847 lttng_syscall_get_arguments(current
, regs
, args
);
848 fptr(event
, ret
, args
[0], args
[1], args
[2], args
[3]);
853 void (*fptr
)(void *__data
,
859 unsigned long arg4
) = entry
->event_func
;
860 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
862 lttng_syscall_get_arguments(current
, regs
, args
);
863 fptr(event
, ret
, args
[0], args
[1], args
[2], args
[3], args
[4]);
868 void (*fptr
)(void *__data
,
875 unsigned long arg5
) = entry
->event_func
;
876 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
878 lttng_syscall_get_arguments(current
, regs
, args
);
879 fptr(event
, ret
, args
[0], args
[1], args
[2],
880 args
[3], args
[4], args
[5]);
888 static __always_inline
889 void syscall_exit_event_notifier_call_func(struct hlist_head
*dispatch_list
,
890 void *func
, unsigned int nrargs
, struct pt_regs
*regs
, long ret
)
892 struct lttng_event_notifier
*notifier
;
897 void (*fptr
)(void *__data
, long ret
) = func
;
899 lttng_hlist_for_each_entry_rcu(notifier
, dispatch_list
, u
.syscall
.node
)
905 void (*fptr
)(void *__data
, long ret
, unsigned long arg0
) = func
;
906 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
908 lttng_syscall_get_arguments(current
, regs
, args
);
909 lttng_hlist_for_each_entry_rcu(notifier
, dispatch_list
, u
.syscall
.node
)
910 fptr(notifier
, ret
, args
[0]);
915 void (*fptr
)(void *__data
,
918 unsigned long arg1
) = func
;
919 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
921 lttng_syscall_get_arguments(current
, regs
, args
);
922 lttng_hlist_for_each_entry_rcu(notifier
, dispatch_list
, u
.syscall
.node
)
923 fptr(notifier
, ret
, args
[0], args
[1]);
928 void (*fptr
)(void *__data
,
932 unsigned long arg2
) = func
;
933 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
935 lttng_syscall_get_arguments(current
, regs
, args
);
936 lttng_hlist_for_each_entry_rcu(notifier
, dispatch_list
, u
.syscall
.node
)
937 fptr(notifier
, ret
, args
[0], args
[1], args
[2]);
942 void (*fptr
)(void *__data
,
947 unsigned long arg3
) = func
;
948 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
950 lttng_syscall_get_arguments(current
, regs
, args
);
951 lttng_hlist_for_each_entry_rcu(notifier
, dispatch_list
, u
.syscall
.node
)
952 fptr(notifier
, ret
, args
[0], args
[1], args
[2], args
[3]);
957 void (*fptr
)(void *__data
,
963 unsigned long arg4
) = func
;
964 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
966 lttng_syscall_get_arguments(current
, regs
, args
);
967 lttng_hlist_for_each_entry_rcu(notifier
, dispatch_list
, u
.syscall
.node
)
968 fptr(notifier
, ret
, args
[0], args
[1], args
[2], args
[3], args
[4]);
973 void (*fptr
)(void *__data
,
980 unsigned long arg5
) = func
;
981 unsigned long args
[LTTNG_SYSCALL_NR_ARGS
];
983 lttng_syscall_get_arguments(current
, regs
, args
);
984 lttng_hlist_for_each_entry_rcu(notifier
, dispatch_list
, u
.syscall
.node
)
985 fptr(notifier
, ret
, args
[0], args
[1], args
[2], args
[3], args
[4], args
[5]);
994 void syscall_exit_event_notifier_probe(void *__data
, struct pt_regs
*regs
,
997 struct lttng_event_notifier_group
*group
= __data
;
998 const struct trace_syscall_entry
*table
, *entry
;
999 struct hlist_head
*dispatch_list
, *unknown_dispatch_list
;
1003 id
= syscall_get_nr(current
, regs
);
1005 if (unlikely(in_compat_syscall())) {
1006 struct lttng_syscall_filter
*filter
= group
->sc_filter
;
1008 if (id
< 0 || id
>= NR_compat_syscalls
1009 || (!READ_ONCE(group
->syscall_all_exit
) &&
1010 !test_bit(id
, filter
->sc_compat_exit
))) {
1011 /* System call filtered out. */
1014 table
= compat_sc_exit_table
;
1015 table_len
= ARRAY_SIZE(compat_sc_exit_table
);
1016 unknown_dispatch_list
= &group
->event_notifier_exit_compat_unknown_syscall_dispatch
;
1018 struct lttng_syscall_filter
*filter
= group
->sc_filter
;
1020 if (id
< 0 || id
>= NR_syscalls
1021 || (!READ_ONCE(group
->syscall_all_exit
) &&
1022 !test_bit(id
, filter
->sc_exit
))) {
1023 /* System call filtered out. */
1026 table
= sc_exit_table
;
1027 table_len
= ARRAY_SIZE(sc_exit_table
);
1028 unknown_dispatch_list
= &group
->event_notifier_exit_unknown_syscall_dispatch
;
1030 /* Check if the syscall id is out of bound. */
1031 if (unlikely(id
< 0 || id
>= table_len
)) {
1032 syscall_exit_event_notifier_unknown(unknown_dispatch_list
,
1038 if (!entry
->event_notifier_func
) {
1039 syscall_entry_event_notifier_unknown(unknown_dispatch_list
,
1044 if (unlikely(in_compat_syscall())) {
1045 dispatch_list
= &group
->event_notifier_exit_compat_syscall_dispatch
[id
];
1047 dispatch_list
= &group
->event_notifier_exit_syscall_dispatch
[id
];
1049 if (unlikely(hlist_empty(dispatch_list
)))
1052 syscall_exit_event_notifier_call_func(dispatch_list
,
1053 entry
->event_notifier_func
, entry
->nrargs
, regs
, ret
);
1056 * noinline to diminish caller stack size.
1057 * Should be called with sessions lock held.
1060 int fill_event_table(const struct trace_syscall_entry
*table
, size_t table_len
,
1061 struct lttng_event
**chan_table
, struct lttng_channel
*chan
,
1062 void *filter
, enum sc_type type
)
1064 const struct lttng_event_desc
*desc
;
1067 /* Allocate events for each syscall, insert into table */
1068 for (i
= 0; i
< table_len
; i
++) {
1069 struct lttng_kernel_event ev
;
1070 desc
= table
[i
].desc
;
1073 /* Unknown syscall */
1077 * Skip those already populated by previous failed
1078 * register for this channel.
1082 memset(&ev
, 0, sizeof(ev
));
1085 ev
.u
.syscall
.entryexit
= LTTNG_KERNEL_SYSCALL_ENTRY
;
1086 ev
.u
.syscall
.abi
= LTTNG_KERNEL_SYSCALL_ABI_NATIVE
;
1089 ev
.u
.syscall
.entryexit
= LTTNG_KERNEL_SYSCALL_EXIT
;
1090 ev
.u
.syscall
.abi
= LTTNG_KERNEL_SYSCALL_ABI_NATIVE
;
1092 case SC_TYPE_COMPAT_ENTRY
:
1093 ev
.u
.syscall
.entryexit
= LTTNG_KERNEL_SYSCALL_ENTRY
;
1094 ev
.u
.syscall
.abi
= LTTNG_KERNEL_SYSCALL_ABI_COMPAT
;
1096 case SC_TYPE_COMPAT_EXIT
:
1097 ev
.u
.syscall
.entryexit
= LTTNG_KERNEL_SYSCALL_EXIT
;
1098 ev
.u
.syscall
.abi
= LTTNG_KERNEL_SYSCALL_ABI_COMPAT
;
1101 strncpy(ev
.name
, desc
->name
, LTTNG_KERNEL_SYM_NAME_LEN
- 1);
1102 ev
.name
[LTTNG_KERNEL_SYM_NAME_LEN
- 1] = '\0';
1103 ev
.instrumentation
= LTTNG_KERNEL_SYSCALL
;
1104 chan_table
[i
] = _lttng_event_create(chan
, &ev
, filter
,
1105 desc
, ev
.instrumentation
);
1106 WARN_ON_ONCE(!chan_table
[i
]);
1107 if (IS_ERR(chan_table
[i
])) {
1109 * If something goes wrong in event registration
1110 * after the first one, we have no choice but to
1111 * leave the previous events in there, until
1112 * deleted by session teardown.
1114 return PTR_ERR(chan_table
[i
]);
1121 * Should be called with sessions lock held.
1123 int lttng_syscalls_register_event(struct lttng_channel
*chan
, void *filter
)
1125 struct lttng_kernel_event ev
;
1128 wrapper_vmalloc_sync_mappings();
1130 if (!chan
->sc_table
) {
1131 /* create syscall table mapping syscall to events */
1132 chan
->sc_table
= kzalloc(sizeof(struct lttng_event
*)
1133 * ARRAY_SIZE(sc_table
), GFP_KERNEL
);
1134 if (!chan
->sc_table
)
1137 if (!chan
->sc_exit_table
) {
1138 /* create syscall table mapping syscall to events */
1139 chan
->sc_exit_table
= kzalloc(sizeof(struct lttng_event
*)
1140 * ARRAY_SIZE(sc_exit_table
), GFP_KERNEL
);
1141 if (!chan
->sc_exit_table
)
1146 #ifdef CONFIG_COMPAT
1147 if (!chan
->compat_sc_table
) {
1148 /* create syscall table mapping compat syscall to events */
1149 chan
->compat_sc_table
= kzalloc(sizeof(struct lttng_event
*)
1150 * ARRAY_SIZE(compat_sc_table
), GFP_KERNEL
);
1151 if (!chan
->compat_sc_table
)
1155 if (!chan
->compat_sc_exit_table
) {
1156 /* create syscall table mapping compat syscall to events */
1157 chan
->compat_sc_exit_table
= kzalloc(sizeof(struct lttng_event
*)
1158 * ARRAY_SIZE(compat_sc_exit_table
), GFP_KERNEL
);
1159 if (!chan
->compat_sc_exit_table
)
1163 if (!chan
->sc_unknown
) {
1164 const struct lttng_event_desc
*desc
=
1165 &__event_desc___syscall_entry_unknown
;
1167 memset(&ev
, 0, sizeof(ev
));
1168 strncpy(ev
.name
, desc
->name
, LTTNG_KERNEL_SYM_NAME_LEN
);
1169 ev
.name
[LTTNG_KERNEL_SYM_NAME_LEN
- 1] = '\0';
1170 ev
.instrumentation
= LTTNG_KERNEL_SYSCALL
;
1171 ev
.u
.syscall
.entryexit
= LTTNG_KERNEL_SYSCALL_ENTRY
;
1172 ev
.u
.syscall
.abi
= LTTNG_KERNEL_SYSCALL_ABI_NATIVE
;
1173 chan
->sc_unknown
= _lttng_event_create(chan
, &ev
, filter
,
1175 ev
.instrumentation
);
1176 WARN_ON_ONCE(!chan
->sc_unknown
);
1177 if (IS_ERR(chan
->sc_unknown
)) {
1178 return PTR_ERR(chan
->sc_unknown
);
1182 if (!chan
->sc_compat_unknown
) {
1183 const struct lttng_event_desc
*desc
=
1184 &__event_desc___compat_syscall_entry_unknown
;
1186 memset(&ev
, 0, sizeof(ev
));
1187 strncpy(ev
.name
, desc
->name
, LTTNG_KERNEL_SYM_NAME_LEN
);
1188 ev
.name
[LTTNG_KERNEL_SYM_NAME_LEN
- 1] = '\0';
1189 ev
.instrumentation
= LTTNG_KERNEL_SYSCALL
;
1190 ev
.u
.syscall
.entryexit
= LTTNG_KERNEL_SYSCALL_ENTRY
;
1191 ev
.u
.syscall
.abi
= LTTNG_KERNEL_SYSCALL_ABI_COMPAT
;
1192 chan
->sc_compat_unknown
= _lttng_event_create(chan
, &ev
, filter
,
1194 ev
.instrumentation
);
1195 WARN_ON_ONCE(!chan
->sc_unknown
);
1196 if (IS_ERR(chan
->sc_compat_unknown
)) {
1197 return PTR_ERR(chan
->sc_compat_unknown
);
1201 if (!chan
->compat_sc_exit_unknown
) {
1202 const struct lttng_event_desc
*desc
=
1203 &__event_desc___compat_syscall_exit_unknown
;
1205 memset(&ev
, 0, sizeof(ev
));
1206 strncpy(ev
.name
, desc
->name
, LTTNG_KERNEL_SYM_NAME_LEN
);
1207 ev
.name
[LTTNG_KERNEL_SYM_NAME_LEN
- 1] = '\0';
1208 ev
.instrumentation
= LTTNG_KERNEL_SYSCALL
;
1209 ev
.u
.syscall
.entryexit
= LTTNG_KERNEL_SYSCALL_EXIT
;
1210 ev
.u
.syscall
.abi
= LTTNG_KERNEL_SYSCALL_ABI_COMPAT
;
1211 chan
->compat_sc_exit_unknown
= _lttng_event_create(chan
, &ev
,
1213 ev
.instrumentation
);
1214 WARN_ON_ONCE(!chan
->compat_sc_exit_unknown
);
1215 if (IS_ERR(chan
->compat_sc_exit_unknown
)) {
1216 return PTR_ERR(chan
->compat_sc_exit_unknown
);
1220 if (!chan
->sc_exit_unknown
) {
1221 const struct lttng_event_desc
*desc
=
1222 &__event_desc___syscall_exit_unknown
;
1224 memset(&ev
, 0, sizeof(ev
));
1225 strncpy(ev
.name
, desc
->name
, LTTNG_KERNEL_SYM_NAME_LEN
);
1226 ev
.name
[LTTNG_KERNEL_SYM_NAME_LEN
- 1] = '\0';
1227 ev
.instrumentation
= LTTNG_KERNEL_SYSCALL
;
1228 ev
.u
.syscall
.entryexit
= LTTNG_KERNEL_SYSCALL_EXIT
;
1229 ev
.u
.syscall
.abi
= LTTNG_KERNEL_SYSCALL_ABI_NATIVE
;
1230 chan
->sc_exit_unknown
= _lttng_event_create(chan
, &ev
, filter
,
1231 desc
, ev
.instrumentation
);
1232 WARN_ON_ONCE(!chan
->sc_exit_unknown
);
1233 if (IS_ERR(chan
->sc_exit_unknown
)) {
1234 return PTR_ERR(chan
->sc_exit_unknown
);
1238 ret
= fill_event_table(sc_table
, ARRAY_SIZE(sc_table
),
1239 chan
->sc_table
, chan
, filter
, SC_TYPE_ENTRY
);
1242 ret
= fill_event_table(sc_exit_table
, ARRAY_SIZE(sc_exit_table
),
1243 chan
->sc_exit_table
, chan
, filter
, SC_TYPE_EXIT
);
1247 #ifdef CONFIG_COMPAT
1248 ret
= fill_event_table(compat_sc_table
, ARRAY_SIZE(compat_sc_table
),
1249 chan
->compat_sc_table
, chan
, filter
,
1250 SC_TYPE_COMPAT_ENTRY
);
1253 ret
= fill_event_table(compat_sc_exit_table
, ARRAY_SIZE(compat_sc_exit_table
),
1254 chan
->compat_sc_exit_table
, chan
, filter
,
1255 SC_TYPE_COMPAT_EXIT
);
1260 if (!chan
->sc_filter
) {
1261 chan
->sc_filter
= kzalloc(sizeof(struct lttng_syscall_filter
),
1263 if (!chan
->sc_filter
)
1267 if (!chan
->sys_enter_registered
) {
1268 ret
= lttng_wrapper_tracepoint_probe_register("sys_enter",
1269 (void *) syscall_entry_event_probe
, chan
);
1272 chan
->sys_enter_registered
= 1;
1275 * We change the name of sys_exit tracepoint due to namespace
1276 * conflict with sys_exit syscall entry.
1278 if (!chan
->sys_exit_registered
) {
1279 ret
= lttng_wrapper_tracepoint_probe_register("sys_exit",
1280 (void *) syscall_exit_event_probe
, chan
);
1282 WARN_ON_ONCE(lttng_wrapper_tracepoint_probe_unregister("sys_enter",
1283 (void *) syscall_entry_event_probe
, chan
));
1286 chan
->sys_exit_registered
= 1;
1292 * Should be called with sessions lock held.
1294 int lttng_syscalls_register_event_notifier(
1295 struct lttng_event_notifier_enabler
*event_notifier_enabler
,
1298 struct lttng_event_notifier_group
*group
= event_notifier_enabler
->group
;
1302 wrapper_vmalloc_sync_mappings();
1304 if (!group
->event_notifier_syscall_dispatch
) {
1305 group
->event_notifier_syscall_dispatch
=
1306 kzalloc(sizeof(struct hlist_head
) * ARRAY_SIZE(sc_table
),
1308 if (!group
->event_notifier_syscall_dispatch
)
1311 /* Initialize all list_head */
1312 for (i
= 0; i
< ARRAY_SIZE(sc_table
); i
++)
1313 INIT_HLIST_HEAD(&group
->event_notifier_syscall_dispatch
[i
]);
1315 /* Init the unknown syscall notifier list. */
1316 INIT_HLIST_HEAD(&group
->event_notifier_unknown_syscall_dispatch
);
1319 if (!group
->event_notifier_exit_syscall_dispatch
) {
1320 group
->event_notifier_exit_syscall_dispatch
=
1321 kzalloc(sizeof(struct hlist_head
) * ARRAY_SIZE(sc_table
),
1323 if (!group
->event_notifier_exit_syscall_dispatch
)
1326 /* Initialize all list_head */
1327 for (i
= 0; i
< ARRAY_SIZE(sc_table
); i
++)
1328 INIT_HLIST_HEAD(&group
->event_notifier_exit_syscall_dispatch
[i
]);
1330 /* Init the unknown exit syscall notifier list. */
1331 INIT_HLIST_HEAD(&group
->event_notifier_exit_unknown_syscall_dispatch
);
1334 #ifdef CONFIG_COMPAT
1335 if (!group
->event_notifier_compat_syscall_dispatch
) {
1336 group
->event_notifier_compat_syscall_dispatch
=
1337 kzalloc(sizeof(struct hlist_head
) * ARRAY_SIZE(compat_sc_table
),
1339 if (!group
->event_notifier_syscall_dispatch
)
1342 /* Initialize all list_head */
1343 for (i
= 0; i
< ARRAY_SIZE(compat_sc_table
); i
++)
1344 INIT_HLIST_HEAD(&group
->event_notifier_compat_syscall_dispatch
[i
]);
1346 /* Init the unknown syscall notifier list. */
1347 INIT_HLIST_HEAD(&group
->event_notifier_compat_unknown_syscall_dispatch
);
1350 if (!group
->event_notifier_exit_compat_syscall_dispatch
) {
1351 group
->event_notifier_exit_compat_syscall_dispatch
=
1352 kzalloc(sizeof(struct hlist_head
) * ARRAY_SIZE(compat_sc_exit_table
),
1354 if (!group
->event_notifier_exit_syscall_dispatch
)
1357 /* Initialize all list_head */
1358 for (i
= 0; i
< ARRAY_SIZE(compat_sc_exit_table
); i
++)
1359 INIT_HLIST_HEAD(&group
->event_notifier_exit_compat_syscall_dispatch
[i
]);
1361 /* Init the unknown exit syscall notifier list. */
1362 INIT_HLIST_HEAD(&group
->event_notifier_exit_compat_unknown_syscall_dispatch
);
1366 if (!group
->sc_filter
) {
1367 group
->sc_filter
= kzalloc(sizeof(struct lttng_syscall_filter
),
1369 if (!group
->sc_filter
)
1373 if (!group
->sys_enter_registered
) {
1374 ret
= lttng_wrapper_tracepoint_probe_register("sys_enter",
1375 (void *) syscall_entry_event_notifier_probe
, group
);
1378 group
->sys_enter_registered
= 1;
1381 if (!group
->sys_exit_registered
) {
1382 ret
= lttng_wrapper_tracepoint_probe_register("sys_exit",
1383 (void *) syscall_exit_event_notifier_probe
, group
);
1385 WARN_ON_ONCE(lttng_wrapper_tracepoint_probe_unregister("sys_enter",
1386 (void *) syscall_entry_event_notifier_probe
, group
));
1389 group
->sys_exit_registered
= 1;
1396 int create_unknown_event_notifier(
1397 struct lttng_event_notifier_enabler
*event_notifier_enabler
,
1400 struct lttng_event_notifier
*notifier
;
1401 const struct lttng_event_desc
*desc
;
1402 struct lttng_event_notifier_group
*group
= event_notifier_enabler
->group
;
1403 struct lttng_kernel_event_notifier event_notifier_param
;
1404 uint64_t user_token
= event_notifier_enabler
->base
.user_token
;
1405 uint64_t error_counter_index
= event_notifier_enabler
->error_counter_index
;
1406 struct lttng_enabler
*base_enabler
= lttng_event_notifier_enabler_as_enabler(
1407 event_notifier_enabler
);
1408 struct hlist_head
*unknown_dispatch_list
;
1411 enum lttng_kernel_syscall_abi abi
;
1412 enum lttng_kernel_syscall_entryexit entryexit
;
1413 struct hlist_head
*head
;
1417 desc
= &__event_desc___syscall_entry_unknown
;
1418 unknown_dispatch_list
= &group
->event_notifier_unknown_syscall_dispatch
;
1419 entryexit
= LTTNG_KERNEL_SYSCALL_ENTRY
;
1420 abi
= LTTNG_KERNEL_SYSCALL_ABI_NATIVE
;
1423 desc
= &__event_desc___syscall_exit_unknown
;
1424 unknown_dispatch_list
= &group
->event_notifier_exit_unknown_syscall_dispatch
;
1425 entryexit
= LTTNG_KERNEL_SYSCALL_EXIT
;
1426 abi
= LTTNG_KERNEL_SYSCALL_ABI_NATIVE
;
1428 case SC_TYPE_COMPAT_ENTRY
:
1429 desc
= &__event_desc___compat_syscall_entry_unknown
;
1430 unknown_dispatch_list
= &group
->event_notifier_compat_unknown_syscall_dispatch
;
1431 entryexit
= LTTNG_KERNEL_SYSCALL_ENTRY
;
1432 abi
= LTTNG_KERNEL_SYSCALL_ABI_COMPAT
;
1434 case SC_TYPE_COMPAT_EXIT
:
1435 desc
= &__event_desc___compat_syscall_exit_unknown
;
1436 unknown_dispatch_list
= &group
->event_notifier_exit_compat_unknown_syscall_dispatch
;
1437 entryexit
= LTTNG_KERNEL_SYSCALL_EXIT
;
1438 abi
= LTTNG_KERNEL_SYSCALL_ABI_COMPAT
;
1445 * Check if already created.
1447 head
= utils_borrow_hash_table_bucket(group
->event_notifiers_ht
.table
,
1448 LTTNG_EVENT_NOTIFIER_HT_SIZE
, desc
->name
);
1449 lttng_hlist_for_each_entry(notifier
, head
, hlist
) {
1450 if (notifier
->desc
== desc
&&
1451 notifier
->user_token
== base_enabler
->user_token
)
1457 memset(&event_notifier_param
, 0, sizeof(event_notifier_param
));
1458 strncat(event_notifier_param
.event
.name
, desc
->name
,
1459 LTTNG_KERNEL_SYM_NAME_LEN
- strlen(event_notifier_param
.event
.name
) - 1);
1461 event_notifier_param
.event
.name
[LTTNG_KERNEL_SYM_NAME_LEN
- 1] = '\0';
1463 event_notifier_param
.event
.instrumentation
= LTTNG_KERNEL_SYSCALL
;
1464 event_notifier_param
.event
.u
.syscall
.abi
= abi
;
1465 event_notifier_param
.event
.u
.syscall
.entryexit
= entryexit
;
1467 notifier
= _lttng_event_notifier_create(desc
, user_token
,
1468 error_counter_index
, group
, &event_notifier_param
, NULL
,
1469 event_notifier_param
.event
.instrumentation
);
1470 if (IS_ERR(notifier
)) {
1471 printk(KERN_INFO
"Unable to create unknown notifier %s\n",
1477 hlist_add_head_rcu(¬ifier
->u
.syscall
.node
, unknown_dispatch_list
);
1483 static int create_matching_event_notifiers(
1484 struct lttng_event_notifier_enabler
*event_notifier_enabler
,
1485 void *filter
, const struct trace_syscall_entry
*table
,
1486 size_t table_len
, enum sc_type type
)
1488 struct lttng_event_notifier_group
*group
= event_notifier_enabler
->group
;
1489 const struct lttng_event_desc
*desc
;
1490 uint64_t user_token
= event_notifier_enabler
->base
.user_token
;
1491 uint64_t error_counter_index
= event_notifier_enabler
->error_counter_index
;
1495 /* iterate over all syscall and create event_notifier that match */
1496 for (i
= 0; i
< table_len
; i
++) {
1497 struct lttng_event_notifier
*event_notifier
;
1498 struct lttng_kernel_event_notifier event_notifier_param
;
1499 struct hlist_head
*head
;
1502 desc
= table
[i
].desc
;
1504 /* Unknown syscall */
1508 if (!lttng_desc_match_enabler(desc
,
1509 lttng_event_notifier_enabler_as_enabler(event_notifier_enabler
)))
1513 * Check if already created.
1515 head
= utils_borrow_hash_table_bucket(group
->event_notifiers_ht
.table
,
1516 LTTNG_EVENT_NOTIFIER_HT_SIZE
, desc
->name
);
1517 lttng_hlist_for_each_entry(event_notifier
, head
, hlist
) {
1518 if (event_notifier
->desc
== desc
1519 && event_notifier
->user_token
== event_notifier_enabler
->base
.user_token
)
1525 memset(&event_notifier_param
, 0, sizeof(event_notifier_param
));
1528 event_notifier_param
.event
.u
.syscall
.entryexit
= LTTNG_KERNEL_SYSCALL_ENTRY
;
1529 event_notifier_param
.event
.u
.syscall
.abi
= LTTNG_KERNEL_SYSCALL_ABI_NATIVE
;
1532 event_notifier_param
.event
.u
.syscall
.entryexit
= LTTNG_KERNEL_SYSCALL_EXIT
;
1533 event_notifier_param
.event
.u
.syscall
.abi
= LTTNG_KERNEL_SYSCALL_ABI_NATIVE
;
1535 case SC_TYPE_COMPAT_ENTRY
:
1536 event_notifier_param
.event
.u
.syscall
.entryexit
= LTTNG_KERNEL_SYSCALL_ENTRY
;
1537 event_notifier_param
.event
.u
.syscall
.abi
= LTTNG_KERNEL_SYSCALL_ABI_COMPAT
;
1539 case SC_TYPE_COMPAT_EXIT
:
1540 event_notifier_param
.event
.u
.syscall
.entryexit
= LTTNG_KERNEL_SYSCALL_EXIT
;
1541 event_notifier_param
.event
.u
.syscall
.abi
= LTTNG_KERNEL_SYSCALL_ABI_COMPAT
;
1544 strncat(event_notifier_param
.event
.name
, desc
->name
,
1545 LTTNG_KERNEL_SYM_NAME_LEN
- strlen(event_notifier_param
.event
.name
) - 1);
1546 event_notifier_param
.event
.name
[LTTNG_KERNEL_SYM_NAME_LEN
- 1] = '\0';
1547 event_notifier_param
.event
.instrumentation
= LTTNG_KERNEL_SYSCALL
;
1549 event_notifier
= _lttng_event_notifier_create(desc
, user_token
,
1550 error_counter_index
, group
, &event_notifier_param
,
1551 filter
, event_notifier_param
.event
.instrumentation
);
1552 if (IS_ERR(event_notifier
)) {
1553 printk(KERN_INFO
"Unable to create event_notifier %s\n",
1559 event_notifier
->u
.syscall
.syscall_id
= i
;
1567 int lttng_syscals_create_matching_event_notifiers(
1568 struct lttng_event_notifier_enabler
*event_notifier_enabler
,
1572 struct lttng_enabler
*base_enabler
=
1573 lttng_event_notifier_enabler_as_enabler(event_notifier_enabler
);
1574 enum lttng_kernel_syscall_entryexit entryexit
=
1575 base_enabler
->event_param
.u
.syscall
.entryexit
;
1577 if (entryexit
== LTTNG_KERNEL_SYSCALL_ENTRY
|| entryexit
== LTTNG_KERNEL_SYSCALL_ENTRYEXIT
) {
1578 ret
= create_matching_event_notifiers(event_notifier_enabler
,
1579 filter
, sc_table
, ARRAY_SIZE(sc_table
), SC_TYPE_ENTRY
);
1583 ret
= create_matching_event_notifiers(event_notifier_enabler
,
1584 filter
, compat_sc_table
, ARRAY_SIZE(compat_sc_table
),
1585 SC_TYPE_COMPAT_ENTRY
);
1589 ret
= create_unknown_event_notifier(event_notifier_enabler
,
1594 ret
= create_unknown_event_notifier(event_notifier_enabler
,
1595 SC_TYPE_COMPAT_ENTRY
);
1600 if (entryexit
== LTTNG_KERNEL_SYSCALL_EXIT
|| entryexit
== LTTNG_KERNEL_SYSCALL_ENTRYEXIT
) {
1601 ret
= create_matching_event_notifiers(event_notifier_enabler
,
1602 filter
, sc_exit_table
, ARRAY_SIZE(sc_exit_table
),
1607 ret
= create_unknown_event_notifier(event_notifier_enabler
,
1612 ret
= create_matching_event_notifiers(event_notifier_enabler
,
1613 filter
, compat_sc_exit_table
, ARRAY_SIZE(compat_sc_exit_table
),
1614 SC_TYPE_COMPAT_EXIT
);
1618 ret
= create_unknown_event_notifier(event_notifier_enabler
,
1619 SC_TYPE_COMPAT_EXIT
);
1629 * Unregister the syscall event_notifier probes from the callsites.
1631 int lttng_syscalls_unregister_event_notifier(
1632 struct lttng_event_notifier_group
*event_notifier_group
)
1637 * Only register the event_notifier probe on the `sys_enter` callsite for now.
1638 * At the moment, we don't think it's desirable to have one fired
1639 * event_notifier for the entry and one for the exit of a syscall.
1641 if (event_notifier_group
->sys_enter_registered
) {
1642 ret
= lttng_wrapper_tracepoint_probe_unregister("sys_enter",
1643 (void *) syscall_entry_event_notifier_probe
, event_notifier_group
);
1646 event_notifier_group
->sys_enter_registered
= 0;
1648 if (event_notifier_group
->sys_exit_registered
) {
1649 ret
= lttng_wrapper_tracepoint_probe_unregister("sys_exit",
1650 (void *) syscall_exit_event_notifier_probe
, event_notifier_group
);
1653 event_notifier_group
->sys_enter_registered
= 0;
1656 kfree(event_notifier_group
->event_notifier_syscall_dispatch
);
1657 kfree(event_notifier_group
->event_notifier_exit_syscall_dispatch
);
1658 #ifdef CONFIG_COMPAT
1659 kfree(event_notifier_group
->event_notifier_compat_syscall_dispatch
);
1660 kfree(event_notifier_group
->event_notifier_exit_compat_syscall_dispatch
);
1665 int lttng_syscalls_unregister_event(struct lttng_channel
*chan
)
1669 if (!chan
->sc_table
)
1671 if (chan
->sys_enter_registered
) {
1672 ret
= lttng_wrapper_tracepoint_probe_unregister("sys_enter",
1673 (void *) syscall_entry_event_probe
, chan
);
1676 chan
->sys_enter_registered
= 0;
1678 if (chan
->sys_exit_registered
) {
1679 ret
= lttng_wrapper_tracepoint_probe_unregister("sys_exit",
1680 (void *) syscall_exit_event_probe
, chan
);
1683 chan
->sys_exit_registered
= 0;
1688 int lttng_syscalls_destroy_event(struct lttng_channel
*chan
)
1690 kfree(chan
->sc_table
);
1691 kfree(chan
->sc_exit_table
);
1692 #ifdef CONFIG_COMPAT
1693 kfree(chan
->compat_sc_table
);
1694 kfree(chan
->compat_sc_exit_table
);
1696 kfree(chan
->sc_filter
);
1701 int get_syscall_nr(const char *syscall_name
)
1703 int syscall_nr
= -1;
1706 for (i
= 0; i
< ARRAY_SIZE(sc_table
); i
++) {
1707 const struct trace_syscall_entry
*entry
;
1708 const char *it_name
;
1710 entry
= &sc_table
[i
];
1713 it_name
= entry
->desc
->name
;
1714 it_name
+= strlen(SYSCALL_ENTRY_STR
);
1715 if (!strcmp(syscall_name
, it_name
)) {
1724 int get_compat_syscall_nr(const char *syscall_name
)
1726 int syscall_nr
= -1;
1729 for (i
= 0; i
< ARRAY_SIZE(compat_sc_table
); i
++) {
1730 const struct trace_syscall_entry
*entry
;
1731 const char *it_name
;
1733 entry
= &compat_sc_table
[i
];
1736 it_name
= entry
->desc
->name
;
1737 it_name
+= strlen(COMPAT_SYSCALL_ENTRY_STR
);
1738 if (!strcmp(syscall_name
, it_name
)) {
1747 uint32_t get_sc_tables_len(void)
1749 return ARRAY_SIZE(sc_table
) + ARRAY_SIZE(compat_sc_table
);
1753 const char *get_syscall_name(const char *desc_name
,
1754 enum lttng_syscall_abi abi
,
1755 enum lttng_syscall_entryexit entryexit
)
1757 size_t prefix_len
= 0;
1760 switch (entryexit
) {
1761 case LTTNG_SYSCALL_ENTRY
:
1763 case LTTNG_SYSCALL_ABI_NATIVE
:
1764 prefix_len
= strlen(SYSCALL_ENTRY_STR
);
1766 case LTTNG_SYSCALL_ABI_COMPAT
:
1767 prefix_len
= strlen(COMPAT_SYSCALL_ENTRY_STR
);
1771 case LTTNG_SYSCALL_EXIT
:
1773 case LTTNG_SYSCALL_ABI_NATIVE
:
1774 prefix_len
= strlen(SYSCALL_EXIT_STR
);
1776 case LTTNG_SYSCALL_ABI_COMPAT
:
1777 prefix_len
= strlen(COMPAT_SYSCALL_EXIT_STR
);
1782 WARN_ON_ONCE(prefix_len
== 0);
1783 return desc_name
+ prefix_len
;
1787 int lttng_syscall_filter_enable(
1788 struct lttng_syscall_filter
*filter
,
1789 const char *desc_name
, enum lttng_syscall_abi abi
,
1790 enum lttng_syscall_entryexit entryexit
)
1792 const char *syscall_name
;
1793 unsigned long *bitmap
;
1796 syscall_name
= get_syscall_name(desc_name
, abi
, entryexit
);
1799 case LTTNG_SYSCALL_ABI_NATIVE
:
1800 syscall_nr
= get_syscall_nr(syscall_name
);
1802 case LTTNG_SYSCALL_ABI_COMPAT
:
1803 syscall_nr
= get_compat_syscall_nr(syscall_name
);
1811 switch (entryexit
) {
1812 case LTTNG_SYSCALL_ENTRY
:
1814 case LTTNG_SYSCALL_ABI_NATIVE
:
1815 bitmap
= filter
->sc_entry
;
1817 case LTTNG_SYSCALL_ABI_COMPAT
:
1818 bitmap
= filter
->sc_compat_entry
;
1824 case LTTNG_SYSCALL_EXIT
:
1826 case LTTNG_SYSCALL_ABI_NATIVE
:
1827 bitmap
= filter
->sc_exit
;
1829 case LTTNG_SYSCALL_ABI_COMPAT
:
1830 bitmap
= filter
->sc_compat_exit
;
1839 if (test_bit(syscall_nr
, bitmap
))
1841 bitmap_set(bitmap
, syscall_nr
, 1);
1845 int lttng_syscall_filter_enable_event_notifier(
1846 struct lttng_event_notifier
*notifier
)
1848 struct lttng_event_notifier_group
*group
= notifier
->group
;
1849 unsigned int syscall_id
= notifier
->u
.syscall
.syscall_id
;
1850 struct hlist_head
*dispatch_list
;
1853 WARN_ON_ONCE(notifier
->instrumentation
!= LTTNG_KERNEL_SYSCALL
);
1855 ret
= lttng_syscall_filter_enable(group
->sc_filter
,
1856 notifier
->desc
->name
, notifier
->u
.syscall
.abi
,
1857 notifier
->u
.syscall
.entryexit
);
1862 switch (notifier
->u
.syscall
.entryexit
) {
1863 case LTTNG_SYSCALL_ENTRY
:
1864 switch (notifier
->u
.syscall
.abi
) {
1865 case LTTNG_SYSCALL_ABI_NATIVE
:
1866 dispatch_list
= &group
->event_notifier_syscall_dispatch
[syscall_id
];
1868 case LTTNG_SYSCALL_ABI_COMPAT
:
1869 dispatch_list
= &group
->event_notifier_compat_syscall_dispatch
[syscall_id
];
1873 case LTTNG_SYSCALL_EXIT
:
1874 switch (notifier
->u
.syscall
.abi
) {
1875 case LTTNG_SYSCALL_ABI_NATIVE
:
1876 dispatch_list
= &group
->event_notifier_exit_syscall_dispatch
[syscall_id
];
1878 case LTTNG_SYSCALL_ABI_COMPAT
:
1879 dispatch_list
= &group
->event_notifier_exit_compat_syscall_dispatch
[syscall_id
];
1885 hlist_add_head_rcu(¬ifier
->u
.syscall
.node
, dispatch_list
);
1891 int lttng_syscall_filter_enable_event(
1892 struct lttng_channel
*channel
,
1893 struct lttng_event
*event
)
1895 WARN_ON_ONCE(event
->instrumentation
!= LTTNG_KERNEL_SYSCALL
);
1897 return lttng_syscall_filter_enable(channel
->sc_filter
,
1898 event
->desc
->name
, event
->u
.syscall
.abi
,
1899 event
->u
.syscall
.entryexit
);
1903 int lttng_syscall_filter_disable(
1904 struct lttng_syscall_filter
*filter
,
1905 const char *desc_name
, enum lttng_syscall_abi abi
,
1906 enum lttng_syscall_entryexit entryexit
)
1908 const char *syscall_name
;
1909 unsigned long *bitmap
;
1912 syscall_name
= get_syscall_name(desc_name
, abi
, entryexit
);
1915 case LTTNG_SYSCALL_ABI_NATIVE
:
1916 syscall_nr
= get_syscall_nr(syscall_name
);
1918 case LTTNG_SYSCALL_ABI_COMPAT
:
1919 syscall_nr
= get_compat_syscall_nr(syscall_name
);
1927 switch (entryexit
) {
1928 case LTTNG_SYSCALL_ENTRY
:
1930 case LTTNG_SYSCALL_ABI_NATIVE
:
1931 bitmap
= filter
->sc_entry
;
1933 case LTTNG_SYSCALL_ABI_COMPAT
:
1934 bitmap
= filter
->sc_compat_entry
;
1940 case LTTNG_SYSCALL_EXIT
:
1942 case LTTNG_SYSCALL_ABI_NATIVE
:
1943 bitmap
= filter
->sc_exit
;
1945 case LTTNG_SYSCALL_ABI_COMPAT
:
1946 bitmap
= filter
->sc_compat_exit
;
1955 if (!test_bit(syscall_nr
, bitmap
))
1957 bitmap_clear(bitmap
, syscall_nr
, 1);
1962 int lttng_syscall_filter_disable_event_notifier(
1963 struct lttng_event_notifier
*notifier
)
1965 struct lttng_event_notifier_group
*group
= notifier
->group
;
1968 WARN_ON_ONCE(notifier
->instrumentation
!= LTTNG_KERNEL_SYSCALL
);
1970 ret
= lttng_syscall_filter_disable(group
->sc_filter
,
1971 notifier
->desc
->name
, notifier
->u
.syscall
.abi
,
1972 notifier
->u
.syscall
.entryexit
);
1973 WARN_ON_ONCE(ret
!= 0);
1975 hlist_del_rcu(¬ifier
->u
.syscall
.node
);
1979 int lttng_syscall_filter_disable_event(
1980 struct lttng_channel
*channel
,
1981 struct lttng_event
*event
)
1983 return lttng_syscall_filter_disable(channel
->sc_filter
,
1984 event
->desc
->name
, event
->u
.syscall
.abi
,
1985 event
->u
.syscall
.entryexit
);
1989 const struct trace_syscall_entry
*syscall_list_get_entry(loff_t
*pos
)
1991 const struct trace_syscall_entry
*entry
;
1994 for (entry
= sc_table
;
1995 entry
< sc_table
+ ARRAY_SIZE(sc_table
);
2000 for (entry
= compat_sc_table
;
2001 entry
< compat_sc_table
+ ARRAY_SIZE(compat_sc_table
);
2011 void *syscall_list_start(struct seq_file
*m
, loff_t
*pos
)
2013 return (void *) syscall_list_get_entry(pos
);
2017 void *syscall_list_next(struct seq_file
*m
, void *p
, loff_t
*ppos
)
2020 return (void *) syscall_list_get_entry(ppos
);
2024 void syscall_list_stop(struct seq_file
*m
, void *p
)
2029 int get_sc_table(const struct trace_syscall_entry
*entry
,
2030 const struct trace_syscall_entry
**table
,
2031 unsigned int *bitness
)
2033 if (entry
>= sc_table
&& entry
< sc_table
+ ARRAY_SIZE(sc_table
)) {
2035 *bitness
= BITS_PER_LONG
;
2040 if (!(entry
>= compat_sc_table
2041 && entry
< compat_sc_table
+ ARRAY_SIZE(compat_sc_table
))) {
2047 *table
= compat_sc_table
;
2052 int syscall_list_show(struct seq_file
*m
, void *p
)
2054 const struct trace_syscall_entry
*table
, *entry
= p
;
2055 unsigned int bitness
;
2056 unsigned long index
;
2060 ret
= get_sc_table(entry
, &table
, &bitness
);
2065 if (table
== sc_table
) {
2066 index
= entry
- table
;
2067 name
= &entry
->desc
->name
[strlen(SYSCALL_ENTRY_STR
)];
2069 index
= (entry
- table
) + ARRAY_SIZE(sc_table
);
2070 name
= &entry
->desc
->name
[strlen(COMPAT_SYSCALL_ENTRY_STR
)];
2072 seq_printf(m
, "syscall { index = %lu; name = %s; bitness = %u; };\n",
2073 index
, name
, bitness
);
2078 const struct seq_operations lttng_syscall_list_seq_ops
= {
2079 .start
= syscall_list_start
,
2080 .next
= syscall_list_next
,
2081 .stop
= syscall_list_stop
,
2082 .show
= syscall_list_show
,
2086 int lttng_syscall_list_open(struct inode
*inode
, struct file
*file
)
2088 return seq_open(file
, <tng_syscall_list_seq_ops
);
2091 const struct file_operations lttng_syscall_list_fops
= {
2092 .owner
= THIS_MODULE
,
2093 .open
= lttng_syscall_list_open
,
2095 .llseek
= seq_lseek
,
2096 .release
= seq_release
,
2100 * A syscall is enabled if it is traced for either entry or exit.
2102 long lttng_channel_syscall_mask(struct lttng_channel
*channel
,
2103 struct lttng_kernel_syscall_mask __user
*usyscall_mask
)
2105 uint32_t len
, sc_tables_len
, bitmask_len
;
2108 struct lttng_syscall_filter
*filter
;
2110 ret
= get_user(len
, &usyscall_mask
->len
);
2113 sc_tables_len
= get_sc_tables_len();
2114 bitmask_len
= ALIGN(sc_tables_len
, 8) >> 3;
2115 if (len
< sc_tables_len
) {
2116 return put_user(sc_tables_len
, &usyscall_mask
->len
);
2118 /* Array is large enough, we can copy array to user-space. */
2119 tmp_mask
= kzalloc(bitmask_len
, GFP_KERNEL
);
2122 filter
= channel
->sc_filter
;
2124 for (bit
= 0; bit
< ARRAY_SIZE(sc_table
); bit
++) {
2127 if (channel
->sc_table
) {
2128 if (!READ_ONCE(channel
->syscall_all
) && filter
)
2129 state
= test_bit(bit
, filter
->sc_entry
)
2130 || test_bit(bit
, filter
->sc_exit
);
2136 bt_bitfield_write_be(tmp_mask
, char, bit
, 1, state
);
2138 for (; bit
< sc_tables_len
; bit
++) {
2141 if (channel
->compat_sc_table
) {
2142 if (!READ_ONCE(channel
->syscall_all
) && filter
)
2143 state
= test_bit(bit
- ARRAY_SIZE(sc_table
),
2144 filter
->sc_compat_entry
)
2145 || test_bit(bit
- ARRAY_SIZE(sc_table
),
2146 filter
->sc_compat_exit
);
2152 bt_bitfield_write_be(tmp_mask
, char, bit
, 1, state
);
2154 if (copy_to_user(usyscall_mask
->mask
, tmp_mask
, bitmask_len
))
2160 int lttng_abi_syscall_list(void)
2162 struct file
*syscall_list_file
;
2165 file_fd
= lttng_get_unused_fd();
2171 syscall_list_file
= anon_inode_getfile("[lttng_syscall_list]",
2172 <tng_syscall_list_fops
,
2174 if (IS_ERR(syscall_list_file
)) {
2175 ret
= PTR_ERR(syscall_list_file
);
2178 ret
= lttng_syscall_list_fops
.open(NULL
, syscall_list_file
);
2181 fd_install(file_fd
, syscall_list_file
);
2185 fput(syscall_list_file
);
2187 put_unused_fd(file_fd
);