Refactoring: rename lttng_channel_create to lttng_channel_buffer_create
[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 */
1ae083ba 619int lttng_syscalls_register_event(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
1111/*
1112 * Unregister the syscall event_notifier probes from the callsites.
259b6cb3 1113 */
3b82c4e1 1114int lttng_syscalls_unregister_event_notifier_group(
8a8ac9a8
FD
1115 struct lttng_event_notifier_group *event_notifier_group)
1116{
0bb716a8 1117 struct lttng_kernel_syscall_table *syscall_table = &event_notifier_group->syscall_table;
8a8ac9a8
FD
1118 int ret;
1119
1120 /*
1121 * Only register the event_notifier probe on the `sys_enter` callsite for now.
1122 * At the moment, we don't think it's desirable to have one fired
1123 * event_notifier for the entry and one for the exit of a syscall.
1124 */
0bb716a8 1125 if (syscall_table->sys_enter_registered) {
8a8ac9a8 1126 ret = lttng_wrapper_tracepoint_probe_unregister("sys_enter",
0bb716a8 1127 (void *) syscall_entry_event_probe, syscall_table);
8a8ac9a8
FD
1128 if (ret)
1129 return ret;
0bb716a8 1130 syscall_table->sys_enter_registered = 0;
8a8ac9a8 1131 }
0bb716a8 1132 if (syscall_table->sys_exit_registered) {
8a8ac9a8 1133 ret = lttng_wrapper_tracepoint_probe_unregister("sys_exit",
0bb716a8 1134 (void *) syscall_exit_event_probe, syscall_table);
8a8ac9a8
FD
1135 if (ret)
1136 return ret;
0bb716a8 1137 syscall_table->sys_enter_registered = 0;
8a8ac9a8
FD
1138 }
1139
0bb716a8
MD
1140 kfree(syscall_table->syscall_dispatch);
1141 kfree(syscall_table->syscall_exit_dispatch);
8a8ac9a8 1142#ifdef CONFIG_COMPAT
0bb716a8
MD
1143 kfree(syscall_table->compat_syscall_dispatch);
1144 kfree(syscall_table->compat_syscall_exit_dispatch);
8a8ac9a8
FD
1145#endif
1146 return 0;
1147}
1148
f7d06400 1149int lttng_syscalls_unregister_channel(struct lttng_kernel_channel_buffer *chan)
259b6cb3 1150{
0bb716a8 1151 struct lttng_kernel_syscall_table *syscall_table = &chan->priv->parent.syscall_table;
259b6cb3
MD
1152 int ret;
1153
0bb716a8 1154 if (!syscall_table->syscall_dispatch)
259b6cb3 1155 return 0;
0bb716a8 1156 if (syscall_table->sys_enter_registered) {
2d9cd7f3 1157 ret = lttng_wrapper_tracepoint_probe_unregister("sys_enter",
0bb716a8 1158 (void *) syscall_entry_event_probe, syscall_table);
80f87dd2
MD
1159 if (ret)
1160 return ret;
0bb716a8 1161 syscall_table->sys_enter_registered = 0;
80f87dd2 1162 }
0bb716a8 1163 if (syscall_table->sys_exit_registered) {
2d9cd7f3 1164 ret = lttng_wrapper_tracepoint_probe_unregister("sys_exit",
0bb716a8 1165 (void *) syscall_exit_event_probe, syscall_table);
80f87dd2
MD
1166 if (ret)
1167 return ret;
0bb716a8 1168 syscall_table->sys_exit_registered = 0;
80f87dd2 1169 }
badfe9f5
MD
1170 return 0;
1171}
1172
289104bf 1173int lttng_syscalls_destroy_channel(struct lttng_kernel_channel_buffer *chan)
badfe9f5 1174{
0bb716a8
MD
1175 struct lttng_kernel_syscall_table *syscall_table = &chan->priv->parent.syscall_table;
1176
1177 kfree(syscall_table->syscall_dispatch);
1178 kfree(syscall_table->syscall_exit_dispatch);
49c50022 1179#ifdef CONFIG_COMPAT
0bb716a8
MD
1180 kfree(syscall_table->compat_syscall_dispatch);
1181 kfree(syscall_table->compat_syscall_exit_dispatch);
49c50022 1182#endif
0bb716a8 1183 kfree(syscall_table->sc_filter);
80f87dd2
MD
1184 return 0;
1185}
1186
1187static
1188int get_syscall_nr(const char *syscall_name)
1189{
1190 int syscall_nr = -1;
1191 int i;
1192
ebcc64cd 1193 for (i = 0; i < sc_table.len; i++) {
80f87dd2 1194 const struct trace_syscall_entry *entry;
5b7ac358 1195 const char *it_name;
80f87dd2 1196
ebcc64cd 1197 entry = &sc_table.table[i];
80f87dd2
MD
1198 if (!entry->desc)
1199 continue;
437d5aa5 1200 it_name = entry->desc->event_name;
5b7ac358
MD
1201 it_name += strlen(SYSCALL_ENTRY_STR);
1202 if (!strcmp(syscall_name, it_name)) {
80f87dd2
MD
1203 syscall_nr = i;
1204 break;
1205 }
1206 }
1207 return syscall_nr;
1208}
1209
1210static
1211int get_compat_syscall_nr(const char *syscall_name)
1212{
1213 int syscall_nr = -1;
1214 int i;
1215
ebcc64cd 1216 for (i = 0; i < compat_sc_table.len; i++) {
80f87dd2 1217 const struct trace_syscall_entry *entry;
5b7ac358 1218 const char *it_name;
80f87dd2 1219
ebcc64cd 1220 entry = &compat_sc_table.table[i];
80f87dd2
MD
1221 if (!entry->desc)
1222 continue;
437d5aa5 1223 it_name = entry->desc->event_name;
5b7ac358
MD
1224 it_name += strlen(COMPAT_SYSCALL_ENTRY_STR);
1225 if (!strcmp(syscall_name, it_name)) {
80f87dd2
MD
1226 syscall_nr = i;
1227 break;
1228 }
1229 }
1230 return syscall_nr;
1231}
1232
12e579db
MD
1233static
1234uint32_t get_sc_tables_len(void)
1235{
ebcc64cd 1236 return sc_table.len + compat_sc_table.len;
12e579db
MD
1237}
1238
badfe9f5 1239static
ade8a729
FD
1240const char *get_syscall_name(const char *desc_name,
1241 enum lttng_syscall_abi abi,
1242 enum lttng_syscall_entryexit entryexit)
80f87dd2 1243{
badfe9f5 1244 size_t prefix_len = 0;
80f87dd2 1245
80f87dd2 1246
ade8a729 1247 switch (entryexit) {
badfe9f5 1248 case LTTNG_SYSCALL_ENTRY:
ade8a729 1249 switch (abi) {
badfe9f5
MD
1250 case LTTNG_SYSCALL_ABI_NATIVE:
1251 prefix_len = strlen(SYSCALL_ENTRY_STR);
1252 break;
1253 case LTTNG_SYSCALL_ABI_COMPAT:
1254 prefix_len = strlen(COMPAT_SYSCALL_ENTRY_STR);
1255 break;
80f87dd2 1256 }
badfe9f5
MD
1257 break;
1258 case LTTNG_SYSCALL_EXIT:
ade8a729 1259 switch (abi) {
badfe9f5
MD
1260 case LTTNG_SYSCALL_ABI_NATIVE:
1261 prefix_len = strlen(SYSCALL_EXIT_STR);
1262 break;
1263 case LTTNG_SYSCALL_ABI_COMPAT:
1264 prefix_len = strlen(COMPAT_SYSCALL_EXIT_STR);
1265 break;
80f87dd2 1266 }
badfe9f5 1267 break;
80f87dd2 1268 }
badfe9f5 1269 WARN_ON_ONCE(prefix_len == 0);
ade8a729 1270 return desc_name + prefix_len;
badfe9f5
MD
1271}
1272
ade8a729
FD
1273static
1274int lttng_syscall_filter_enable(
1275 struct lttng_syscall_filter *filter,
1276 const char *desc_name, enum lttng_syscall_abi abi,
1277 enum lttng_syscall_entryexit entryexit)
badfe9f5 1278{
badfe9f5
MD
1279 const char *syscall_name;
1280 unsigned long *bitmap;
1281 int syscall_nr;
1282
ade8a729 1283 syscall_name = get_syscall_name(desc_name, abi, entryexit);
badfe9f5 1284
ade8a729 1285 switch (abi) {
badfe9f5
MD
1286 case LTTNG_SYSCALL_ABI_NATIVE:
1287 syscall_nr = get_syscall_nr(syscall_name);
1288 break;
1289 case LTTNG_SYSCALL_ABI_COMPAT:
1290 syscall_nr = get_compat_syscall_nr(syscall_name);
1291 break;
1292 default:
1293 return -EINVAL;
80f87dd2 1294 }
badfe9f5
MD
1295 if (syscall_nr < 0)
1296 return -ENOENT;
1297
ade8a729 1298 switch (entryexit) {
badfe9f5 1299 case LTTNG_SYSCALL_ENTRY:
ade8a729 1300 switch (abi) {
badfe9f5
MD
1301 case LTTNG_SYSCALL_ABI_NATIVE:
1302 bitmap = filter->sc_entry;
1303 break;
1304 case LTTNG_SYSCALL_ABI_COMPAT:
1305 bitmap = filter->sc_compat_entry;
1306 break;
6d9694d8
MD
1307 default:
1308 return -EINVAL;
80f87dd2 1309 }
badfe9f5
MD
1310 break;
1311 case LTTNG_SYSCALL_EXIT:
ade8a729 1312 switch (abi) {
badfe9f5
MD
1313 case LTTNG_SYSCALL_ABI_NATIVE:
1314 bitmap = filter->sc_exit;
1315 break;
1316 case LTTNG_SYSCALL_ABI_COMPAT:
1317 bitmap = filter->sc_compat_exit;
1318 break;
6d9694d8
MD
1319 default:
1320 return -EINVAL;
80f87dd2 1321 }
badfe9f5
MD
1322 break;
1323 default:
1324 return -EINVAL;
80f87dd2 1325 }
badfe9f5
MD
1326 if (test_bit(syscall_nr, bitmap))
1327 return -EEXIST;
1328 bitmap_set(bitmap, syscall_nr, 1);
80f87dd2 1329 return 0;
80f87dd2
MD
1330}
1331
f2db8be3 1332int lttng_syscall_filter_enable_event_notifier(struct lttng_kernel_event_notifier *event_notifier)
8a8ac9a8 1333{
a67ba386 1334 struct lttng_event_notifier_group *group = event_notifier->priv->group;
0bb716a8 1335 struct lttng_kernel_syscall_table *syscall_table = &group->syscall_table;
a67ba386 1336 unsigned int syscall_id = event_notifier->priv->parent.u.syscall.syscall_id;
8a8ac9a8
FD
1337 struct hlist_head *dispatch_list;
1338 int ret = 0;
1339
a67ba386 1340 WARN_ON_ONCE(event_notifier->priv->parent.instrumentation != LTTNG_KERNEL_ABI_SYSCALL);
8a8ac9a8 1341
0bb716a8 1342 ret = lttng_syscall_filter_enable(syscall_table->sc_filter,
a67ba386
MD
1343 event_notifier->priv->parent.desc->event_name,
1344 event_notifier->priv->parent.u.syscall.abi,
1345 event_notifier->priv->parent.u.syscall.entryexit);
8a8ac9a8
FD
1346 if (ret) {
1347 goto end;
1348 }
1349
a67ba386 1350 switch (event_notifier->priv->parent.u.syscall.entryexit) {
8a8ac9a8 1351 case LTTNG_SYSCALL_ENTRY:
a67ba386 1352 switch (event_notifier->priv->parent.u.syscall.abi) {
8a8ac9a8 1353 case LTTNG_SYSCALL_ABI_NATIVE:
0bb716a8 1354 dispatch_list = &syscall_table->syscall_dispatch[syscall_id];
8a8ac9a8
FD
1355 break;
1356 case LTTNG_SYSCALL_ABI_COMPAT:
0bb716a8 1357 dispatch_list = &syscall_table->compat_syscall_dispatch[syscall_id];
8a8ac9a8 1358 break;
6866b1c7
MJ
1359 default:
1360 ret = -EINVAL;
1361 goto end;
8a8ac9a8
FD
1362 }
1363 break;
1364 case LTTNG_SYSCALL_EXIT:
a67ba386 1365 switch (event_notifier->priv->parent.u.syscall.abi) {
8a8ac9a8 1366 case LTTNG_SYSCALL_ABI_NATIVE:
0bb716a8 1367 dispatch_list = &syscall_table->syscall_exit_dispatch[syscall_id];
8a8ac9a8
FD
1368 break;
1369 case LTTNG_SYSCALL_ABI_COMPAT:
0bb716a8 1370 dispatch_list = &syscall_table->compat_syscall_exit_dispatch[syscall_id];
8a8ac9a8 1371 break;
6866b1c7
MJ
1372 default:
1373 ret = -EINVAL;
1374 goto end;
8a8ac9a8
FD
1375 }
1376 break;
6866b1c7
MJ
1377 default:
1378 ret = -EINVAL;
1379 goto end;
8a8ac9a8
FD
1380 }
1381
a67ba386 1382 hlist_add_head_rcu(&event_notifier->priv->parent.u.syscall.node, dispatch_list);
8a8ac9a8
FD
1383
1384end:
1385 return ret ;
1386}
1387
f2db8be3 1388int lttng_syscall_filter_enable_event_recorder(struct lttng_kernel_event_recorder *event_recorder)
80f87dd2 1389{
f2db8be3 1390 struct lttng_kernel_channel_buffer *channel = event_recorder->chan;
0bb716a8
MD
1391 struct lttng_kernel_syscall_table *syscall_table = &channel->priv->parent.syscall_table;
1392
a67ba386 1393 WARN_ON_ONCE(event_recorder->priv->parent.instrumentation != LTTNG_KERNEL_ABI_SYSCALL);
ade8a729 1394
0bb716a8 1395 return lttng_syscall_filter_enable(syscall_table->sc_filter,
a67ba386
MD
1396 event_recorder->priv->parent.desc->event_name,
1397 event_recorder->priv->parent.u.syscall.abi,
1398 event_recorder->priv->parent.u.syscall.entryexit);
ade8a729
FD
1399}
1400
1401static
f2db8be3 1402int lttng_syscall_filter_disable(struct lttng_syscall_filter *filter,
ade8a729
FD
1403 const char *desc_name, enum lttng_syscall_abi abi,
1404 enum lttng_syscall_entryexit entryexit)
1405{
badfe9f5
MD
1406 const char *syscall_name;
1407 unsigned long *bitmap;
1408 int syscall_nr;
80f87dd2 1409
ade8a729 1410 syscall_name = get_syscall_name(desc_name, abi, entryexit);
80f87dd2 1411
ade8a729 1412 switch (abi) {
badfe9f5
MD
1413 case LTTNG_SYSCALL_ABI_NATIVE:
1414 syscall_nr = get_syscall_nr(syscall_name);
1415 break;
1416 case LTTNG_SYSCALL_ABI_COMPAT:
1417 syscall_nr = get_compat_syscall_nr(syscall_name);
1418 break;
1419 default:
1420 return -EINVAL;
80f87dd2 1421 }
badfe9f5
MD
1422 if (syscall_nr < 0)
1423 return -ENOENT;
80f87dd2 1424
ade8a729 1425 switch (entryexit) {
badfe9f5 1426 case LTTNG_SYSCALL_ENTRY:
ade8a729 1427 switch (abi) {
badfe9f5
MD
1428 case LTTNG_SYSCALL_ABI_NATIVE:
1429 bitmap = filter->sc_entry;
1430 break;
1431 case LTTNG_SYSCALL_ABI_COMPAT:
1432 bitmap = filter->sc_compat_entry;
1433 break;
6d9694d8
MD
1434 default:
1435 return -EINVAL;
80f87dd2 1436 }
badfe9f5
MD
1437 break;
1438 case LTTNG_SYSCALL_EXIT:
ade8a729 1439 switch (abi) {
badfe9f5
MD
1440 case LTTNG_SYSCALL_ABI_NATIVE:
1441 bitmap = filter->sc_exit;
1442 break;
1443 case LTTNG_SYSCALL_ABI_COMPAT:
1444 bitmap = filter->sc_compat_exit;
1445 break;
6d9694d8
MD
1446 default:
1447 return -EINVAL;
80f87dd2 1448 }
badfe9f5
MD
1449 break;
1450 default:
1451 return -EINVAL;
80f87dd2 1452 }
badfe9f5
MD
1453 if (!test_bit(syscall_nr, bitmap))
1454 return -EEXIST;
1455 bitmap_clear(bitmap, syscall_nr, 1);
80f87dd2 1456
badfe9f5 1457 return 0;
259b6cb3 1458}
2d2464bd 1459
f2db8be3 1460int lttng_syscall_filter_disable_event_notifier(struct lttng_kernel_event_notifier *event_notifier)
8a8ac9a8 1461{
a67ba386 1462 struct lttng_event_notifier_group *group = event_notifier->priv->group;
0bb716a8 1463 struct lttng_kernel_syscall_table *syscall_table = &group->syscall_table;
8a8ac9a8
FD
1464 int ret;
1465
a67ba386 1466 WARN_ON_ONCE(event_notifier->priv->parent.instrumentation != LTTNG_KERNEL_ABI_SYSCALL);
8a8ac9a8 1467
0bb716a8 1468 ret = lttng_syscall_filter_disable(syscall_table->sc_filter,
a67ba386
MD
1469 event_notifier->priv->parent.desc->event_name,
1470 event_notifier->priv->parent.u.syscall.abi,
1471 event_notifier->priv->parent.u.syscall.entryexit);
8a8ac9a8
FD
1472 WARN_ON_ONCE(ret != 0);
1473
a67ba386 1474 hlist_del_rcu(&event_notifier->priv->parent.u.syscall.node);
8a8ac9a8
FD
1475 return 0;
1476}
1477
f2db8be3 1478int lttng_syscall_filter_disable_event_recorder(struct lttng_kernel_event_recorder *event_recorder)
ade8a729 1479{
f2db8be3 1480 struct lttng_kernel_channel_buffer *channel = event_recorder->chan;
0bb716a8
MD
1481 struct lttng_kernel_syscall_table *syscall_table = &channel->priv->parent.syscall_table;
1482
1483 return lttng_syscall_filter_disable(syscall_table->sc_filter,
a67ba386
MD
1484 event_recorder->priv->parent.desc->event_name,
1485 event_recorder->priv->parent.u.syscall.abi,
1486 event_recorder->priv->parent.u.syscall.entryexit);
ade8a729
FD
1487}
1488
2d2464bd
MD
1489static
1490const struct trace_syscall_entry *syscall_list_get_entry(loff_t *pos)
1491{
1492 const struct trace_syscall_entry *entry;
1493 int iter = 0;
1494
ebcc64cd
FD
1495 for (entry = sc_table.table;
1496 entry < sc_table.table + sc_table.len;
2d2464bd
MD
1497 entry++) {
1498 if (iter++ >= *pos)
1499 return entry;
1500 }
ebcc64cd
FD
1501 for (entry = compat_sc_table.table;
1502 entry < compat_sc_table.table + compat_sc_table.len;
2d2464bd
MD
1503 entry++) {
1504 if (iter++ >= *pos)
1505 return entry;
1506 }
1507 /* End of list */
1508 return NULL;
1509}
1510
1511static
1512void *syscall_list_start(struct seq_file *m, loff_t *pos)
1513{
1514 return (void *) syscall_list_get_entry(pos);
1515}
1516
1517static
1518void *syscall_list_next(struct seq_file *m, void *p, loff_t *ppos)
1519{
1520 (*ppos)++;
1521 return (void *) syscall_list_get_entry(ppos);
1522}
1523
1524static
1525void syscall_list_stop(struct seq_file *m, void *p)
1526{
1527}
1528
12e579db
MD
1529static
1530int get_sc_table(const struct trace_syscall_entry *entry,
1531 const struct trace_syscall_entry **table,
1532 unsigned int *bitness)
1533{
ebcc64cd 1534 if (entry >= sc_table.table && entry < sc_table.table + sc_table.len) {
12e579db
MD
1535 if (bitness)
1536 *bitness = BITS_PER_LONG;
1537 if (table)
ebcc64cd 1538 *table = sc_table.table;
12e579db
MD
1539 return 0;
1540 }
ebcc64cd
FD
1541 if (!(entry >= compat_sc_table.table
1542 && entry < compat_sc_table.table + compat_sc_table.len)) {
12e579db
MD
1543 return -EINVAL;
1544 }
1545 if (bitness)
1546 *bitness = 32;
1547 if (table)
ebcc64cd 1548 *table = compat_sc_table.table;
12e579db
MD
1549 return 0;
1550}
1551
2d2464bd
MD
1552static
1553int syscall_list_show(struct seq_file *m, void *p)
1554{
1555 const struct trace_syscall_entry *table, *entry = p;
1556 unsigned int bitness;
d4291869 1557 unsigned long index;
12e579db 1558 int ret;
d4291869 1559 const char *name;
2d2464bd 1560
12e579db
MD
1561 ret = get_sc_table(entry, &table, &bitness);
1562 if (ret)
1563 return ret;
f4855b46
MD
1564 if (!entry->desc)
1565 return 0;
ebcc64cd 1566 if (table == sc_table.table) {
d4291869 1567 index = entry - table;
437d5aa5 1568 name = &entry->desc->event_name[strlen(SYSCALL_ENTRY_STR)];
d4291869 1569 } else {
ebcc64cd 1570 index = (entry - table) + sc_table.len;
437d5aa5 1571 name = &entry->desc->event_name[strlen(COMPAT_SYSCALL_ENTRY_STR)];
d4291869 1572 }
12e579db 1573 seq_printf(m, "syscall { index = %lu; name = %s; bitness = %u; };\n",
d4291869 1574 index, name, bitness);
2d2464bd
MD
1575 return 0;
1576}
1577
1578static
1579const struct seq_operations lttng_syscall_list_seq_ops = {
1580 .start = syscall_list_start,
1581 .next = syscall_list_next,
1582 .stop = syscall_list_stop,
1583 .show = syscall_list_show,
1584};
1585
1586static
1587int lttng_syscall_list_open(struct inode *inode, struct file *file)
1588{
1589 return seq_open(file, &lttng_syscall_list_seq_ops);
1590}
1591
1592const struct file_operations lttng_syscall_list_fops = {
1593 .owner = THIS_MODULE,
1594 .open = lttng_syscall_list_open,
1595 .read = seq_read,
1596 .llseek = seq_lseek,
1597 .release = seq_release,
1598};
12e579db 1599
badfe9f5
MD
1600/*
1601 * A syscall is enabled if it is traced for either entry or exit.
1602 */
f7d06400 1603long lttng_channel_syscall_mask(struct lttng_kernel_channel_buffer *channel,
606828e4 1604 struct lttng_kernel_abi_syscall_mask __user *usyscall_mask)
12e579db 1605{
0bb716a8 1606 struct lttng_kernel_syscall_table *syscall_table = &channel->priv->parent.syscall_table;
12e579db
MD
1607 uint32_t len, sc_tables_len, bitmask_len;
1608 int ret = 0, bit;
1609 char *tmp_mask;
1610 struct lttng_syscall_filter *filter;
1611
1612 ret = get_user(len, &usyscall_mask->len);
1613 if (ret)
1614 return ret;
1615 sc_tables_len = get_sc_tables_len();
1616 bitmask_len = ALIGN(sc_tables_len, 8) >> 3;
1617 if (len < sc_tables_len) {
1618 return put_user(sc_tables_len, &usyscall_mask->len);
1619 }
1620 /* Array is large enough, we can copy array to user-space. */
1621 tmp_mask = kzalloc(bitmask_len, GFP_KERNEL);
1622 if (!tmp_mask)
1623 return -ENOMEM;
0bb716a8 1624 filter = syscall_table->sc_filter;
12e579db 1625
ebcc64cd 1626 for (bit = 0; bit < sc_table.len; bit++) {
e2129868 1627 char state;
2f25059d 1628
0bb716a8
MD
1629 if (syscall_table->syscall_dispatch) {
1630 if (!(READ_ONCE(syscall_table->syscall_all_entry)
1631 || READ_ONCE(syscall_table->syscall_all_exit)) && filter)
badfe9f5
MD
1632 state = test_bit(bit, filter->sc_entry)
1633 || test_bit(bit, filter->sc_exit);
2f25059d
MD
1634 else
1635 state = 1;
1636 } else {
1637 state = 0;
1638 }
1639 bt_bitfield_write_be(tmp_mask, char, bit, 1, state);
12e579db
MD
1640 }
1641 for (; bit < sc_tables_len; bit++) {
e2129868 1642 char state;
2f25059d 1643
0bb716a8
MD
1644 if (syscall_table->compat_syscall_dispatch) {
1645 if (!(READ_ONCE(syscall_table->syscall_all_entry)
1646 || READ_ONCE(syscall_table->syscall_all_exit)) && filter)
ebcc64cd 1647 state = test_bit(bit - sc_table.len,
badfe9f5 1648 filter->sc_compat_entry)
ebcc64cd 1649 || test_bit(bit - sc_table.len,
badfe9f5 1650 filter->sc_compat_exit);
2f25059d
MD
1651 else
1652 state = 1;
1653 } else {
1654 state = 0;
1655 }
1656 bt_bitfield_write_be(tmp_mask, char, bit, 1, state);
12e579db
MD
1657 }
1658 if (copy_to_user(usyscall_mask->mask, tmp_mask, bitmask_len))
1659 ret = -EFAULT;
1660 kfree(tmp_mask);
1661 return ret;
1662}
082d4946
MD
1663
1664int lttng_abi_syscall_list(void)
1665{
1666 struct file *syscall_list_file;
1667 int file_fd, ret;
1668
4ac10b76 1669 file_fd = lttng_get_unused_fd();
082d4946
MD
1670 if (file_fd < 0) {
1671 ret = file_fd;
1672 goto fd_error;
1673 }
1674
1675 syscall_list_file = anon_inode_getfile("[lttng_syscall_list]",
1676 &lttng_syscall_list_fops,
1677 NULL, O_RDWR);
1678 if (IS_ERR(syscall_list_file)) {
1679 ret = PTR_ERR(syscall_list_file);
1680 goto file_error;
1681 }
1682 ret = lttng_syscall_list_fops.open(NULL, syscall_list_file);
1683 if (ret < 0)
1684 goto open_error;
1685 fd_install(file_fd, syscall_list_file);
082d4946
MD
1686 return file_fd;
1687
1688open_error:
1689 fput(syscall_list_file);
1690file_error:
1691 put_unused_fd(file_fd);
1692fd_error:
1693 return ret;
1694}
This page took 0.172753 seconds and 4 git commands to generate.