Refactoring: rename lttng_syscalls_register_event to lttng_syscalls_register_event_re...
[lttng-modules.git] / src / lttng-syscalls.c
CommitLineData
b7cdc182 1/* SPDX-License-Identifier: (GPL-2.0-only or LGPL-2.1-only)
9f36eaed 2 *
259b6cb3
MD
3 * lttng-syscalls.c
4 *
2faf7d1b 5 * LTTng syscall probes.
259b6cb3 6 *
886d51a3 7 * Copyright (C) 2010-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
259b6cb3
MD
8 */
9
10#include <linux/module.h>
11#include <linux/slab.h>
6333ace3 12#include <linux/compat.h>
abc0446a 13#include <linux/err.h>
80f87dd2 14#include <linux/bitmap.h>
7ca580f8
MD
15#include <linux/in.h>
16#include <linux/in6.h>
2d2464bd 17#include <linux/seq_file.h>
d4291869 18#include <linux/stringify.h>
082d4946
MD
19#include <linux/file.h>
20#include <linux/anon_inodes.h>
c8dfb724 21#include <linux/fcntl.h>
3cf55950 22#include <linux/mman.h>
259b6cb3
MD
23#include <asm/ptrace.h>
24#include <asm/syscall.h>
25
a071f25d 26#include <lttng/bitfield.h>
241ae9a8
MD
27#include <wrapper/tracepoint.h>
28#include <wrapper/file.h>
29#include <wrapper/rcu.h>
1b7b9c65 30#include <wrapper/syscall.h>
2df37e95 31#include <lttng/events.h>
6f156b09 32#include <lttng/events-internal.h>
8a8ac9a8 33#include <lttng/utils.h>
259b6cb3 34
ebcc64cd
FD
35#include "lttng-syscalls.h"
36
6333ace3 37#ifndef CONFIG_COMPAT
bfa949bf
MD
38# ifndef is_compat_task
39# define is_compat_task() (0)
40# endif
6333ace3
MD
41#endif
42
1aa3298b
MD
43/* in_compat_syscall appears in kernel 4.6. */
44#ifndef in_compat_syscall
45 #define in_compat_syscall() is_compat_task()
46#endif
47
5b7ac358
MD
48enum sc_type {
49 SC_TYPE_ENTRY,
50 SC_TYPE_EXIT,
51 SC_TYPE_COMPAT_ENTRY,
52 SC_TYPE_COMPAT_EXIT,
53};
54
d4291869
MD
55#define SYSCALL_ENTRY_TOK syscall_entry_
56#define COMPAT_SYSCALL_ENTRY_TOK compat_syscall_entry_
57#define SYSCALL_EXIT_TOK syscall_exit_
58#define COMPAT_SYSCALL_EXIT_TOK compat_syscall_exit_
59
60#define SYSCALL_ENTRY_STR __stringify(SYSCALL_ENTRY_TOK)
61#define COMPAT_SYSCALL_ENTRY_STR __stringify(COMPAT_SYSCALL_ENTRY_TOK)
62#define SYSCALL_EXIT_STR __stringify(SYSCALL_EXIT_TOK)
63#define COMPAT_SYSCALL_EXIT_STR __stringify(COMPAT_SYSCALL_EXIT_TOK)
5b7ac358 64
2d6d88c6 65void syscall_entry_event_probe(void *__data, struct pt_regs *regs, long id);
2d6d88c6 66void syscall_exit_event_probe(void *__data, struct pt_regs *regs, long ret);
259b6cb3 67
3a523f5b
MD
68/*
69 * Forward declarations for old kernels.
70 */
71struct mmsghdr;
72struct rlimit64;
73struct oldold_utsname;
74struct old_utsname;
75struct sel_arg_struct;
76struct mmap_arg_struct;
c0b71117 77struct file_handle;
a292e6f1 78struct user_msghdr;
3a523f5b 79
9eb15e8b
MJ
80/*
81 * Forward declaration for kernels >= 5.6
82 */
83struct timex;
edfdcb68
MJ
84struct timeval;
85struct itimerval;
86struct itimerspec;
87
5f4c791e 88#if (LTTNG_LINUX_VERSION_CODE >= LTTNG_KERNEL_VERSION(5,6,0))
edfdcb68
MJ
89typedef __kernel_old_time_t time_t;
90#endif
9eb15e8b 91
80f87dd2
MD
92#ifdef IA32_NR_syscalls
93#define NR_compat_syscalls IA32_NR_syscalls
94#else
95#define NR_compat_syscalls NR_syscalls
96#endif
97
259b6cb3
MD
98/*
99 * Create LTTng tracepoint probes.
100 */
101#define LTTNG_PACKAGE_BUILD
102#define CREATE_TRACE_POINTS
2655f9ad 103#define TP_MODULE_NOINIT
c075712b 104#define TRACE_INCLUDE_PATH instrumentation/syscalls/headers
259b6cb3 105
a93244f8
MD
106#define PARAMS(args...) args
107
5b7ac358 108/* Handle unknown syscalls */
72a52753 109#undef TRACE_SYSTEM
5b7ac358 110#define TRACE_SYSTEM syscalls_unknown
241ae9a8 111#include <instrumentation/syscalls/headers/syscalls_unknown.h>
5b7ac358
MD
112#undef TRACE_SYSTEM
113
5b7ac358 114#undef TP_PROBE_CB
fc4f7161 115
e42c4f49
FD
116extern const struct trace_syscall_table sc_table;
117extern const struct trace_syscall_table compat_sc_table;
5b7ac358 118
2d6d88c6 119/* Event syscall exit table */
e42c4f49
FD
120extern const struct trace_syscall_table sc_exit_table;
121extern const struct trace_syscall_table compat_sc_exit_table;
ebcc64cd
FD
122
123
fc4f7161
MD
124#undef SC_EXIT
125
a93244f8 126#undef CREATE_SYSCALL_TABLE
2faf7d1b 127
80f87dd2 128struct lttng_syscall_filter {
badfe9f5
MD
129 DECLARE_BITMAP(sc_entry, NR_syscalls);
130 DECLARE_BITMAP(sc_exit, NR_syscalls);
131 DECLARE_BITMAP(sc_compat_entry, NR_compat_syscalls);
132 DECLARE_BITMAP(sc_compat_exit, NR_compat_syscalls);
80f87dd2
MD
133};
134
3b82c4e1 135static void syscall_entry_event_unknown(struct hlist_head *unknown_action_list_head,
8a8ac9a8 136 struct pt_regs *regs, long id)
f405cfce 137{
1b7b9c65 138 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
a67ba386 139 struct lttng_kernel_event_common_private *event_priv;
f405cfce 140
1b7b9c65 141 lttng_syscall_get_arguments(current, regs, args);
a67ba386 142 lttng_hlist_for_each_entry_rcu(event_priv, unknown_action_list_head, u.syscall.node) {
8a8ac9a8 143 if (unlikely(in_compat_syscall()))
e2d5dbc7 144 __event_probe__compat_syscall_entry_unknown(event_priv->pub, id, args);
8a8ac9a8 145 else
e2d5dbc7 146 __event_probe__syscall_entry_unknown(event_priv->pub, id, args);
8a8ac9a8
FD
147 }
148}
149
63aa9160 150static __always_inline
e2d5dbc7 151void syscall_entry_event_call_func(struct hlist_head *action_list,
3b82c4e1 152 void *func, unsigned int nrargs,
63aa9160 153 struct pt_regs *regs)
259b6cb3 154{
a67ba386 155 struct lttng_kernel_event_common_private *event_priv;
3b82c4e1 156
63aa9160 157 switch (nrargs) {
259b6cb3
MD
158 case 0:
159 {
63aa9160 160 void (*fptr)(void *__data) = func;
259b6cb3 161
e2d5dbc7
MD
162 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node)
163 fptr(event_priv->pub);
259b6cb3
MD
164 break;
165 }
166 case 1:
167 {
63aa9160 168 void (*fptr)(void *__data, unsigned long arg0) = func;
1b7b9c65 169 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
259b6cb3 170
1b7b9c65 171 lttng_syscall_get_arguments(current, regs, args);
e2d5dbc7
MD
172 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node)
173 fptr(event_priv->pub, args[0]);
259b6cb3
MD
174 break;
175 }
176 case 2:
177 {
178 void (*fptr)(void *__data,
179 unsigned long arg0,
63aa9160 180 unsigned long arg1) = func;
1b7b9c65 181 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
259b6cb3 182
1b7b9c65 183 lttng_syscall_get_arguments(current, regs, args);
e2d5dbc7
MD
184 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node)
185 fptr(event_priv->pub, args[0], args[1]);
259b6cb3
MD
186 break;
187 }
188 case 3:
189 {
190 void (*fptr)(void *__data,
191 unsigned long arg0,
192 unsigned long arg1,
63aa9160 193 unsigned long arg2) = func;
1b7b9c65 194 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
259b6cb3 195
1b7b9c65 196 lttng_syscall_get_arguments(current, regs, args);
e2d5dbc7
MD
197 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node)
198 fptr(event_priv->pub, args[0], args[1], args[2]);
259b6cb3
MD
199 break;
200 }
201 case 4:
202 {
203 void (*fptr)(void *__data,
204 unsigned long arg0,
205 unsigned long arg1,
206 unsigned long arg2,
63aa9160 207 unsigned long arg3) = func;
1b7b9c65 208 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
259b6cb3 209
1b7b9c65 210 lttng_syscall_get_arguments(current, regs, args);
e2d5dbc7
MD
211 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node)
212 fptr(event_priv->pub, args[0], args[1], args[2], args[3]);
259b6cb3
MD
213 break;
214 }
215 case 5:
216 {
217 void (*fptr)(void *__data,
218 unsigned long arg0,
219 unsigned long arg1,
220 unsigned long arg2,
221 unsigned long arg3,
63aa9160 222 unsigned long arg4) = func;
1b7b9c65 223 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
259b6cb3 224
1b7b9c65 225 lttng_syscall_get_arguments(current, regs, args);
e2d5dbc7
MD
226 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node)
227 fptr(event_priv->pub, args[0], args[1], args[2], args[3], args[4]);
259b6cb3
MD
228 break;
229 }
230 case 6:
231 {
232 void (*fptr)(void *__data,
233 unsigned long arg0,
234 unsigned long arg1,
235 unsigned long arg2,
236 unsigned long arg3,
237 unsigned long arg4,
63aa9160 238 unsigned long arg5) = func;
1b7b9c65 239 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
259b6cb3 240
1b7b9c65 241 lttng_syscall_get_arguments(current, regs, args);
e2d5dbc7
MD
242 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node)
243 fptr(event_priv->pub, args[0], args[1], args[2],
3b82c4e1 244 args[3], args[4], args[5]);
8a8ac9a8
FD
245 break;
246 }
247 default:
248 break;
249 }
250}
251
63aa9160
FD
252void syscall_entry_event_probe(void *__data, struct pt_regs *regs, long id)
253{
0bb716a8 254 struct lttng_kernel_syscall_table *syscall_table = __data;
3b82c4e1 255 struct hlist_head *action_list, *unknown_action_list;
63aa9160
FD
256 const struct trace_syscall_entry *table, *entry;
257 size_t table_len;
258
259 if (unlikely(in_compat_syscall())) {
0bb716a8 260 struct lttng_syscall_filter *filter = syscall_table->sc_filter;
63aa9160
FD
261
262 if (id < 0 || id >= NR_compat_syscalls
0bb716a8 263 || (!READ_ONCE(syscall_table->syscall_all_entry) && !test_bit(id, filter->sc_compat_entry))) {
63aa9160
FD
264 /* System call filtered out. */
265 return;
266 }
ebcc64cd
FD
267 table = compat_sc_table.table;
268 table_len = compat_sc_table.len;
0bb716a8 269 unknown_action_list = &syscall_table->compat_unknown_syscall_dispatch;
63aa9160 270 } else {
0bb716a8 271 struct lttng_syscall_filter *filter = syscall_table->sc_filter;
63aa9160
FD
272
273 if (id < 0 || id >= NR_syscalls
0bb716a8 274 || (!READ_ONCE(syscall_table->syscall_all_entry) && !test_bit(id, filter->sc_entry))) {
63aa9160
FD
275 /* System call filtered out. */
276 return;
277 }
ebcc64cd
FD
278 table = sc_table.table;
279 table_len = sc_table.len;
0bb716a8 280 unknown_action_list = &syscall_table->unknown_syscall_dispatch;
63aa9160
FD
281 }
282 if (unlikely(id < 0 || id >= table_len)) {
3b82c4e1 283 syscall_entry_event_unknown(unknown_action_list, regs, id);
63aa9160
FD
284 return;
285 }
3b82c4e1
MD
286
287 entry = &table[id];
288 if (!entry->event_func) {
289 syscall_entry_event_unknown(unknown_action_list, regs, id);
63aa9160
FD
290 return;
291 }
3b82c4e1
MD
292
293 if (unlikely(in_compat_syscall())) {
0bb716a8 294 action_list = &syscall_table->compat_syscall_dispatch[id];
3b82c4e1 295 } else {
0bb716a8 296 action_list = &syscall_table->syscall_dispatch[id];
3b82c4e1
MD
297 }
298 if (unlikely(hlist_empty(action_list)))
299 return;
300
e2d5dbc7 301 syscall_entry_event_call_func(action_list, entry->event_func, entry->nrargs, regs);
63aa9160
FD
302}
303
3b82c4e1 304static void syscall_exit_event_unknown(struct hlist_head *unknown_action_list_head,
8a8ac9a8 305 struct pt_regs *regs, long id, long ret)
5b7ac358 306{
1b7b9c65 307 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
a67ba386 308 struct lttng_kernel_event_common_private *event_priv;
5b7ac358 309
1b7b9c65 310 lttng_syscall_get_arguments(current, regs, args);
a67ba386 311 lttng_hlist_for_each_entry_rcu(event_priv, unknown_action_list_head, u.syscall.node) {
3b82c4e1 312 if (unlikely(in_compat_syscall()))
e2d5dbc7 313 __event_probe__compat_syscall_exit_unknown(event_priv->pub, id, ret,
3b82c4e1
MD
314 args);
315 else
e2d5dbc7 316 __event_probe__syscall_exit_unknown(event_priv->pub, id, ret, args);
3b82c4e1 317 }
5b7ac358
MD
318}
319
3b82c4e1 320static __always_inline
e2d5dbc7 321void syscall_exit_event_call_func(struct hlist_head *action_list,
3b82c4e1
MD
322 void *func, unsigned int nrargs,
323 struct pt_regs *regs, long ret)
5b7ac358 324{
a67ba386 325 struct lttng_kernel_event_common_private *event_priv;
badfe9f5 326
3b82c4e1 327 switch (nrargs) {
5b7ac358
MD
328 case 0:
329 {
3b82c4e1 330 void (*fptr)(void *__data, long ret) = func;
5b7ac358 331
e2d5dbc7
MD
332 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node)
333 fptr(event_priv->pub, ret);
5b7ac358
MD
334 break;
335 }
336 case 1:
337 {
338 void (*fptr)(void *__data,
fc4f7161 339 long ret,
3b82c4e1 340 unsigned long arg0) = func;
1b7b9c65 341 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
5b7ac358 342
1b7b9c65 343 lttng_syscall_get_arguments(current, regs, args);
e2d5dbc7
MD
344 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node)
345 fptr(event_priv->pub, ret, args[0]);
5b7ac358
MD
346 break;
347 }
348 case 2:
349 {
350 void (*fptr)(void *__data,
fc4f7161 351 long ret,
5b7ac358 352 unsigned long arg0,
3b82c4e1 353 unsigned long arg1) = func;
1b7b9c65 354 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
5b7ac358 355
1b7b9c65 356 lttng_syscall_get_arguments(current, regs, args);
e2d5dbc7
MD
357 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node)
358 fptr(event_priv->pub, ret, args[0], args[1]);
5b7ac358
MD
359 break;
360 }
361 case 3:
362 {
363 void (*fptr)(void *__data,
fc4f7161 364 long ret,
5b7ac358
MD
365 unsigned long arg0,
366 unsigned long arg1,
3b82c4e1 367 unsigned long arg2) = func;
1b7b9c65 368 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
5b7ac358 369
1b7b9c65 370 lttng_syscall_get_arguments(current, regs, args);
e2d5dbc7
MD
371 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node)
372 fptr(event_priv->pub, ret, args[0], args[1], args[2]);
5b7ac358
MD
373 break;
374 }
375 case 4:
376 {
377 void (*fptr)(void *__data,
fc4f7161 378 long ret,
5b7ac358
MD
379 unsigned long arg0,
380 unsigned long arg1,
381 unsigned long arg2,
3b82c4e1 382 unsigned long arg3) = func;
1b7b9c65 383 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
5b7ac358 384
1b7b9c65 385 lttng_syscall_get_arguments(current, regs, args);
e2d5dbc7
MD
386 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node)
387 fptr(event_priv->pub, ret, args[0], args[1], args[2], args[3]);
5b7ac358
MD
388 break;
389 }
390 case 5:
391 {
392 void (*fptr)(void *__data,
fc4f7161 393 long ret,
5b7ac358
MD
394 unsigned long arg0,
395 unsigned long arg1,
396 unsigned long arg2,
397 unsigned long arg3,
3b82c4e1 398 unsigned long arg4) = func;
1b7b9c65 399 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
5b7ac358 400
1b7b9c65 401 lttng_syscall_get_arguments(current, regs, args);
e2d5dbc7
MD
402 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node)
403 fptr(event_priv->pub, ret, args[0], args[1], args[2], args[3], args[4]);
5b7ac358
MD
404 break;
405 }
406 case 6:
407 {
408 void (*fptr)(void *__data,
fc4f7161 409 long ret,
5b7ac358
MD
410 unsigned long arg0,
411 unsigned long arg1,
412 unsigned long arg2,
413 unsigned long arg3,
414 unsigned long arg4,
3b82c4e1 415 unsigned long arg5) = func;
1b7b9c65 416 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
5b7ac358 417
1b7b9c65 418 lttng_syscall_get_arguments(current, regs, args);
e2d5dbc7
MD
419 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node)
420 fptr(event_priv->pub, ret, args[0], args[1], args[2],
3b82c4e1 421 args[3], args[4], args[5]);
5b7ac358
MD
422 break;
423 }
424 default:
425 break;
426 }
427}
428
3b82c4e1
MD
429void syscall_exit_event_probe(void *__data, struct pt_regs *regs, long ret)
430{
0bb716a8 431 struct lttng_kernel_syscall_table *syscall_table = __data;
3b82c4e1
MD
432 struct hlist_head *action_list, *unknown_action_list;
433 const struct trace_syscall_entry *table, *entry;
434 size_t table_len;
435 long id;
436
437 id = syscall_get_nr(current, regs);
438
439 if (unlikely(in_compat_syscall())) {
0bb716a8 440 struct lttng_syscall_filter *filter = syscall_table->sc_filter;
3b82c4e1
MD
441
442 if (id < 0 || id >= NR_compat_syscalls
0bb716a8 443 || (!READ_ONCE(syscall_table->syscall_all_exit) && !test_bit(id, filter->sc_compat_exit))) {
3b82c4e1
MD
444 /* System call filtered out. */
445 return;
446 }
ebcc64cd
FD
447 table = compat_sc_exit_table.table;
448 table_len = compat_sc_exit_table.len;
0bb716a8 449 unknown_action_list = &syscall_table->compat_unknown_syscall_exit_dispatch;
3b82c4e1 450 } else {
0bb716a8 451 struct lttng_syscall_filter *filter = syscall_table->sc_filter;
3b82c4e1
MD
452
453 if (id < 0 || id >= NR_syscalls
0bb716a8 454 || (!READ_ONCE(syscall_table->syscall_all_exit) && !test_bit(id, filter->sc_exit))) {
3b82c4e1
MD
455 /* System call filtered out. */
456 return;
457 }
ebcc64cd
FD
458 table = sc_exit_table.table;
459 table_len = sc_exit_table.len;
0bb716a8 460 unknown_action_list = &syscall_table->unknown_syscall_exit_dispatch;
3b82c4e1
MD
461 }
462 if (unlikely(id < 0 || id >= table_len)) {
463 syscall_exit_event_unknown(unknown_action_list, regs, id, ret);
464 return;
465 }
466
467 entry = &table[id];
468 if (!entry->event_func) {
469 syscall_exit_event_unknown(unknown_action_list, regs, id, ret);
470 return;
471 }
472
473 if (unlikely(in_compat_syscall())) {
0bb716a8 474 action_list = &syscall_table->compat_syscall_exit_dispatch[id];
3b82c4e1 475 } else {
0bb716a8 476 action_list = &syscall_table->syscall_exit_dispatch[id];
3b82c4e1
MD
477 }
478 if (unlikely(hlist_empty(action_list)))
479 return;
480
e2d5dbc7 481 syscall_exit_event_call_func(action_list, entry->event_func, entry->nrargs,
3b82c4e1
MD
482 regs, ret);
483}
484
0bb716a8
MD
485static
486struct lttng_kernel_syscall_table *get_syscall_table_from_enabler(struct lttng_event_enabler_common *event_enabler)
8a8ac9a8 487{
0bb716a8
MD
488 switch (event_enabler->enabler_type) {
489 case LTTNG_EVENT_ENABLER_TYPE_RECORDER:
490 {
1ae083ba
MD
491 struct lttng_event_recorder_enabler *event_recorder_enabler =
492 container_of(event_enabler, struct lttng_event_recorder_enabler, parent);
0bb716a8 493 return &event_recorder_enabler->chan->priv->parent.syscall_table;
8a8ac9a8 494 }
0bb716a8
MD
495 case LTTNG_EVENT_ENABLER_TYPE_NOTIFIER:
496 {
497 struct lttng_event_notifier_enabler *event_notifier_enabler =
498 container_of(event_enabler, struct lttng_event_notifier_enabler, parent);
499 return &event_notifier_enabler->group->syscall_table;
8a8ac9a8 500 }
0bb716a8
MD
501 default:
502 return NULL;
8a8ac9a8 503 }
0bb716a8 504}
8a8ac9a8 505
0bb716a8
MD
506static
507struct lttng_kernel_syscall_table *get_syscall_table_from_event(struct lttng_kernel_event_common *event)
508{
509 switch (event->type) {
510 case LTTNG_KERNEL_EVENT_TYPE_RECORDER:
511 {
512 struct lttng_kernel_event_recorder *event_recorder =
513 container_of(event, struct lttng_kernel_event_recorder, parent);
514 return &event_recorder->chan->priv->parent.syscall_table;
515 }
516 case LTTNG_KERNEL_EVENT_TYPE_NOTIFIER:
517 {
518 struct lttng_kernel_event_notifier *event_notifier =
519 container_of(event, struct lttng_kernel_event_notifier, parent);
520 return &event_notifier->priv->group->syscall_table;
521 }
522 default:
523 return NULL;
8a8ac9a8 524 }
8a8ac9a8 525}
0bb716a8 526
33a39a3c
MD
527/*
528 * noinline to diminish caller stack size.
529 * Should be called with sessions lock held.
530 */
49c50022 531static
3b82c4e1 532int lttng_create_syscall_event_if_missing(const struct trace_syscall_entry *table, size_t table_len,
1ae083ba 533 struct hlist_head *chan_table, struct lttng_event_recorder_enabler *syscall_event_enabler,
a67ba386 534 enum sc_type type)
259b6cb3 535{
0bb716a8 536 struct lttng_kernel_syscall_table *syscall_table = get_syscall_table_from_enabler(&syscall_event_enabler->parent);
def1e304 537 struct lttng_kernel_channel_buffer *chan = syscall_event_enabler->chan;
f7d06400 538 struct lttng_kernel_session *session = chan->parent.session;
259b6cb3 539 unsigned int i;
49c50022 540
3b82c4e1 541 /* Allocate events for each syscall matching enabler, insert into table */
49c50022 542 for (i = 0; i < table_len; i++) {
437d5aa5 543 const struct lttng_kernel_event_desc *desc = table[i].desc;
1ae083ba 544 struct lttng_event_recorder_enabler *event_enabler;
606828e4 545 struct lttng_kernel_abi_event ev;
a67ba386
MD
546 struct lttng_kernel_event_recorder_private *event_recorder_priv;
547 struct lttng_kernel_event_recorder *event_recorder;
3b82c4e1
MD
548 struct hlist_head *head;
549 bool found = false;
49c50022
MD
550
551 if (!desc) {
552 /* Unknown syscall */
553 continue;
554 }
3b82c4e1 555 if (lttng_desc_match_enabler(desc,
1ae083ba 556 lttng_event_recorder_enabler_as_enabler(syscall_event_enabler)) <= 0)
3b82c4e1 557 continue;
49c50022 558 /*
3b82c4e1 559 * Check if already created.
49c50022 560 */
3b82c4e1 561 head = utils_borrow_hash_table_bucket(
8cdc1a81 562 session->priv->events_ht.table, LTTNG_EVENT_HT_SIZE,
437d5aa5 563 desc->event_name);
a67ba386
MD
564 lttng_hlist_for_each_entry(event_recorder_priv, head, hlist) {
565 if (event_recorder_priv->parent.desc == desc
0bb716a8 566 && get_syscall_table_from_event(event_recorder_priv->parent.pub) == syscall_table)
3b82c4e1
MD
567 found = true;
568 }
569 if (found)
49c50022 570 continue;
3b82c4e1
MD
571
572 /* We need to create an event for this syscall/enabler. */
49c50022 573 memset(&ev, 0, sizeof(ev));
5b7ac358
MD
574 switch (type) {
575 case SC_TYPE_ENTRY:
606828e4
MD
576 ev.u.syscall.entryexit = LTTNG_KERNEL_ABI_SYSCALL_ENTRY;
577 ev.u.syscall.abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_NATIVE;
5b7ac358
MD
578 break;
579 case SC_TYPE_EXIT:
606828e4
MD
580 ev.u.syscall.entryexit = LTTNG_KERNEL_ABI_SYSCALL_EXIT;
581 ev.u.syscall.abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_NATIVE;
5b7ac358
MD
582 break;
583 case SC_TYPE_COMPAT_ENTRY:
606828e4
MD
584 ev.u.syscall.entryexit = LTTNG_KERNEL_ABI_SYSCALL_ENTRY;
585 ev.u.syscall.abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_COMPAT;
5b7ac358
MD
586 break;
587 case SC_TYPE_COMPAT_EXIT:
606828e4
MD
588 ev.u.syscall.entryexit = LTTNG_KERNEL_ABI_SYSCALL_EXIT;
589 ev.u.syscall.abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_COMPAT;
5b7ac358
MD
590 break;
591 }
606828e4
MD
592 strncpy(ev.name, desc->event_name, LTTNG_KERNEL_ABI_SYM_NAME_LEN - 1);
593 ev.name[LTTNG_KERNEL_ABI_SYM_NAME_LEN - 1] = '\0';
594 ev.instrumentation = LTTNG_KERNEL_ABI_SYSCALL;
1ae083ba 595 event_enabler = lttng_event_recorder_enabler_create(LTTNG_ENABLER_FORMAT_NAME, &ev, chan);
def1e304
MD
596 if (!event_enabler) {
597 return -ENOMEM;
598 }
599 event_recorder = _lttng_kernel_event_recorder_create(event_enabler, desc);
a67ba386 600 WARN_ON_ONCE(!event_recorder);
44b1abdc 601 lttng_event_enabler_destroy(&event_enabler->parent);
a67ba386 602 if (IS_ERR(event_recorder)) {
49c50022
MD
603 /*
604 * If something goes wrong in event registration
605 * after the first one, we have no choice but to
606 * leave the previous events in there, until
607 * deleted by session teardown.
608 */
a67ba386 609 return PTR_ERR(event_recorder);
49c50022 610 }
a67ba386 611 hlist_add_head(&event_recorder->priv->parent.u.syscall.node, &chan_table[i]);
49c50022
MD
612 }
613 return 0;
614}
615
33a39a3c
MD
616/*
617 * Should be called with sessions lock held.
618 */
3c6beb8d 619int lttng_syscalls_register_event_recorder(struct lttng_event_recorder_enabler *syscall_event_enabler)
49c50022 620{
0bb716a8 621 struct lttng_kernel_syscall_table *syscall_table = get_syscall_table_from_enabler(&syscall_event_enabler->parent);
606828e4 622 struct lttng_kernel_abi_event ev;
259b6cb3
MD
623 int ret;
624
263b6c88 625 wrapper_vmalloc_sync_mappings();
259b6cb3 626
0bb716a8 627 if (!syscall_table->syscall_dispatch) {
259b6cb3 628 /* create syscall table mapping syscall to events */
0bb716a8
MD
629 syscall_table->syscall_dispatch = kzalloc(sizeof(struct hlist_head) * sc_table.len, GFP_KERNEL);
630 if (!syscall_table->syscall_dispatch)
259b6cb3
MD
631 return -ENOMEM;
632 }
0bb716a8 633 if (!syscall_table->syscall_exit_dispatch) {
5b7ac358 634 /* create syscall table mapping syscall to events */
0bb716a8
MD
635 syscall_table->syscall_exit_dispatch = kzalloc(sizeof(struct hlist_head) * sc_exit_table.len, GFP_KERNEL);
636 if (!syscall_table->syscall_exit_dispatch)
5b7ac358
MD
637 return -ENOMEM;
638 }
639
259b6cb3 640
49c50022 641#ifdef CONFIG_COMPAT
0bb716a8 642 if (!syscall_table->compat_syscall_dispatch) {
49c50022 643 /* create syscall table mapping compat syscall to events */
0bb716a8
MD
644 syscall_table->compat_syscall_dispatch = kzalloc(sizeof(struct hlist_head) * compat_sc_table.len, GFP_KERNEL);
645 if (!syscall_table->compat_syscall_dispatch)
49c50022
MD
646 return -ENOMEM;
647 }
5b7ac358 648
0bb716a8 649 if (!syscall_table->compat_syscall_exit_dispatch) {
5b7ac358 650 /* create syscall table mapping compat syscall to events */
0bb716a8
MD
651 syscall_table->compat_syscall_exit_dispatch = kzalloc(sizeof(struct hlist_head) * compat_sc_exit_table.len, GFP_KERNEL);
652 if (!syscall_table->compat_syscall_exit_dispatch)
5b7ac358
MD
653 return -ENOMEM;
654 }
49c50022 655#endif
0bb716a8 656 if (hlist_empty(&syscall_table->unknown_syscall_dispatch)) {
437d5aa5 657 const struct lttng_kernel_event_desc *desc =
d4291869 658 &__event_desc___syscall_entry_unknown;
a67ba386 659 struct lttng_kernel_event_recorder *event_recorder;
1ae083ba 660 struct lttng_event_recorder_enabler *event_enabler;
2f804c0a 661
f405cfce 662 memset(&ev, 0, sizeof(ev));
606828e4
MD
663 strncpy(ev.name, desc->event_name, LTTNG_KERNEL_ABI_SYM_NAME_LEN);
664 ev.name[LTTNG_KERNEL_ABI_SYM_NAME_LEN - 1] = '\0';
665 ev.instrumentation = LTTNG_KERNEL_ABI_SYSCALL;
666 ev.u.syscall.entryexit = LTTNG_KERNEL_ABI_SYSCALL_ENTRY;
667 ev.u.syscall.abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_NATIVE;
1ae083ba 668 event_enabler = lttng_event_recorder_enabler_create(LTTNG_ENABLER_FORMAT_NAME, &ev, syscall_event_enabler->chan);
def1e304
MD
669 if (!event_enabler) {
670 return -ENOMEM;
671 }
672 event_recorder = _lttng_kernel_event_recorder_create(event_enabler, desc);
44b1abdc 673 lttng_event_enabler_destroy(&event_enabler->parent);
a67ba386
MD
674 WARN_ON_ONCE(!event_recorder);
675 if (IS_ERR(event_recorder)) {
676 return PTR_ERR(event_recorder);
f405cfce 677 }
0bb716a8 678 hlist_add_head(&event_recorder->priv->parent.u.syscall.node, &syscall_table->unknown_syscall_dispatch);
f405cfce
MD
679 }
680
0bb716a8 681 if (hlist_empty(&syscall_table->compat_unknown_syscall_dispatch)) {
437d5aa5 682 const struct lttng_kernel_event_desc *desc =
d4291869 683 &__event_desc___compat_syscall_entry_unknown;
a67ba386 684 struct lttng_kernel_event_recorder *event_recorder;
1ae083ba 685 struct lttng_event_recorder_enabler *event_enabler;
b76dc1a0
MD
686
687 memset(&ev, 0, sizeof(ev));
606828e4
MD
688 strncpy(ev.name, desc->event_name, LTTNG_KERNEL_ABI_SYM_NAME_LEN);
689 ev.name[LTTNG_KERNEL_ABI_SYM_NAME_LEN - 1] = '\0';
690 ev.instrumentation = LTTNG_KERNEL_ABI_SYSCALL;
691 ev.u.syscall.entryexit = LTTNG_KERNEL_ABI_SYSCALL_ENTRY;
692 ev.u.syscall.abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_COMPAT;
1ae083ba 693 event_enabler = lttng_event_recorder_enabler_create(LTTNG_ENABLER_FORMAT_NAME, &ev, syscall_event_enabler->chan);
def1e304
MD
694 if (!event_enabler) {
695 return -ENOMEM;
696 }
697 event_recorder = _lttng_kernel_event_recorder_create(event_enabler, desc);
a67ba386 698 WARN_ON_ONCE(!event_recorder);
44b1abdc 699 lttng_event_enabler_destroy(&event_enabler->parent);
a67ba386
MD
700 if (IS_ERR(event_recorder)) {
701 return PTR_ERR(event_recorder);
b76dc1a0 702 }
0bb716a8 703 hlist_add_head(&event_recorder->priv->parent.u.syscall.node, &syscall_table->compat_unknown_syscall_dispatch);
b76dc1a0
MD
704 }
705
0bb716a8 706 if (hlist_empty(&syscall_table->compat_unknown_syscall_exit_dispatch)) {
437d5aa5 707 const struct lttng_kernel_event_desc *desc =
5b7ac358 708 &__event_desc___compat_syscall_exit_unknown;
a67ba386 709 struct lttng_kernel_event_recorder *event_recorder;
1ae083ba 710 struct lttng_event_recorder_enabler *event_enabler;
2f804c0a
MD
711
712 memset(&ev, 0, sizeof(ev));
606828e4
MD
713 strncpy(ev.name, desc->event_name, LTTNG_KERNEL_ABI_SYM_NAME_LEN);
714 ev.name[LTTNG_KERNEL_ABI_SYM_NAME_LEN - 1] = '\0';
715 ev.instrumentation = LTTNG_KERNEL_ABI_SYSCALL;
716 ev.u.syscall.entryexit = LTTNG_KERNEL_ABI_SYSCALL_EXIT;
717 ev.u.syscall.abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_COMPAT;
1ae083ba 718 event_enabler = lttng_event_recorder_enabler_create(LTTNG_ENABLER_FORMAT_NAME, &ev, syscall_event_enabler->chan);
def1e304
MD
719 if (!event_enabler) {
720 return -ENOMEM;
721 }
722 event_recorder = _lttng_kernel_event_recorder_create(event_enabler, desc);
a67ba386 723 WARN_ON_ONCE(!event_recorder);
44b1abdc 724 lttng_event_enabler_destroy(&event_enabler->parent);
a67ba386
MD
725 if (IS_ERR(event_recorder)) {
726 return PTR_ERR(event_recorder);
5b7ac358 727 }
0bb716a8 728 hlist_add_head(&event_recorder->priv->parent.u.syscall.node, &syscall_table->compat_unknown_syscall_exit_dispatch);
5b7ac358
MD
729 }
730
0bb716a8 731 if (hlist_empty(&syscall_table->unknown_syscall_exit_dispatch)) {
437d5aa5 732 const struct lttng_kernel_event_desc *desc =
5b7ac358 733 &__event_desc___syscall_exit_unknown;
a67ba386 734 struct lttng_kernel_event_recorder *event_recorder;
1ae083ba 735 struct lttng_event_recorder_enabler *event_enabler;
5b7ac358
MD
736
737 memset(&ev, 0, sizeof(ev));
606828e4
MD
738 strncpy(ev.name, desc->event_name, LTTNG_KERNEL_ABI_SYM_NAME_LEN);
739 ev.name[LTTNG_KERNEL_ABI_SYM_NAME_LEN - 1] = '\0';
740 ev.instrumentation = LTTNG_KERNEL_ABI_SYSCALL;
741 ev.u.syscall.entryexit = LTTNG_KERNEL_ABI_SYSCALL_EXIT;
742 ev.u.syscall.abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_NATIVE;
1ae083ba 743 event_enabler = lttng_event_recorder_enabler_create(LTTNG_ENABLER_FORMAT_NAME, &ev, syscall_event_enabler->chan);
def1e304
MD
744 if (!event_enabler) {
745 return -ENOMEM;
746 }
747 event_recorder = _lttng_kernel_event_recorder_create(event_enabler, desc);
a67ba386 748 WARN_ON_ONCE(!event_recorder);
44b1abdc 749 lttng_event_enabler_destroy(&event_enabler->parent);
a67ba386
MD
750 if (IS_ERR(event_recorder)) {
751 return PTR_ERR(event_recorder);
2f804c0a 752 }
0bb716a8 753 hlist_add_head(&event_recorder->priv->parent.u.syscall.node, &syscall_table->unknown_syscall_exit_dispatch);
2f804c0a
MD
754 }
755
ebcc64cd 756 ret = lttng_create_syscall_event_if_missing(sc_table.table, sc_table.len,
0bb716a8 757 syscall_table->syscall_dispatch, syscall_event_enabler, SC_TYPE_ENTRY);
5b7ac358
MD
758 if (ret)
759 return ret;
ebcc64cd 760 ret = lttng_create_syscall_event_if_missing(sc_exit_table.table, sc_exit_table.len,
0bb716a8 761 syscall_table->syscall_exit_dispatch, syscall_event_enabler, SC_TYPE_EXIT);
49c50022
MD
762 if (ret)
763 return ret;
5b7ac358 764
49c50022 765#ifdef CONFIG_COMPAT
ebcc64cd 766 ret = lttng_create_syscall_event_if_missing(compat_sc_table.table, compat_sc_table.len,
0bb716a8 767 syscall_table->compat_syscall_dispatch, syscall_event_enabler, SC_TYPE_COMPAT_ENTRY);
5b7ac358
MD
768 if (ret)
769 return ret;
ebcc64cd 770 ret = lttng_create_syscall_event_if_missing(compat_sc_exit_table.table, compat_sc_exit_table.len,
0bb716a8 771 syscall_table->compat_syscall_exit_dispatch, syscall_event_enabler, SC_TYPE_COMPAT_EXIT);
49c50022
MD
772 if (ret)
773 return ret;
774#endif
badfe9f5 775
0bb716a8
MD
776 if (!syscall_table->sc_filter) {
777 syscall_table->sc_filter = kzalloc(sizeof(struct lttng_syscall_filter),
badfe9f5 778 GFP_KERNEL);
0bb716a8 779 if (!syscall_table->sc_filter)
badfe9f5
MD
780 return -ENOMEM;
781 }
782
0bb716a8 783 if (!syscall_table->sys_enter_registered) {
80f87dd2 784 ret = lttng_wrapper_tracepoint_probe_register("sys_enter",
0bb716a8 785 (void *) syscall_entry_event_probe, syscall_table);
80f87dd2
MD
786 if (ret)
787 return ret;
0bb716a8 788 syscall_table->sys_enter_registered = 1;
80f87dd2 789 }
63728b02
MD
790 /*
791 * We change the name of sys_exit tracepoint due to namespace
792 * conflict with sys_exit syscall entry.
793 */
0bb716a8 794 if (!syscall_table->sys_exit_registered) {
80f87dd2 795 ret = lttng_wrapper_tracepoint_probe_register("sys_exit",
0bb716a8 796 (void *) syscall_exit_event_probe, syscall_table);
80f87dd2
MD
797 if (ret) {
798 WARN_ON_ONCE(lttng_wrapper_tracepoint_probe_unregister("sys_enter",
0bb716a8 799 (void *) syscall_entry_event_probe, syscall_table));
80f87dd2
MD
800 return ret;
801 }
0bb716a8 802 syscall_table->sys_exit_registered = 1;
63728b02 803 }
259b6cb3
MD
804 return ret;
805}
806
807/*
8a8ac9a8
FD
808 * Should be called with sessions lock held.
809 */
810int lttng_syscalls_register_event_notifier(
a67ba386 811 struct lttng_event_notifier_enabler *event_notifier_enabler)
8a8ac9a8
FD
812{
813 struct lttng_event_notifier_group *group = event_notifier_enabler->group;
0bb716a8 814 struct lttng_kernel_syscall_table *syscall_table = &group->syscall_table;
8a8ac9a8
FD
815 int ret = 0;
816
817 wrapper_vmalloc_sync_mappings();
818
0bb716a8
MD
819 if (!syscall_table->syscall_dispatch) {
820 syscall_table->syscall_dispatch = kzalloc(sizeof(struct hlist_head) * sc_table.len, GFP_KERNEL);
821 if (!syscall_table->syscall_dispatch)
8a8ac9a8 822 return -ENOMEM;
8a8ac9a8
FD
823 }
824
0bb716a8
MD
825 if (!syscall_table->syscall_exit_dispatch) {
826 syscall_table->syscall_exit_dispatch = kzalloc(sizeof(struct hlist_head) * sc_table.len, GFP_KERNEL);
827 if (!syscall_table->syscall_exit_dispatch)
8a8ac9a8 828 return -ENOMEM;
8a8ac9a8
FD
829 }
830
831#ifdef CONFIG_COMPAT
0bb716a8
MD
832 if (!syscall_table->compat_syscall_dispatch) {
833 syscall_table->compat_syscall_dispatch = kzalloc(sizeof(struct hlist_head) * compat_sc_table.len, GFP_KERNEL);
834 if (!syscall_table->compat_syscall_dispatch)
8a8ac9a8 835 return -ENOMEM;
8a8ac9a8
FD
836 }
837
0bb716a8
MD
838 if (!syscall_table->compat_syscall_exit_dispatch) {
839 syscall_table->compat_syscall_exit_dispatch =
ebcc64cd 840 kzalloc(sizeof(struct hlist_head) * compat_sc_exit_table.len,
8a8ac9a8 841 GFP_KERNEL);
0bb716a8 842 if (!syscall_table->compat_syscall_exit_dispatch)
8a8ac9a8 843 return -ENOMEM;
8a8ac9a8
FD
844 }
845#endif
846
0bb716a8
MD
847 if (!syscall_table->sc_filter) {
848 syscall_table->sc_filter = kzalloc(sizeof(struct lttng_syscall_filter),
8a8ac9a8 849 GFP_KERNEL);
0bb716a8 850 if (!syscall_table->sc_filter)
8a8ac9a8
FD
851 return -ENOMEM;
852 }
853
0bb716a8 854 if (!syscall_table->sys_enter_registered) {
8a8ac9a8 855 ret = lttng_wrapper_tracepoint_probe_register("sys_enter",
0bb716a8 856 (void *) syscall_entry_event_probe, syscall_table);
8a8ac9a8
FD
857 if (ret)
858 return ret;
0bb716a8 859 syscall_table->sys_enter_registered = 1;
8a8ac9a8
FD
860 }
861
0bb716a8 862 if (!syscall_table->sys_exit_registered) {
8a8ac9a8 863 ret = lttng_wrapper_tracepoint_probe_register("sys_exit",
0bb716a8 864 (void *) syscall_exit_event_probe, syscall_table);
8a8ac9a8
FD
865 if (ret) {
866 WARN_ON_ONCE(lttng_wrapper_tracepoint_probe_unregister("sys_enter",
0bb716a8 867 (void *) syscall_entry_event_probe, syscall_table));
8a8ac9a8
FD
868 return ret;
869 }
0bb716a8 870 syscall_table->sys_exit_registered = 1;
8a8ac9a8
FD
871 }
872
873 return ret;
874}
875
876static
877int create_unknown_event_notifier(
878 struct lttng_event_notifier_enabler *event_notifier_enabler,
879 enum sc_type type)
880{
a67ba386
MD
881 struct lttng_kernel_event_notifier_private *event_notifier_priv;
882 struct lttng_kernel_event_notifier *event_notifier;
437d5aa5 883 const struct lttng_kernel_event_desc *desc;
8a8ac9a8 884 struct lttng_event_notifier_group *group = event_notifier_enabler->group;
0bb716a8 885 struct lttng_kernel_syscall_table *syscall_table = &group->syscall_table;
606828e4 886 struct lttng_kernel_abi_event_notifier event_notifier_param;
5b9817ae 887 uint64_t user_token = event_notifier_enabler->parent.user_token;
99f52fcc 888 uint64_t error_counter_index = event_notifier_enabler->error_counter_index;
8d554755 889 struct lttng_event_enabler_common *base_enabler = lttng_event_notifier_enabler_as_enabler(
8a8ac9a8
FD
890 event_notifier_enabler);
891 struct hlist_head *unknown_dispatch_list;
892 int ret = 0;
893 bool found = false;
606828e4
MD
894 enum lttng_kernel_abi_syscall_abi abi;
895 enum lttng_kernel_abi_syscall_entryexit entryexit;
8a8ac9a8
FD
896 struct hlist_head *head;
897
898 switch (type) {
899 case SC_TYPE_ENTRY:
900 desc = &__event_desc___syscall_entry_unknown;
0bb716a8 901 unknown_dispatch_list = &syscall_table->unknown_syscall_dispatch;
606828e4
MD
902 entryexit = LTTNG_KERNEL_ABI_SYSCALL_ENTRY;
903 abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_NATIVE;
8a8ac9a8
FD
904 break;
905 case SC_TYPE_EXIT:
906 desc = &__event_desc___syscall_exit_unknown;
0bb716a8 907 unknown_dispatch_list = &syscall_table->unknown_syscall_exit_dispatch;
606828e4
MD
908 entryexit = LTTNG_KERNEL_ABI_SYSCALL_EXIT;
909 abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_NATIVE;
8a8ac9a8
FD
910 break;
911 case SC_TYPE_COMPAT_ENTRY:
912 desc = &__event_desc___compat_syscall_entry_unknown;
0bb716a8 913 unknown_dispatch_list = &syscall_table->compat_unknown_syscall_dispatch;
606828e4
MD
914 entryexit = LTTNG_KERNEL_ABI_SYSCALL_ENTRY;
915 abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_COMPAT;
8a8ac9a8
FD
916 break;
917 case SC_TYPE_COMPAT_EXIT:
918 desc = &__event_desc___compat_syscall_exit_unknown;
0bb716a8 919 unknown_dispatch_list = &syscall_table->compat_unknown_syscall_exit_dispatch;
606828e4
MD
920 entryexit = LTTNG_KERNEL_ABI_SYSCALL_EXIT;
921 abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_COMPAT;
8a8ac9a8
FD
922 break;
923 default:
924 BUG_ON(1);
925 }
926
927 /*
928 * Check if already created.
929 */
930 head = utils_borrow_hash_table_bucket(group->event_notifiers_ht.table,
437d5aa5 931 LTTNG_EVENT_NOTIFIER_HT_SIZE, desc->event_name);
a67ba386
MD
932 lttng_hlist_for_each_entry(event_notifier_priv, head, hlist) {
933 if (event_notifier_priv->parent.desc == desc &&
934 event_notifier_priv->parent.user_token == base_enabler->user_token)
8a8ac9a8
FD
935 found = true;
936 }
937 if (found)
938 goto end;
939
940 memset(&event_notifier_param, 0, sizeof(event_notifier_param));
437d5aa5 941 strncat(event_notifier_param.event.name, desc->event_name,
606828e4 942 LTTNG_KERNEL_ABI_SYM_NAME_LEN - strlen(event_notifier_param.event.name) - 1);
8a8ac9a8 943
606828e4 944 event_notifier_param.event.name[LTTNG_KERNEL_ABI_SYM_NAME_LEN - 1] = '\0';
8a8ac9a8 945
606828e4 946 event_notifier_param.event.instrumentation = LTTNG_KERNEL_ABI_SYSCALL;
8a8ac9a8
FD
947 event_notifier_param.event.u.syscall.abi = abi;
948 event_notifier_param.event.u.syscall.entryexit = entryexit;
949
a67ba386
MD
950 event_notifier = _lttng_event_notifier_create(desc, user_token,
951 error_counter_index, group, &event_notifier_param,
8a8ac9a8 952 event_notifier_param.event.instrumentation);
a67ba386 953 if (IS_ERR(event_notifier)) {
8a8ac9a8 954 printk(KERN_INFO "Unable to create unknown notifier %s\n",
437d5aa5 955 desc->event_name);
8a8ac9a8
FD
956 ret = -ENOMEM;
957 goto end;
958 }
959
a67ba386 960 hlist_add_head_rcu(&event_notifier->priv->parent.u.syscall.node, unknown_dispatch_list);
8a8ac9a8
FD
961
962end:
963 return ret;
964}
965
966static int create_matching_event_notifiers(
967 struct lttng_event_notifier_enabler *event_notifier_enabler,
a67ba386 968 const struct trace_syscall_entry *table,
8a8ac9a8
FD
969 size_t table_len, enum sc_type type)
970{
971 struct lttng_event_notifier_group *group = event_notifier_enabler->group;
437d5aa5 972 const struct lttng_kernel_event_desc *desc;
5b9817ae 973 uint64_t user_token = event_notifier_enabler->parent.user_token;
99f52fcc 974 uint64_t error_counter_index = event_notifier_enabler->error_counter_index;
8a8ac9a8
FD
975 unsigned int i;
976 int ret = 0;
977
978 /* iterate over all syscall and create event_notifier that match */
979 for (i = 0; i < table_len; i++) {
a67ba386
MD
980 struct lttng_kernel_event_notifier_private *event_notifier_priv;
981 struct lttng_kernel_event_notifier *event_notifier;
606828e4 982 struct lttng_kernel_abi_event_notifier event_notifier_param;
8a8ac9a8
FD
983 struct hlist_head *head;
984 int found = 0;
985
986 desc = table[i].desc;
987 if (!desc) {
988 /* Unknown syscall */
989 continue;
990 }
991
992 if (!lttng_desc_match_enabler(desc,
993 lttng_event_notifier_enabler_as_enabler(event_notifier_enabler)))
994 continue;
995
996 /*
997 * Check if already created.
998 */
999 head = utils_borrow_hash_table_bucket(group->event_notifiers_ht.table,
437d5aa5 1000 LTTNG_EVENT_NOTIFIER_HT_SIZE, desc->event_name);
a67ba386
MD
1001 lttng_hlist_for_each_entry(event_notifier_priv, head, hlist) {
1002 if (event_notifier_priv->parent.desc == desc
5b9817ae 1003 && event_notifier_priv->parent.user_token == event_notifier_enabler->parent.user_token)
8a8ac9a8
FD
1004 found = 1;
1005 }
1006 if (found)
1007 continue;
1008
1009 memset(&event_notifier_param, 0, sizeof(event_notifier_param));
1010 switch (type) {
1011 case SC_TYPE_ENTRY:
606828e4
MD
1012 event_notifier_param.event.u.syscall.entryexit = LTTNG_KERNEL_ABI_SYSCALL_ENTRY;
1013 event_notifier_param.event.u.syscall.abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_NATIVE;
8a8ac9a8
FD
1014 break;
1015 case SC_TYPE_EXIT:
606828e4
MD
1016 event_notifier_param.event.u.syscall.entryexit = LTTNG_KERNEL_ABI_SYSCALL_EXIT;
1017 event_notifier_param.event.u.syscall.abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_NATIVE;
8a8ac9a8
FD
1018 break;
1019 case SC_TYPE_COMPAT_ENTRY:
606828e4
MD
1020 event_notifier_param.event.u.syscall.entryexit = LTTNG_KERNEL_ABI_SYSCALL_ENTRY;
1021 event_notifier_param.event.u.syscall.abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_COMPAT;
8a8ac9a8
FD
1022 break;
1023 case SC_TYPE_COMPAT_EXIT:
606828e4
MD
1024 event_notifier_param.event.u.syscall.entryexit = LTTNG_KERNEL_ABI_SYSCALL_EXIT;
1025 event_notifier_param.event.u.syscall.abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_COMPAT;
8a8ac9a8
FD
1026 break;
1027 }
437d5aa5 1028 strncat(event_notifier_param.event.name, desc->event_name,
606828e4
MD
1029 LTTNG_KERNEL_ABI_SYM_NAME_LEN - strlen(event_notifier_param.event.name) - 1);
1030 event_notifier_param.event.name[LTTNG_KERNEL_ABI_SYM_NAME_LEN - 1] = '\0';
1031 event_notifier_param.event.instrumentation = LTTNG_KERNEL_ABI_SYSCALL;
8a8ac9a8 1032
99f52fcc
FD
1033 event_notifier = _lttng_event_notifier_create(desc, user_token,
1034 error_counter_index, group, &event_notifier_param,
a67ba386 1035 event_notifier_param.event.instrumentation);
8a8ac9a8
FD
1036 if (IS_ERR(event_notifier)) {
1037 printk(KERN_INFO "Unable to create event_notifier %s\n",
437d5aa5 1038 desc->event_name);
8a8ac9a8
FD
1039 ret = -ENOMEM;
1040 goto end;
1041 }
1042
a67ba386 1043 event_notifier->priv->parent.u.syscall.syscall_id = i;
8a8ac9a8
FD
1044 }
1045
1046end:
1047 return ret;
1048
1049}
1050
a67ba386
MD
1051int lttng_syscalls_create_matching_event_notifiers(
1052 struct lttng_event_notifier_enabler *event_notifier_enabler)
8a8ac9a8
FD
1053{
1054 int ret;
8d554755 1055 struct lttng_event_enabler_common *base_enabler =
8a8ac9a8 1056 lttng_event_notifier_enabler_as_enabler(event_notifier_enabler);
606828e4 1057 enum lttng_kernel_abi_syscall_entryexit entryexit =
8a8ac9a8
FD
1058 base_enabler->event_param.u.syscall.entryexit;
1059
606828e4 1060 if (entryexit == LTTNG_KERNEL_ABI_SYSCALL_ENTRY || entryexit == LTTNG_KERNEL_ABI_SYSCALL_ENTRYEXIT) {
8a8ac9a8 1061 ret = create_matching_event_notifiers(event_notifier_enabler,
ebcc64cd 1062 sc_table.table, sc_table.len, SC_TYPE_ENTRY);
8a8ac9a8
FD
1063 if (ret)
1064 goto end;
1065
1066 ret = create_matching_event_notifiers(event_notifier_enabler,
ebcc64cd 1067 compat_sc_table.table, compat_sc_table.len,
8a8ac9a8
FD
1068 SC_TYPE_COMPAT_ENTRY);
1069 if (ret)
1070 goto end;
1071
1072 ret = create_unknown_event_notifier(event_notifier_enabler,
1073 SC_TYPE_ENTRY);
1074 if (ret)
1075 goto end;
1076
1077 ret = create_unknown_event_notifier(event_notifier_enabler,
1078 SC_TYPE_COMPAT_ENTRY);
1079 if (ret)
1080 goto end;
1081 }
1082
606828e4 1083 if (entryexit == LTTNG_KERNEL_ABI_SYSCALL_EXIT || entryexit == LTTNG_KERNEL_ABI_SYSCALL_ENTRYEXIT) {
8a8ac9a8 1084 ret = create_matching_event_notifiers(event_notifier_enabler,
ebcc64cd 1085 sc_exit_table.table, sc_exit_table.len,
8a8ac9a8
FD
1086 SC_TYPE_EXIT);
1087 if (ret)
1088 goto end;
1089
1090 ret = create_unknown_event_notifier(event_notifier_enabler,
1091 SC_TYPE_EXIT);
1092 if (ret)
1093 goto end;
1094
1095 ret = create_matching_event_notifiers(event_notifier_enabler,
ebcc64cd 1096 compat_sc_exit_table.table, compat_sc_exit_table.len,
8a8ac9a8
FD
1097 SC_TYPE_COMPAT_EXIT);
1098 if (ret)
1099 goto end;
1100
1101 ret = create_unknown_event_notifier(event_notifier_enabler,
1102 SC_TYPE_COMPAT_EXIT);
1103 if (ret)
1104 goto end;
1105 }
1106
1107end:
1108 return ret;
1109}
1110
6053e75e 1111int lttng_syscalls_unregister_syscall_table(struct lttng_kernel_syscall_table *syscall_table)
259b6cb3
MD
1112{
1113 int ret;
1114
0bb716a8 1115 if (!syscall_table->syscall_dispatch)
259b6cb3 1116 return 0;
0bb716a8 1117 if (syscall_table->sys_enter_registered) {
2d9cd7f3 1118 ret = lttng_wrapper_tracepoint_probe_unregister("sys_enter",
0bb716a8 1119 (void *) syscall_entry_event_probe, syscall_table);
80f87dd2
MD
1120 if (ret)
1121 return ret;
0bb716a8 1122 syscall_table->sys_enter_registered = 0;
80f87dd2 1123 }
0bb716a8 1124 if (syscall_table->sys_exit_registered) {
2d9cd7f3 1125 ret = lttng_wrapper_tracepoint_probe_unregister("sys_exit",
0bb716a8 1126 (void *) syscall_exit_event_probe, syscall_table);
80f87dd2
MD
1127 if (ret)
1128 return ret;
0bb716a8 1129 syscall_table->sys_exit_registered = 0;
80f87dd2 1130 }
badfe9f5
MD
1131 return 0;
1132}
1133
6053e75e 1134int lttng_syscalls_destroy_syscall_table(struct lttng_kernel_syscall_table *syscall_table)
badfe9f5 1135{
0bb716a8
MD
1136 kfree(syscall_table->syscall_dispatch);
1137 kfree(syscall_table->syscall_exit_dispatch);
49c50022 1138#ifdef CONFIG_COMPAT
0bb716a8
MD
1139 kfree(syscall_table->compat_syscall_dispatch);
1140 kfree(syscall_table->compat_syscall_exit_dispatch);
49c50022 1141#endif
0bb716a8 1142 kfree(syscall_table->sc_filter);
80f87dd2
MD
1143 return 0;
1144}
1145
1146static
1147int get_syscall_nr(const char *syscall_name)
1148{
1149 int syscall_nr = -1;
1150 int i;
1151
ebcc64cd 1152 for (i = 0; i < sc_table.len; i++) {
80f87dd2 1153 const struct trace_syscall_entry *entry;
5b7ac358 1154 const char *it_name;
80f87dd2 1155
ebcc64cd 1156 entry = &sc_table.table[i];
80f87dd2
MD
1157 if (!entry->desc)
1158 continue;
437d5aa5 1159 it_name = entry->desc->event_name;
5b7ac358
MD
1160 it_name += strlen(SYSCALL_ENTRY_STR);
1161 if (!strcmp(syscall_name, it_name)) {
80f87dd2
MD
1162 syscall_nr = i;
1163 break;
1164 }
1165 }
1166 return syscall_nr;
1167}
1168
1169static
1170int get_compat_syscall_nr(const char *syscall_name)
1171{
1172 int syscall_nr = -1;
1173 int i;
1174
ebcc64cd 1175 for (i = 0; i < compat_sc_table.len; i++) {
80f87dd2 1176 const struct trace_syscall_entry *entry;
5b7ac358 1177 const char *it_name;
80f87dd2 1178
ebcc64cd 1179 entry = &compat_sc_table.table[i];
80f87dd2
MD
1180 if (!entry->desc)
1181 continue;
437d5aa5 1182 it_name = entry->desc->event_name;
5b7ac358
MD
1183 it_name += strlen(COMPAT_SYSCALL_ENTRY_STR);
1184 if (!strcmp(syscall_name, it_name)) {
80f87dd2
MD
1185 syscall_nr = i;
1186 break;
1187 }
1188 }
1189 return syscall_nr;
1190}
1191
12e579db
MD
1192static
1193uint32_t get_sc_tables_len(void)
1194{
ebcc64cd 1195 return sc_table.len + compat_sc_table.len;
12e579db
MD
1196}
1197
badfe9f5 1198static
ade8a729
FD
1199const char *get_syscall_name(const char *desc_name,
1200 enum lttng_syscall_abi abi,
1201 enum lttng_syscall_entryexit entryexit)
80f87dd2 1202{
badfe9f5 1203 size_t prefix_len = 0;
80f87dd2 1204
80f87dd2 1205
ade8a729 1206 switch (entryexit) {
badfe9f5 1207 case LTTNG_SYSCALL_ENTRY:
ade8a729 1208 switch (abi) {
badfe9f5
MD
1209 case LTTNG_SYSCALL_ABI_NATIVE:
1210 prefix_len = strlen(SYSCALL_ENTRY_STR);
1211 break;
1212 case LTTNG_SYSCALL_ABI_COMPAT:
1213 prefix_len = strlen(COMPAT_SYSCALL_ENTRY_STR);
1214 break;
80f87dd2 1215 }
badfe9f5
MD
1216 break;
1217 case LTTNG_SYSCALL_EXIT:
ade8a729 1218 switch (abi) {
badfe9f5
MD
1219 case LTTNG_SYSCALL_ABI_NATIVE:
1220 prefix_len = strlen(SYSCALL_EXIT_STR);
1221 break;
1222 case LTTNG_SYSCALL_ABI_COMPAT:
1223 prefix_len = strlen(COMPAT_SYSCALL_EXIT_STR);
1224 break;
80f87dd2 1225 }
badfe9f5 1226 break;
80f87dd2 1227 }
badfe9f5 1228 WARN_ON_ONCE(prefix_len == 0);
ade8a729 1229 return desc_name + prefix_len;
badfe9f5
MD
1230}
1231
ade8a729
FD
1232static
1233int lttng_syscall_filter_enable(
1234 struct lttng_syscall_filter *filter,
1235 const char *desc_name, enum lttng_syscall_abi abi,
1236 enum lttng_syscall_entryexit entryexit)
badfe9f5 1237{
badfe9f5
MD
1238 const char *syscall_name;
1239 unsigned long *bitmap;
1240 int syscall_nr;
1241
ade8a729 1242 syscall_name = get_syscall_name(desc_name, abi, entryexit);
badfe9f5 1243
ade8a729 1244 switch (abi) {
badfe9f5
MD
1245 case LTTNG_SYSCALL_ABI_NATIVE:
1246 syscall_nr = get_syscall_nr(syscall_name);
1247 break;
1248 case LTTNG_SYSCALL_ABI_COMPAT:
1249 syscall_nr = get_compat_syscall_nr(syscall_name);
1250 break;
1251 default:
1252 return -EINVAL;
80f87dd2 1253 }
badfe9f5
MD
1254 if (syscall_nr < 0)
1255 return -ENOENT;
1256
ade8a729 1257 switch (entryexit) {
badfe9f5 1258 case LTTNG_SYSCALL_ENTRY:
ade8a729 1259 switch (abi) {
badfe9f5
MD
1260 case LTTNG_SYSCALL_ABI_NATIVE:
1261 bitmap = filter->sc_entry;
1262 break;
1263 case LTTNG_SYSCALL_ABI_COMPAT:
1264 bitmap = filter->sc_compat_entry;
1265 break;
6d9694d8
MD
1266 default:
1267 return -EINVAL;
80f87dd2 1268 }
badfe9f5
MD
1269 break;
1270 case LTTNG_SYSCALL_EXIT:
ade8a729 1271 switch (abi) {
badfe9f5
MD
1272 case LTTNG_SYSCALL_ABI_NATIVE:
1273 bitmap = filter->sc_exit;
1274 break;
1275 case LTTNG_SYSCALL_ABI_COMPAT:
1276 bitmap = filter->sc_compat_exit;
1277 break;
6d9694d8
MD
1278 default:
1279 return -EINVAL;
80f87dd2 1280 }
badfe9f5
MD
1281 break;
1282 default:
1283 return -EINVAL;
80f87dd2 1284 }
badfe9f5
MD
1285 if (test_bit(syscall_nr, bitmap))
1286 return -EEXIST;
1287 bitmap_set(bitmap, syscall_nr, 1);
80f87dd2 1288 return 0;
80f87dd2
MD
1289}
1290
f2db8be3 1291int lttng_syscall_filter_enable_event_notifier(struct lttng_kernel_event_notifier *event_notifier)
8a8ac9a8 1292{
a67ba386 1293 struct lttng_event_notifier_group *group = event_notifier->priv->group;
0bb716a8 1294 struct lttng_kernel_syscall_table *syscall_table = &group->syscall_table;
a67ba386 1295 unsigned int syscall_id = event_notifier->priv->parent.u.syscall.syscall_id;
8a8ac9a8
FD
1296 struct hlist_head *dispatch_list;
1297 int ret = 0;
1298
a67ba386 1299 WARN_ON_ONCE(event_notifier->priv->parent.instrumentation != LTTNG_KERNEL_ABI_SYSCALL);
8a8ac9a8 1300
0bb716a8 1301 ret = lttng_syscall_filter_enable(syscall_table->sc_filter,
a67ba386
MD
1302 event_notifier->priv->parent.desc->event_name,
1303 event_notifier->priv->parent.u.syscall.abi,
1304 event_notifier->priv->parent.u.syscall.entryexit);
8a8ac9a8
FD
1305 if (ret) {
1306 goto end;
1307 }
1308
a67ba386 1309 switch (event_notifier->priv->parent.u.syscall.entryexit) {
8a8ac9a8 1310 case LTTNG_SYSCALL_ENTRY:
a67ba386 1311 switch (event_notifier->priv->parent.u.syscall.abi) {
8a8ac9a8 1312 case LTTNG_SYSCALL_ABI_NATIVE:
0bb716a8 1313 dispatch_list = &syscall_table->syscall_dispatch[syscall_id];
8a8ac9a8
FD
1314 break;
1315 case LTTNG_SYSCALL_ABI_COMPAT:
0bb716a8 1316 dispatch_list = &syscall_table->compat_syscall_dispatch[syscall_id];
8a8ac9a8 1317 break;
6866b1c7
MJ
1318 default:
1319 ret = -EINVAL;
1320 goto end;
8a8ac9a8
FD
1321 }
1322 break;
1323 case LTTNG_SYSCALL_EXIT:
a67ba386 1324 switch (event_notifier->priv->parent.u.syscall.abi) {
8a8ac9a8 1325 case LTTNG_SYSCALL_ABI_NATIVE:
0bb716a8 1326 dispatch_list = &syscall_table->syscall_exit_dispatch[syscall_id];
8a8ac9a8
FD
1327 break;
1328 case LTTNG_SYSCALL_ABI_COMPAT:
0bb716a8 1329 dispatch_list = &syscall_table->compat_syscall_exit_dispatch[syscall_id];
8a8ac9a8 1330 break;
6866b1c7
MJ
1331 default:
1332 ret = -EINVAL;
1333 goto end;
8a8ac9a8
FD
1334 }
1335 break;
6866b1c7
MJ
1336 default:
1337 ret = -EINVAL;
1338 goto end;
8a8ac9a8
FD
1339 }
1340
a67ba386 1341 hlist_add_head_rcu(&event_notifier->priv->parent.u.syscall.node, dispatch_list);
8a8ac9a8
FD
1342
1343end:
1344 return ret ;
1345}
1346
f2db8be3 1347int lttng_syscall_filter_enable_event_recorder(struct lttng_kernel_event_recorder *event_recorder)
80f87dd2 1348{
f2db8be3 1349 struct lttng_kernel_channel_buffer *channel = event_recorder->chan;
0bb716a8
MD
1350 struct lttng_kernel_syscall_table *syscall_table = &channel->priv->parent.syscall_table;
1351
a67ba386 1352 WARN_ON_ONCE(event_recorder->priv->parent.instrumentation != LTTNG_KERNEL_ABI_SYSCALL);
ade8a729 1353
0bb716a8 1354 return lttng_syscall_filter_enable(syscall_table->sc_filter,
a67ba386
MD
1355 event_recorder->priv->parent.desc->event_name,
1356 event_recorder->priv->parent.u.syscall.abi,
1357 event_recorder->priv->parent.u.syscall.entryexit);
ade8a729
FD
1358}
1359
1360static
f2db8be3 1361int lttng_syscall_filter_disable(struct lttng_syscall_filter *filter,
ade8a729
FD
1362 const char *desc_name, enum lttng_syscall_abi abi,
1363 enum lttng_syscall_entryexit entryexit)
1364{
badfe9f5
MD
1365 const char *syscall_name;
1366 unsigned long *bitmap;
1367 int syscall_nr;
80f87dd2 1368
ade8a729 1369 syscall_name = get_syscall_name(desc_name, abi, entryexit);
80f87dd2 1370
ade8a729 1371 switch (abi) {
badfe9f5
MD
1372 case LTTNG_SYSCALL_ABI_NATIVE:
1373 syscall_nr = get_syscall_nr(syscall_name);
1374 break;
1375 case LTTNG_SYSCALL_ABI_COMPAT:
1376 syscall_nr = get_compat_syscall_nr(syscall_name);
1377 break;
1378 default:
1379 return -EINVAL;
80f87dd2 1380 }
badfe9f5
MD
1381 if (syscall_nr < 0)
1382 return -ENOENT;
80f87dd2 1383
ade8a729 1384 switch (entryexit) {
badfe9f5 1385 case LTTNG_SYSCALL_ENTRY:
ade8a729 1386 switch (abi) {
badfe9f5
MD
1387 case LTTNG_SYSCALL_ABI_NATIVE:
1388 bitmap = filter->sc_entry;
1389 break;
1390 case LTTNG_SYSCALL_ABI_COMPAT:
1391 bitmap = filter->sc_compat_entry;
1392 break;
6d9694d8
MD
1393 default:
1394 return -EINVAL;
80f87dd2 1395 }
badfe9f5
MD
1396 break;
1397 case LTTNG_SYSCALL_EXIT:
ade8a729 1398 switch (abi) {
badfe9f5
MD
1399 case LTTNG_SYSCALL_ABI_NATIVE:
1400 bitmap = filter->sc_exit;
1401 break;
1402 case LTTNG_SYSCALL_ABI_COMPAT:
1403 bitmap = filter->sc_compat_exit;
1404 break;
6d9694d8
MD
1405 default:
1406 return -EINVAL;
80f87dd2 1407 }
badfe9f5
MD
1408 break;
1409 default:
1410 return -EINVAL;
80f87dd2 1411 }
badfe9f5
MD
1412 if (!test_bit(syscall_nr, bitmap))
1413 return -EEXIST;
1414 bitmap_clear(bitmap, syscall_nr, 1);
80f87dd2 1415
badfe9f5 1416 return 0;
259b6cb3 1417}
2d2464bd 1418
f2db8be3 1419int lttng_syscall_filter_disable_event_notifier(struct lttng_kernel_event_notifier *event_notifier)
8a8ac9a8 1420{
a67ba386 1421 struct lttng_event_notifier_group *group = event_notifier->priv->group;
0bb716a8 1422 struct lttng_kernel_syscall_table *syscall_table = &group->syscall_table;
8a8ac9a8
FD
1423 int ret;
1424
a67ba386 1425 WARN_ON_ONCE(event_notifier->priv->parent.instrumentation != LTTNG_KERNEL_ABI_SYSCALL);
8a8ac9a8 1426
0bb716a8 1427 ret = lttng_syscall_filter_disable(syscall_table->sc_filter,
a67ba386
MD
1428 event_notifier->priv->parent.desc->event_name,
1429 event_notifier->priv->parent.u.syscall.abi,
1430 event_notifier->priv->parent.u.syscall.entryexit);
8a8ac9a8
FD
1431 WARN_ON_ONCE(ret != 0);
1432
a67ba386 1433 hlist_del_rcu(&event_notifier->priv->parent.u.syscall.node);
8a8ac9a8
FD
1434 return 0;
1435}
1436
f2db8be3 1437int lttng_syscall_filter_disable_event_recorder(struct lttng_kernel_event_recorder *event_recorder)
ade8a729 1438{
f2db8be3 1439 struct lttng_kernel_channel_buffer *channel = event_recorder->chan;
0bb716a8
MD
1440 struct lttng_kernel_syscall_table *syscall_table = &channel->priv->parent.syscall_table;
1441
1442 return lttng_syscall_filter_disable(syscall_table->sc_filter,
a67ba386
MD
1443 event_recorder->priv->parent.desc->event_name,
1444 event_recorder->priv->parent.u.syscall.abi,
1445 event_recorder->priv->parent.u.syscall.entryexit);
ade8a729
FD
1446}
1447
2d2464bd
MD
1448static
1449const struct trace_syscall_entry *syscall_list_get_entry(loff_t *pos)
1450{
1451 const struct trace_syscall_entry *entry;
1452 int iter = 0;
1453
ebcc64cd
FD
1454 for (entry = sc_table.table;
1455 entry < sc_table.table + sc_table.len;
2d2464bd
MD
1456 entry++) {
1457 if (iter++ >= *pos)
1458 return entry;
1459 }
ebcc64cd
FD
1460 for (entry = compat_sc_table.table;
1461 entry < compat_sc_table.table + compat_sc_table.len;
2d2464bd
MD
1462 entry++) {
1463 if (iter++ >= *pos)
1464 return entry;
1465 }
1466 /* End of list */
1467 return NULL;
1468}
1469
1470static
1471void *syscall_list_start(struct seq_file *m, loff_t *pos)
1472{
1473 return (void *) syscall_list_get_entry(pos);
1474}
1475
1476static
1477void *syscall_list_next(struct seq_file *m, void *p, loff_t *ppos)
1478{
1479 (*ppos)++;
1480 return (void *) syscall_list_get_entry(ppos);
1481}
1482
1483static
1484void syscall_list_stop(struct seq_file *m, void *p)
1485{
1486}
1487
12e579db
MD
1488static
1489int get_sc_table(const struct trace_syscall_entry *entry,
1490 const struct trace_syscall_entry **table,
1491 unsigned int *bitness)
1492{
ebcc64cd 1493 if (entry >= sc_table.table && entry < sc_table.table + sc_table.len) {
12e579db
MD
1494 if (bitness)
1495 *bitness = BITS_PER_LONG;
1496 if (table)
ebcc64cd 1497 *table = sc_table.table;
12e579db
MD
1498 return 0;
1499 }
ebcc64cd
FD
1500 if (!(entry >= compat_sc_table.table
1501 && entry < compat_sc_table.table + compat_sc_table.len)) {
12e579db
MD
1502 return -EINVAL;
1503 }
1504 if (bitness)
1505 *bitness = 32;
1506 if (table)
ebcc64cd 1507 *table = compat_sc_table.table;
12e579db
MD
1508 return 0;
1509}
1510
2d2464bd
MD
1511static
1512int syscall_list_show(struct seq_file *m, void *p)
1513{
1514 const struct trace_syscall_entry *table, *entry = p;
1515 unsigned int bitness;
d4291869 1516 unsigned long index;
12e579db 1517 int ret;
d4291869 1518 const char *name;
2d2464bd 1519
12e579db
MD
1520 ret = get_sc_table(entry, &table, &bitness);
1521 if (ret)
1522 return ret;
f4855b46
MD
1523 if (!entry->desc)
1524 return 0;
ebcc64cd 1525 if (table == sc_table.table) {
d4291869 1526 index = entry - table;
437d5aa5 1527 name = &entry->desc->event_name[strlen(SYSCALL_ENTRY_STR)];
d4291869 1528 } else {
ebcc64cd 1529 index = (entry - table) + sc_table.len;
437d5aa5 1530 name = &entry->desc->event_name[strlen(COMPAT_SYSCALL_ENTRY_STR)];
d4291869 1531 }
12e579db 1532 seq_printf(m, "syscall { index = %lu; name = %s; bitness = %u; };\n",
d4291869 1533 index, name, bitness);
2d2464bd
MD
1534 return 0;
1535}
1536
1537static
1538const struct seq_operations lttng_syscall_list_seq_ops = {
1539 .start = syscall_list_start,
1540 .next = syscall_list_next,
1541 .stop = syscall_list_stop,
1542 .show = syscall_list_show,
1543};
1544
1545static
1546int lttng_syscall_list_open(struct inode *inode, struct file *file)
1547{
1548 return seq_open(file, &lttng_syscall_list_seq_ops);
1549}
1550
1551const struct file_operations lttng_syscall_list_fops = {
1552 .owner = THIS_MODULE,
1553 .open = lttng_syscall_list_open,
1554 .read = seq_read,
1555 .llseek = seq_lseek,
1556 .release = seq_release,
1557};
12e579db 1558
badfe9f5
MD
1559/*
1560 * A syscall is enabled if it is traced for either entry or exit.
1561 */
f7d06400 1562long lttng_channel_syscall_mask(struct lttng_kernel_channel_buffer *channel,
606828e4 1563 struct lttng_kernel_abi_syscall_mask __user *usyscall_mask)
12e579db 1564{
0bb716a8 1565 struct lttng_kernel_syscall_table *syscall_table = &channel->priv->parent.syscall_table;
12e579db
MD
1566 uint32_t len, sc_tables_len, bitmask_len;
1567 int ret = 0, bit;
1568 char *tmp_mask;
1569 struct lttng_syscall_filter *filter;
1570
1571 ret = get_user(len, &usyscall_mask->len);
1572 if (ret)
1573 return ret;
1574 sc_tables_len = get_sc_tables_len();
1575 bitmask_len = ALIGN(sc_tables_len, 8) >> 3;
1576 if (len < sc_tables_len) {
1577 return put_user(sc_tables_len, &usyscall_mask->len);
1578 }
1579 /* Array is large enough, we can copy array to user-space. */
1580 tmp_mask = kzalloc(bitmask_len, GFP_KERNEL);
1581 if (!tmp_mask)
1582 return -ENOMEM;
0bb716a8 1583 filter = syscall_table->sc_filter;
12e579db 1584
ebcc64cd 1585 for (bit = 0; bit < sc_table.len; bit++) {
e2129868 1586 char state;
2f25059d 1587
0bb716a8
MD
1588 if (syscall_table->syscall_dispatch) {
1589 if (!(READ_ONCE(syscall_table->syscall_all_entry)
1590 || READ_ONCE(syscall_table->syscall_all_exit)) && filter)
badfe9f5
MD
1591 state = test_bit(bit, filter->sc_entry)
1592 || test_bit(bit, filter->sc_exit);
2f25059d
MD
1593 else
1594 state = 1;
1595 } else {
1596 state = 0;
1597 }
1598 bt_bitfield_write_be(tmp_mask, char, bit, 1, state);
12e579db
MD
1599 }
1600 for (; bit < sc_tables_len; bit++) {
e2129868 1601 char state;
2f25059d 1602
0bb716a8
MD
1603 if (syscall_table->compat_syscall_dispatch) {
1604 if (!(READ_ONCE(syscall_table->syscall_all_entry)
1605 || READ_ONCE(syscall_table->syscall_all_exit)) && filter)
ebcc64cd 1606 state = test_bit(bit - sc_table.len,
badfe9f5 1607 filter->sc_compat_entry)
ebcc64cd 1608 || test_bit(bit - sc_table.len,
badfe9f5 1609 filter->sc_compat_exit);
2f25059d
MD
1610 else
1611 state = 1;
1612 } else {
1613 state = 0;
1614 }
1615 bt_bitfield_write_be(tmp_mask, char, bit, 1, state);
12e579db
MD
1616 }
1617 if (copy_to_user(usyscall_mask->mask, tmp_mask, bitmask_len))
1618 ret = -EFAULT;
1619 kfree(tmp_mask);
1620 return ret;
1621}
082d4946
MD
1622
1623int lttng_abi_syscall_list(void)
1624{
1625 struct file *syscall_list_file;
1626 int file_fd, ret;
1627
4ac10b76 1628 file_fd = lttng_get_unused_fd();
082d4946
MD
1629 if (file_fd < 0) {
1630 ret = file_fd;
1631 goto fd_error;
1632 }
1633
1634 syscall_list_file = anon_inode_getfile("[lttng_syscall_list]",
1635 &lttng_syscall_list_fops,
1636 NULL, O_RDWR);
1637 if (IS_ERR(syscall_list_file)) {
1638 ret = PTR_ERR(syscall_list_file);
1639 goto file_error;
1640 }
1641 ret = lttng_syscall_list_fops.open(NULL, syscall_list_file);
1642 if (ret < 0)
1643 goto open_error;
1644 fd_install(file_fd, syscall_list_file);
082d4946
MD
1645 return file_fd;
1646
1647open_error:
1648 fput(syscall_list_file);
1649file_error:
1650 put_unused_fd(file_fd);
1651fd_error:
1652 return ret;
1653}
This page took 0.145102 seconds and 4 git commands to generate.