fix: block: move block-related definitions out of fs.h (v5.16)
[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);
7f52f0d4
MD
133
134 /*
135 * Reference counters keeping track of number of events enabled
136 * for each bit.
137 */
138 u32 sc_entry_refcount_map[NR_syscalls];
139 u32 sc_exit_refcount_map[NR_syscalls];
140 u32 sc_compat_entry_refcount_map[NR_compat_syscalls];
141 u32 sc_compat_exit_refcount_map[NR_compat_syscalls];
80f87dd2
MD
142};
143
3b82c4e1 144static void syscall_entry_event_unknown(struct hlist_head *unknown_action_list_head,
8a8ac9a8 145 struct pt_regs *regs, long id)
f405cfce 146{
1b7b9c65 147 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
a67ba386 148 struct lttng_kernel_event_common_private *event_priv;
f405cfce 149
1b7b9c65 150 lttng_syscall_get_arguments(current, regs, args);
a67ba386 151 lttng_hlist_for_each_entry_rcu(event_priv, unknown_action_list_head, u.syscall.node) {
8a8ac9a8 152 if (unlikely(in_compat_syscall()))
e2d5dbc7 153 __event_probe__compat_syscall_entry_unknown(event_priv->pub, id, args);
8a8ac9a8 154 else
e2d5dbc7 155 __event_probe__syscall_entry_unknown(event_priv->pub, id, args);
8a8ac9a8
FD
156 }
157}
158
63aa9160 159static __always_inline
e2d5dbc7 160void syscall_entry_event_call_func(struct hlist_head *action_list,
3b82c4e1 161 void *func, unsigned int nrargs,
63aa9160 162 struct pt_regs *regs)
259b6cb3 163{
a67ba386 164 struct lttng_kernel_event_common_private *event_priv;
3b82c4e1 165
63aa9160 166 switch (nrargs) {
259b6cb3
MD
167 case 0:
168 {
63aa9160 169 void (*fptr)(void *__data) = func;
259b6cb3 170
e2d5dbc7
MD
171 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node)
172 fptr(event_priv->pub);
259b6cb3
MD
173 break;
174 }
175 case 1:
176 {
63aa9160 177 void (*fptr)(void *__data, unsigned long arg0) = func;
1b7b9c65 178 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
259b6cb3 179
1b7b9c65 180 lttng_syscall_get_arguments(current, regs, args);
e2d5dbc7
MD
181 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node)
182 fptr(event_priv->pub, args[0]);
259b6cb3
MD
183 break;
184 }
185 case 2:
186 {
187 void (*fptr)(void *__data,
188 unsigned long arg0,
63aa9160 189 unsigned long arg1) = func;
1b7b9c65 190 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
259b6cb3 191
1b7b9c65 192 lttng_syscall_get_arguments(current, regs, args);
e2d5dbc7
MD
193 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node)
194 fptr(event_priv->pub, args[0], args[1]);
259b6cb3
MD
195 break;
196 }
197 case 3:
198 {
199 void (*fptr)(void *__data,
200 unsigned long arg0,
201 unsigned long arg1,
63aa9160 202 unsigned long arg2) = func;
1b7b9c65 203 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
259b6cb3 204
1b7b9c65 205 lttng_syscall_get_arguments(current, regs, args);
e2d5dbc7
MD
206 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node)
207 fptr(event_priv->pub, args[0], args[1], args[2]);
259b6cb3
MD
208 break;
209 }
210 case 4:
211 {
212 void (*fptr)(void *__data,
213 unsigned long arg0,
214 unsigned long arg1,
215 unsigned long arg2,
63aa9160 216 unsigned long arg3) = func;
1b7b9c65 217 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
259b6cb3 218
1b7b9c65 219 lttng_syscall_get_arguments(current, regs, args);
e2d5dbc7
MD
220 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node)
221 fptr(event_priv->pub, args[0], args[1], args[2], args[3]);
259b6cb3
MD
222 break;
223 }
224 case 5:
225 {
226 void (*fptr)(void *__data,
227 unsigned long arg0,
228 unsigned long arg1,
229 unsigned long arg2,
230 unsigned long arg3,
63aa9160 231 unsigned long arg4) = func;
1b7b9c65 232 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
259b6cb3 233
1b7b9c65 234 lttng_syscall_get_arguments(current, regs, args);
e2d5dbc7
MD
235 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node)
236 fptr(event_priv->pub, args[0], args[1], args[2], args[3], args[4]);
259b6cb3
MD
237 break;
238 }
239 case 6:
240 {
241 void (*fptr)(void *__data,
242 unsigned long arg0,
243 unsigned long arg1,
244 unsigned long arg2,
245 unsigned long arg3,
246 unsigned long arg4,
63aa9160 247 unsigned long arg5) = func;
1b7b9c65 248 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
259b6cb3 249
1b7b9c65 250 lttng_syscall_get_arguments(current, regs, args);
e2d5dbc7
MD
251 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node)
252 fptr(event_priv->pub, args[0], args[1], args[2],
3b82c4e1 253 args[3], args[4], args[5]);
8a8ac9a8
FD
254 break;
255 }
256 default:
257 break;
258 }
259}
260
63aa9160
FD
261void syscall_entry_event_probe(void *__data, struct pt_regs *regs, long id)
262{
0bb716a8 263 struct lttng_kernel_syscall_table *syscall_table = __data;
3b82c4e1 264 struct hlist_head *action_list, *unknown_action_list;
63aa9160
FD
265 const struct trace_syscall_entry *table, *entry;
266 size_t table_len;
267
268 if (unlikely(in_compat_syscall())) {
0bb716a8 269 struct lttng_syscall_filter *filter = syscall_table->sc_filter;
63aa9160
FD
270
271 if (id < 0 || id >= NR_compat_syscalls
0bb716a8 272 || (!READ_ONCE(syscall_table->syscall_all_entry) && !test_bit(id, filter->sc_compat_entry))) {
63aa9160
FD
273 /* System call filtered out. */
274 return;
275 }
ebcc64cd
FD
276 table = compat_sc_table.table;
277 table_len = compat_sc_table.len;
0bb716a8 278 unknown_action_list = &syscall_table->compat_unknown_syscall_dispatch;
63aa9160 279 } else {
0bb716a8 280 struct lttng_syscall_filter *filter = syscall_table->sc_filter;
63aa9160
FD
281
282 if (id < 0 || id >= NR_syscalls
0bb716a8 283 || (!READ_ONCE(syscall_table->syscall_all_entry) && !test_bit(id, filter->sc_entry))) {
63aa9160
FD
284 /* System call filtered out. */
285 return;
286 }
ebcc64cd
FD
287 table = sc_table.table;
288 table_len = sc_table.len;
0bb716a8 289 unknown_action_list = &syscall_table->unknown_syscall_dispatch;
63aa9160
FD
290 }
291 if (unlikely(id < 0 || id >= table_len)) {
3b82c4e1 292 syscall_entry_event_unknown(unknown_action_list, regs, id);
63aa9160
FD
293 return;
294 }
3b82c4e1
MD
295
296 entry = &table[id];
297 if (!entry->event_func) {
298 syscall_entry_event_unknown(unknown_action_list, regs, id);
63aa9160
FD
299 return;
300 }
3b82c4e1
MD
301
302 if (unlikely(in_compat_syscall())) {
0bb716a8 303 action_list = &syscall_table->compat_syscall_dispatch[id];
3b82c4e1 304 } else {
0bb716a8 305 action_list = &syscall_table->syscall_dispatch[id];
3b82c4e1
MD
306 }
307 if (unlikely(hlist_empty(action_list)))
308 return;
309
e2d5dbc7 310 syscall_entry_event_call_func(action_list, entry->event_func, entry->nrargs, regs);
63aa9160
FD
311}
312
3b82c4e1 313static void syscall_exit_event_unknown(struct hlist_head *unknown_action_list_head,
8a8ac9a8 314 struct pt_regs *regs, long id, long ret)
5b7ac358 315{
1b7b9c65 316 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
a67ba386 317 struct lttng_kernel_event_common_private *event_priv;
5b7ac358 318
1b7b9c65 319 lttng_syscall_get_arguments(current, regs, args);
a67ba386 320 lttng_hlist_for_each_entry_rcu(event_priv, unknown_action_list_head, u.syscall.node) {
3b82c4e1 321 if (unlikely(in_compat_syscall()))
e2d5dbc7 322 __event_probe__compat_syscall_exit_unknown(event_priv->pub, id, ret,
3b82c4e1
MD
323 args);
324 else
e2d5dbc7 325 __event_probe__syscall_exit_unknown(event_priv->pub, id, ret, args);
3b82c4e1 326 }
5b7ac358
MD
327}
328
3b82c4e1 329static __always_inline
e2d5dbc7 330void syscall_exit_event_call_func(struct hlist_head *action_list,
3b82c4e1
MD
331 void *func, unsigned int nrargs,
332 struct pt_regs *regs, long ret)
5b7ac358 333{
a67ba386 334 struct lttng_kernel_event_common_private *event_priv;
badfe9f5 335
3b82c4e1 336 switch (nrargs) {
5b7ac358
MD
337 case 0:
338 {
3b82c4e1 339 void (*fptr)(void *__data, long ret) = func;
5b7ac358 340
e2d5dbc7
MD
341 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node)
342 fptr(event_priv->pub, ret);
5b7ac358
MD
343 break;
344 }
345 case 1:
346 {
347 void (*fptr)(void *__data,
fc4f7161 348 long ret,
3b82c4e1 349 unsigned long arg0) = func;
1b7b9c65 350 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
5b7ac358 351
1b7b9c65 352 lttng_syscall_get_arguments(current, regs, args);
e2d5dbc7
MD
353 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node)
354 fptr(event_priv->pub, ret, args[0]);
5b7ac358
MD
355 break;
356 }
357 case 2:
358 {
359 void (*fptr)(void *__data,
fc4f7161 360 long ret,
5b7ac358 361 unsigned long arg0,
3b82c4e1 362 unsigned long arg1) = func;
1b7b9c65 363 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
5b7ac358 364
1b7b9c65 365 lttng_syscall_get_arguments(current, regs, args);
e2d5dbc7
MD
366 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node)
367 fptr(event_priv->pub, ret, args[0], args[1]);
5b7ac358
MD
368 break;
369 }
370 case 3:
371 {
372 void (*fptr)(void *__data,
fc4f7161 373 long ret,
5b7ac358
MD
374 unsigned long arg0,
375 unsigned long arg1,
3b82c4e1 376 unsigned long arg2) = func;
1b7b9c65 377 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
5b7ac358 378
1b7b9c65 379 lttng_syscall_get_arguments(current, regs, args);
e2d5dbc7
MD
380 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node)
381 fptr(event_priv->pub, ret, args[0], args[1], args[2]);
5b7ac358
MD
382 break;
383 }
384 case 4:
385 {
386 void (*fptr)(void *__data,
fc4f7161 387 long ret,
5b7ac358
MD
388 unsigned long arg0,
389 unsigned long arg1,
390 unsigned long arg2,
3b82c4e1 391 unsigned long arg3) = func;
1b7b9c65 392 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
5b7ac358 393
1b7b9c65 394 lttng_syscall_get_arguments(current, regs, args);
e2d5dbc7
MD
395 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node)
396 fptr(event_priv->pub, ret, args[0], args[1], args[2], args[3]);
5b7ac358
MD
397 break;
398 }
399 case 5:
400 {
401 void (*fptr)(void *__data,
fc4f7161 402 long ret,
5b7ac358
MD
403 unsigned long arg0,
404 unsigned long arg1,
405 unsigned long arg2,
406 unsigned long arg3,
3b82c4e1 407 unsigned long arg4) = func;
1b7b9c65 408 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
5b7ac358 409
1b7b9c65 410 lttng_syscall_get_arguments(current, regs, args);
e2d5dbc7
MD
411 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node)
412 fptr(event_priv->pub, ret, args[0], args[1], args[2], args[3], args[4]);
5b7ac358
MD
413 break;
414 }
415 case 6:
416 {
417 void (*fptr)(void *__data,
fc4f7161 418 long ret,
5b7ac358
MD
419 unsigned long arg0,
420 unsigned long arg1,
421 unsigned long arg2,
422 unsigned long arg3,
423 unsigned long arg4,
3b82c4e1 424 unsigned long arg5) = func;
1b7b9c65 425 unsigned long args[LTTNG_SYSCALL_NR_ARGS];
5b7ac358 426
1b7b9c65 427 lttng_syscall_get_arguments(current, regs, args);
e2d5dbc7
MD
428 lttng_hlist_for_each_entry_rcu(event_priv, action_list, u.syscall.node)
429 fptr(event_priv->pub, ret, args[0], args[1], args[2],
3b82c4e1 430 args[3], args[4], args[5]);
5b7ac358
MD
431 break;
432 }
433 default:
434 break;
435 }
436}
437
3b82c4e1
MD
438void syscall_exit_event_probe(void *__data, struct pt_regs *regs, long ret)
439{
0bb716a8 440 struct lttng_kernel_syscall_table *syscall_table = __data;
3b82c4e1
MD
441 struct hlist_head *action_list, *unknown_action_list;
442 const struct trace_syscall_entry *table, *entry;
443 size_t table_len;
444 long id;
445
446 id = syscall_get_nr(current, regs);
447
448 if (unlikely(in_compat_syscall())) {
0bb716a8 449 struct lttng_syscall_filter *filter = syscall_table->sc_filter;
3b82c4e1
MD
450
451 if (id < 0 || id >= NR_compat_syscalls
0bb716a8 452 || (!READ_ONCE(syscall_table->syscall_all_exit) && !test_bit(id, filter->sc_compat_exit))) {
3b82c4e1
MD
453 /* System call filtered out. */
454 return;
455 }
ebcc64cd
FD
456 table = compat_sc_exit_table.table;
457 table_len = compat_sc_exit_table.len;
0bb716a8 458 unknown_action_list = &syscall_table->compat_unknown_syscall_exit_dispatch;
3b82c4e1 459 } else {
0bb716a8 460 struct lttng_syscall_filter *filter = syscall_table->sc_filter;
3b82c4e1
MD
461
462 if (id < 0 || id >= NR_syscalls
0bb716a8 463 || (!READ_ONCE(syscall_table->syscall_all_exit) && !test_bit(id, filter->sc_exit))) {
3b82c4e1
MD
464 /* System call filtered out. */
465 return;
466 }
ebcc64cd
FD
467 table = sc_exit_table.table;
468 table_len = sc_exit_table.len;
0bb716a8 469 unknown_action_list = &syscall_table->unknown_syscall_exit_dispatch;
3b82c4e1
MD
470 }
471 if (unlikely(id < 0 || id >= table_len)) {
472 syscall_exit_event_unknown(unknown_action_list, regs, id, ret);
473 return;
474 }
475
476 entry = &table[id];
477 if (!entry->event_func) {
478 syscall_exit_event_unknown(unknown_action_list, regs, id, ret);
479 return;
480 }
481
482 if (unlikely(in_compat_syscall())) {
0bb716a8 483 action_list = &syscall_table->compat_syscall_exit_dispatch[id];
3b82c4e1 484 } else {
0bb716a8 485 action_list = &syscall_table->syscall_exit_dispatch[id];
3b82c4e1
MD
486 }
487 if (unlikely(hlist_empty(action_list)))
488 return;
489
e2d5dbc7 490 syscall_exit_event_call_func(action_list, entry->event_func, entry->nrargs,
3b82c4e1
MD
491 regs, ret);
492}
493
0bb716a8
MD
494static
495struct lttng_kernel_syscall_table *get_syscall_table_from_enabler(struct lttng_event_enabler_common *event_enabler)
8a8ac9a8 496{
0bb716a8
MD
497 switch (event_enabler->enabler_type) {
498 case LTTNG_EVENT_ENABLER_TYPE_RECORDER:
499 {
1ae083ba
MD
500 struct lttng_event_recorder_enabler *event_recorder_enabler =
501 container_of(event_enabler, struct lttng_event_recorder_enabler, parent);
0bb716a8 502 return &event_recorder_enabler->chan->priv->parent.syscall_table;
8a8ac9a8 503 }
0bb716a8
MD
504 case LTTNG_EVENT_ENABLER_TYPE_NOTIFIER:
505 {
506 struct lttng_event_notifier_enabler *event_notifier_enabler =
507 container_of(event_enabler, struct lttng_event_notifier_enabler, parent);
508 return &event_notifier_enabler->group->syscall_table;
8a8ac9a8 509 }
0bb716a8
MD
510 default:
511 return NULL;
8a8ac9a8 512 }
0bb716a8 513}
8a8ac9a8 514
0bb716a8
MD
515static
516struct lttng_kernel_syscall_table *get_syscall_table_from_event(struct lttng_kernel_event_common *event)
517{
518 switch (event->type) {
519 case LTTNG_KERNEL_EVENT_TYPE_RECORDER:
520 {
521 struct lttng_kernel_event_recorder *event_recorder =
522 container_of(event, struct lttng_kernel_event_recorder, parent);
523 return &event_recorder->chan->priv->parent.syscall_table;
524 }
525 case LTTNG_KERNEL_EVENT_TYPE_NOTIFIER:
526 {
527 struct lttng_kernel_event_notifier *event_notifier =
528 container_of(event, struct lttng_kernel_event_notifier, parent);
529 return &event_notifier->priv->group->syscall_table;
530 }
531 default:
532 return NULL;
8a8ac9a8 533 }
8a8ac9a8 534}
0bb716a8 535
5408b6d6
MD
536static
537void lttng_syscall_event_enabler_create_event(struct lttng_event_enabler_common *syscall_event_enabler,
99903379 538 const struct lttng_kernel_event_desc *desc, enum sc_type type, unsigned int syscall_nr)
5408b6d6
MD
539{
540 struct lttng_kernel_event_common *event;
541
542 switch (syscall_event_enabler->enabler_type) {
543 case LTTNG_EVENT_ENABLER_TYPE_RECORDER:
544 {
545 struct lttng_event_recorder_enabler *syscall_event_recorder_enabler =
546 container_of(syscall_event_enabler, struct lttng_event_recorder_enabler, parent);
547 struct lttng_event_recorder_enabler *event_recorder_enabler;
548 struct lttng_kernel_abi_event ev;
549
550 /* We need to create an event for this syscall/enabler. */
551 memset(&ev, 0, sizeof(ev));
552 switch (type) {
553 case SC_TYPE_ENTRY:
554 ev.u.syscall.entryexit = LTTNG_KERNEL_ABI_SYSCALL_ENTRY;
555 ev.u.syscall.abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_NATIVE;
556 break;
557 case SC_TYPE_EXIT:
558 ev.u.syscall.entryexit = LTTNG_KERNEL_ABI_SYSCALL_EXIT;
559 ev.u.syscall.abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_NATIVE;
560 break;
561 case SC_TYPE_COMPAT_ENTRY:
562 ev.u.syscall.entryexit = LTTNG_KERNEL_ABI_SYSCALL_ENTRY;
563 ev.u.syscall.abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_COMPAT;
564 break;
565 case SC_TYPE_COMPAT_EXIT:
566 ev.u.syscall.entryexit = LTTNG_KERNEL_ABI_SYSCALL_EXIT;
567 ev.u.syscall.abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_COMPAT;
568 break;
569 }
570 strncpy(ev.name, desc->event_name, LTTNG_KERNEL_ABI_SYM_NAME_LEN - 1);
571 ev.name[LTTNG_KERNEL_ABI_SYM_NAME_LEN - 1] = '\0';
572 ev.instrumentation = LTTNG_KERNEL_ABI_SYSCALL;
573 event_recorder_enabler = lttng_event_recorder_enabler_create(LTTNG_ENABLER_FORMAT_NAME, &ev,
574 syscall_event_recorder_enabler->chan);
575 WARN_ON_ONCE(!event_recorder_enabler);
576 if (!event_recorder_enabler)
577 return;
578 event = _lttng_kernel_event_create(&event_recorder_enabler->parent, desc);
c3fb484e 579 WARN_ON_ONCE(IS_ERR(event));
5408b6d6 580 lttng_event_enabler_destroy(&event_recorder_enabler->parent);
c3fb484e 581 if (IS_ERR(event)) {
5408b6d6
MD
582 printk(KERN_INFO "Unable to create event recorder %s\n", desc->event_name);
583 return;
584 }
9cd106a6 585 event->priv->u.syscall.syscall_id = syscall_nr;
5408b6d6
MD
586 break;
587 }
588 case LTTNG_EVENT_ENABLER_TYPE_NOTIFIER:
589 {
590 struct lttng_event_notifier_enabler *syscall_event_notifier_enabler =
591 container_of(syscall_event_enabler, struct lttng_event_notifier_enabler, parent);
592 struct lttng_event_notifier_enabler *event_notifier_enabler;
593 struct lttng_kernel_abi_event_notifier event_notifier_param;
594 uint64_t user_token = syscall_event_enabler->user_token;
595 uint64_t error_counter_index = syscall_event_notifier_enabler->error_counter_index;
596
597 memset(&event_notifier_param, 0, sizeof(event_notifier_param));
598 switch (type) {
599 case SC_TYPE_ENTRY:
600 event_notifier_param.event.u.syscall.entryexit = LTTNG_KERNEL_ABI_SYSCALL_ENTRY;
601 event_notifier_param.event.u.syscall.abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_NATIVE;
602 break;
603 case SC_TYPE_EXIT:
604 event_notifier_param.event.u.syscall.entryexit = LTTNG_KERNEL_ABI_SYSCALL_EXIT;
605 event_notifier_param.event.u.syscall.abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_NATIVE;
606 break;
607 case SC_TYPE_COMPAT_ENTRY:
608 event_notifier_param.event.u.syscall.entryexit = LTTNG_KERNEL_ABI_SYSCALL_ENTRY;
609 event_notifier_param.event.u.syscall.abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_COMPAT;
610 break;
611 case SC_TYPE_COMPAT_EXIT:
612 event_notifier_param.event.u.syscall.entryexit = LTTNG_KERNEL_ABI_SYSCALL_EXIT;
613 event_notifier_param.event.u.syscall.abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_COMPAT;
614 break;
615 }
616 strncat(event_notifier_param.event.name, desc->event_name,
617 LTTNG_KERNEL_ABI_SYM_NAME_LEN - strlen(event_notifier_param.event.name) - 1);
618 event_notifier_param.event.name[LTTNG_KERNEL_ABI_SYM_NAME_LEN - 1] = '\0';
619 event_notifier_param.event.instrumentation = LTTNG_KERNEL_ABI_SYSCALL;
620 event_notifier_param.event.token = user_token;
621 event_notifier_param.error_counter_index = error_counter_index;
622
623 event_notifier_enabler = lttng_event_notifier_enabler_create(LTTNG_ENABLER_FORMAT_NAME,
624 &event_notifier_param, syscall_event_notifier_enabler->group);
625 WARN_ON_ONCE(!event_notifier_enabler);
626 event = _lttng_kernel_event_create(&event_notifier_enabler->parent, desc);
c3fb484e 627 WARN_ON_ONCE(IS_ERR(event));
5408b6d6 628 lttng_event_enabler_destroy(&event_notifier_enabler->parent);
c3fb484e 629 if (IS_ERR(event)) {
5408b6d6
MD
630 printk(KERN_INFO "Unable to create event notifier %s\n", desc->event_name);
631 return;
632 }
633 event->priv->u.syscall.syscall_id = syscall_nr;
634 break;
635 }
636 default:
637 break;
638 }
639}
640
49c50022 641static
67233a18
MD
642void lttng_syscall_event_enabler_create_matching_syscall_table_events(struct lttng_event_enabler_common *syscall_event_enabler_common,
643 const struct trace_syscall_entry *table, size_t table_len, enum sc_type type)
259b6cb3 644{
063f0825
MD
645 struct lttng_event_ht *events_ht = lttng_get_event_ht_from_enabler(syscall_event_enabler_common);
646 const struct lttng_kernel_event_desc *desc;
259b6cb3 647 unsigned int i;
49c50022 648
1d303f69
MD
649#ifndef CONFIG_COMPAT
650 if (type == SC_TYPE_COMPAT_ENTRY || type == SC_TYPE_COMPAT_EXIT)
1ab4126a 651 return;
1d303f69 652#endif
67233a18 653 /* iterate over all syscall and create event that match */
49c50022 654 for (i = 0; i < table_len; i++) {
19bef247 655 struct lttng_kernel_event_common_private *event_priv;
3b82c4e1 656 struct hlist_head *head;
6768203a 657 bool found = false;
49c50022 658
063f0825 659 desc = table[i].desc;
49c50022
MD
660 if (!desc) {
661 /* Unknown syscall */
662 continue;
663 }
063f0825
MD
664
665 if (!lttng_desc_match_enabler(desc, syscall_event_enabler_common))
3b82c4e1 666 continue;
063f0825 667
49c50022 668 /*
3b82c4e1 669 * Check if already created.
49c50022 670 */
0def9170 671 head = utils_borrow_hash_table_bucket(events_ht->table, LTTNG_EVENT_HT_SIZE, desc->event_name);
19bef247 672 lttng_hlist_for_each_entry(event_priv, head, hlist_node) {
6768203a
MD
673 if (lttng_event_enabler_desc_match_event(syscall_event_enabler_common, desc, event_priv->pub)) {
674 found = true;
675 break;
676 }
3b82c4e1
MD
677 }
678 if (found)
49c50022 679 continue;
3b82c4e1 680
99903379 681 lttng_syscall_event_enabler_create_event(syscall_event_enabler_common, desc, type, i);
49c50022 682 }
49c50022
MD
683}
684
552f7c79
MD
685static
686bool lttng_syscall_event_enabler_is_wildcard_all(struct lttng_event_enabler_common *event_enabler)
687{
688 if (event_enabler->event_param.instrumentation != LTTNG_KERNEL_ABI_SYSCALL)
689 return false;
690 if (event_enabler->event_param.u.syscall.abi != LTTNG_KERNEL_ABI_SYSCALL_ABI_ALL)
691 return false;
692 if (event_enabler->event_param.u.syscall.match != LTTNG_KERNEL_ABI_SYSCALL_MATCH_NAME)
693 return false;
694 if (strcmp(event_enabler->event_param.name, "*"))
695 return false;
696 return true;
697}
698
9f6f4507
MD
699static
700void create_unknown_syscall_event(struct lttng_event_enabler_common *event_enabler, enum sc_type type)
701{
9f6f4507
MD
702 struct lttng_event_ht *events_ht = lttng_get_event_ht_from_enabler(event_enabler);
703 struct lttng_kernel_event_common_private *event_priv;
704 const struct lttng_kernel_event_desc *desc;
9f6f4507
MD
705 bool found = false;
706 struct hlist_head *head;
707
1d303f69
MD
708#ifndef CONFIG_COMPAT
709 if (type == SC_TYPE_COMPAT_ENTRY || type == SC_TYPE_COMPAT_EXIT)
1ab4126a 710 return;
1d303f69 711#endif
552f7c79
MD
712 /*
713 * Considering that currently system calls can only be enabled on a per
714 * name basis (or wildcard based on a name), unknown syscall events are
715 * only used when matching *all* system calls, because this is the only
716 * case which can be associated with an unknown system call.
717 *
718 * When enabling system call on a per system call number basis will be
719 * supported, this will need to be revisited.
720 */
721 if (!lttng_syscall_event_enabler_is_wildcard_all(event_enabler))
722 return;
723
9f6f4507
MD
724 switch (type) {
725 case SC_TYPE_ENTRY:
726 desc = &__event_desc___syscall_entry_unknown;
9f6f4507
MD
727 break;
728 case SC_TYPE_EXIT:
729 desc = &__event_desc___syscall_exit_unknown;
9f6f4507
MD
730 break;
731 case SC_TYPE_COMPAT_ENTRY:
732 desc = &__event_desc___compat_syscall_entry_unknown;
9f6f4507
MD
733 break;
734 case SC_TYPE_COMPAT_EXIT:
735 desc = &__event_desc___compat_syscall_exit_unknown;
9f6f4507
MD
736 break;
737 default:
738 WARN_ON_ONCE(1);
739 }
740
741 /*
742 * Check if already created.
743 */
744 head = utils_borrow_hash_table_bucket(events_ht->table, LTTNG_EVENT_HT_SIZE, desc->event_name);
745 lttng_hlist_for_each_entry(event_priv, head, hlist_node) {
6768203a 746 if (lttng_event_enabler_desc_match_event(event_enabler, desc, event_priv->pub)) {
9f6f4507 747 found = true;
6768203a
MD
748 break;
749 }
9f6f4507
MD
750 }
751 if (!found)
99903379 752 lttng_syscall_event_enabler_create_event(event_enabler, desc, type, -1U);
9f6f4507
MD
753}
754
d26015f6 755static
15a00134 756void lttng_syscall_event_enabler_create_matching_events(struct lttng_event_enabler_common *event_enabler)
49c50022 757{
15a00134 758 enum lttng_kernel_abi_syscall_entryexit entryexit = event_enabler->event_param.u.syscall.entryexit;
5b7ac358 759
15a00134
MD
760 if (entryexit == LTTNG_KERNEL_ABI_SYSCALL_ENTRY || entryexit == LTTNG_KERNEL_ABI_SYSCALL_ENTRYEXIT) {
761 lttng_syscall_event_enabler_create_matching_syscall_table_events(event_enabler,
762 sc_table.table, sc_table.len, SC_TYPE_ENTRY);
763 lttng_syscall_event_enabler_create_matching_syscall_table_events(event_enabler,
764 compat_sc_table.table, compat_sc_table.len, SC_TYPE_COMPAT_ENTRY);
765 create_unknown_syscall_event(event_enabler, SC_TYPE_ENTRY);
766 create_unknown_syscall_event(event_enabler, SC_TYPE_COMPAT_ENTRY);
767 }
1ab4126a 768
15a00134
MD
769 if (entryexit == LTTNG_KERNEL_ABI_SYSCALL_EXIT || entryexit == LTTNG_KERNEL_ABI_SYSCALL_ENTRYEXIT) {
770 lttng_syscall_event_enabler_create_matching_syscall_table_events(event_enabler,
771 sc_exit_table.table, sc_exit_table.len, SC_TYPE_EXIT);
772 lttng_syscall_event_enabler_create_matching_syscall_table_events(event_enabler,
773 compat_sc_exit_table.table, compat_sc_exit_table.len, SC_TYPE_COMPAT_EXIT);
774 create_unknown_syscall_event(event_enabler, SC_TYPE_EXIT);
775 create_unknown_syscall_event(event_enabler, SC_TYPE_COMPAT_EXIT);
776 }
259b6cb3
MD
777}
778
779/*
8a8ac9a8
FD
780 * Should be called with sessions lock held.
781 */
b2f63bde 782int lttng_event_enabler_create_syscall_events_if_missing(struct lttng_event_enabler_common *syscall_event_enabler)
8a8ac9a8 783{
d26015f6
MD
784 struct lttng_kernel_syscall_table *syscall_table = get_syscall_table_from_enabler(syscall_event_enabler);
785 int ret;
8a8ac9a8 786
0bb716a8 787 if (!syscall_table->syscall_dispatch) {
d26015f6 788 /* create syscall table mapping syscall to events */
0bb716a8
MD
789 syscall_table->syscall_dispatch = kzalloc(sizeof(struct hlist_head) * sc_table.len, GFP_KERNEL);
790 if (!syscall_table->syscall_dispatch)
8a8ac9a8 791 return -ENOMEM;
8a8ac9a8 792 }
0bb716a8 793 if (!syscall_table->syscall_exit_dispatch) {
d26015f6
MD
794 /* create syscall table mapping syscall to events */
795 syscall_table->syscall_exit_dispatch = kzalloc(sizeof(struct hlist_head) * sc_exit_table.len, GFP_KERNEL);
0bb716a8 796 if (!syscall_table->syscall_exit_dispatch)
8a8ac9a8 797 return -ENOMEM;
8a8ac9a8
FD
798 }
799
800#ifdef CONFIG_COMPAT
0bb716a8 801 if (!syscall_table->compat_syscall_dispatch) {
d26015f6 802 /* create syscall table mapping compat syscall to events */
0bb716a8
MD
803 syscall_table->compat_syscall_dispatch = kzalloc(sizeof(struct hlist_head) * compat_sc_table.len, GFP_KERNEL);
804 if (!syscall_table->compat_syscall_dispatch)
8a8ac9a8 805 return -ENOMEM;
8a8ac9a8
FD
806 }
807
0bb716a8 808 if (!syscall_table->compat_syscall_exit_dispatch) {
d26015f6
MD
809 /* create syscall table mapping compat syscall to events */
810 syscall_table->compat_syscall_exit_dispatch = kzalloc(sizeof(struct hlist_head) * compat_sc_exit_table.len, GFP_KERNEL);
0bb716a8 811 if (!syscall_table->compat_syscall_exit_dispatch)
8a8ac9a8 812 return -ENOMEM;
8a8ac9a8
FD
813 }
814#endif
0bb716a8
MD
815 if (!syscall_table->sc_filter) {
816 syscall_table->sc_filter = kzalloc(sizeof(struct lttng_syscall_filter),
8a8ac9a8 817 GFP_KERNEL);
0bb716a8 818 if (!syscall_table->sc_filter)
8a8ac9a8
FD
819 return -ENOMEM;
820 }
821
0bb716a8 822 if (!syscall_table->sys_enter_registered) {
8a8ac9a8 823 ret = lttng_wrapper_tracepoint_probe_register("sys_enter",
0bb716a8 824 (void *) syscall_entry_event_probe, syscall_table);
8a8ac9a8
FD
825 if (ret)
826 return ret;
0bb716a8 827 syscall_table->sys_enter_registered = 1;
8a8ac9a8 828 }
0bb716a8 829 if (!syscall_table->sys_exit_registered) {
8a8ac9a8 830 ret = lttng_wrapper_tracepoint_probe_register("sys_exit",
0bb716a8 831 (void *) syscall_exit_event_probe, syscall_table);
8a8ac9a8
FD
832 if (ret) {
833 WARN_ON_ONCE(lttng_wrapper_tracepoint_probe_unregister("sys_enter",
0bb716a8 834 (void *) syscall_entry_event_probe, syscall_table));
8a8ac9a8
FD
835 return ret;
836 }
0bb716a8 837 syscall_table->sys_exit_registered = 1;
8a8ac9a8 838 }
0fab709d 839
86e12a51
MD
840 lttng_syscall_event_enabler_create_matching_events(syscall_event_enabler);
841
8a8ac9a8
FD
842 return ret;
843}
844
6053e75e 845int lttng_syscalls_unregister_syscall_table(struct lttng_kernel_syscall_table *syscall_table)
259b6cb3
MD
846{
847 int ret;
848
0bb716a8 849 if (!syscall_table->syscall_dispatch)
259b6cb3 850 return 0;
0bb716a8 851 if (syscall_table->sys_enter_registered) {
2d9cd7f3 852 ret = lttng_wrapper_tracepoint_probe_unregister("sys_enter",
0bb716a8 853 (void *) syscall_entry_event_probe, syscall_table);
80f87dd2
MD
854 if (ret)
855 return ret;
0bb716a8 856 syscall_table->sys_enter_registered = 0;
80f87dd2 857 }
0bb716a8 858 if (syscall_table->sys_exit_registered) {
2d9cd7f3 859 ret = lttng_wrapper_tracepoint_probe_unregister("sys_exit",
0bb716a8 860 (void *) syscall_exit_event_probe, syscall_table);
80f87dd2
MD
861 if (ret)
862 return ret;
0bb716a8 863 syscall_table->sys_exit_registered = 0;
80f87dd2 864 }
badfe9f5
MD
865 return 0;
866}
867
6053e75e 868int lttng_syscalls_destroy_syscall_table(struct lttng_kernel_syscall_table *syscall_table)
badfe9f5 869{
0bb716a8
MD
870 kfree(syscall_table->syscall_dispatch);
871 kfree(syscall_table->syscall_exit_dispatch);
49c50022 872#ifdef CONFIG_COMPAT
0bb716a8
MD
873 kfree(syscall_table->compat_syscall_dispatch);
874 kfree(syscall_table->compat_syscall_exit_dispatch);
49c50022 875#endif
0bb716a8 876 kfree(syscall_table->sc_filter);
80f87dd2
MD
877 return 0;
878}
879
12e579db
MD
880static
881uint32_t get_sc_tables_len(void)
882{
ebcc64cd 883 return sc_table.len + compat_sc_table.len;
12e579db
MD
884}
885
badfe9f5 886static
ade8a729
FD
887const char *get_syscall_name(const char *desc_name,
888 enum lttng_syscall_abi abi,
889 enum lttng_syscall_entryexit entryexit)
80f87dd2 890{
badfe9f5 891 size_t prefix_len = 0;
80f87dd2 892
80f87dd2 893
ade8a729 894 switch (entryexit) {
badfe9f5 895 case LTTNG_SYSCALL_ENTRY:
ade8a729 896 switch (abi) {
badfe9f5
MD
897 case LTTNG_SYSCALL_ABI_NATIVE:
898 prefix_len = strlen(SYSCALL_ENTRY_STR);
899 break;
900 case LTTNG_SYSCALL_ABI_COMPAT:
901 prefix_len = strlen(COMPAT_SYSCALL_ENTRY_STR);
902 break;
80f87dd2 903 }
badfe9f5
MD
904 break;
905 case LTTNG_SYSCALL_EXIT:
ade8a729 906 switch (abi) {
badfe9f5
MD
907 case LTTNG_SYSCALL_ABI_NATIVE:
908 prefix_len = strlen(SYSCALL_EXIT_STR);
909 break;
910 case LTTNG_SYSCALL_ABI_COMPAT:
911 prefix_len = strlen(COMPAT_SYSCALL_EXIT_STR);
912 break;
80f87dd2 913 }
badfe9f5 914 break;
80f87dd2 915 }
badfe9f5 916 WARN_ON_ONCE(prefix_len == 0);
ade8a729 917 return desc_name + prefix_len;
badfe9f5
MD
918}
919
ade8a729
FD
920static
921int lttng_syscall_filter_enable(
922 struct lttng_syscall_filter *filter,
923 const char *desc_name, enum lttng_syscall_abi abi,
99903379
MD
924 enum lttng_syscall_entryexit entryexit,
925 unsigned int syscall_id)
badfe9f5 926{
badfe9f5
MD
927 const char *syscall_name;
928 unsigned long *bitmap;
7f52f0d4 929 u32 *refcount_map;
badfe9f5 930
ade8a729 931 syscall_name = get_syscall_name(desc_name, abi, entryexit);
badfe9f5 932
ade8a729 933 switch (entryexit) {
badfe9f5 934 case LTTNG_SYSCALL_ENTRY:
ade8a729 935 switch (abi) {
badfe9f5
MD
936 case LTTNG_SYSCALL_ABI_NATIVE:
937 bitmap = filter->sc_entry;
7f52f0d4 938 refcount_map = filter->sc_entry_refcount_map;
badfe9f5
MD
939 break;
940 case LTTNG_SYSCALL_ABI_COMPAT:
941 bitmap = filter->sc_compat_entry;
7f52f0d4 942 refcount_map = filter->sc_compat_entry_refcount_map;
badfe9f5 943 break;
6d9694d8
MD
944 default:
945 return -EINVAL;
80f87dd2 946 }
badfe9f5
MD
947 break;
948 case LTTNG_SYSCALL_EXIT:
ade8a729 949 switch (abi) {
badfe9f5
MD
950 case LTTNG_SYSCALL_ABI_NATIVE:
951 bitmap = filter->sc_exit;
7f52f0d4 952 refcount_map = filter->sc_exit_refcount_map;
badfe9f5
MD
953 break;
954 case LTTNG_SYSCALL_ABI_COMPAT:
955 bitmap = filter->sc_compat_exit;
7f52f0d4 956 refcount_map = filter->sc_compat_exit_refcount_map;
badfe9f5 957 break;
6d9694d8
MD
958 default:
959 return -EINVAL;
80f87dd2 960 }
badfe9f5
MD
961 break;
962 default:
963 return -EINVAL;
80f87dd2 964 }
99903379 965 if (refcount_map[syscall_id] == U32_MAX)
7f52f0d4 966 return -EOVERFLOW;
99903379
MD
967 if (refcount_map[syscall_id]++ == 0)
968 bitmap_set(bitmap, syscall_id, 1);
80f87dd2 969 return 0;
80f87dd2
MD
970}
971
9b2f1c54 972int lttng_syscall_filter_enable_event(struct lttng_kernel_event_common *event)
8a8ac9a8 973{
9b2f1c54 974 struct lttng_kernel_syscall_table *syscall_table = get_syscall_table_from_event(event);
9cd106a6
MD
975 unsigned int syscall_id = event->priv->u.syscall.syscall_id;
976 struct hlist_head *dispatch_list;
9b2f1c54 977 int ret;
8a8ac9a8 978
9b2f1c54 979 WARN_ON_ONCE(event->priv->instrumentation != LTTNG_KERNEL_ABI_SYSCALL);
8a8ac9a8 980
99903379
MD
981 /* Unknown syscall */
982 if (syscall_id == -1U) {
983 switch (event->priv->u.syscall.entryexit) {
984 case LTTNG_SYSCALL_ENTRY:
985 switch (event->priv->u.syscall.abi) {
986 case LTTNG_SYSCALL_ABI_NATIVE:
987 dispatch_list = &syscall_table->unknown_syscall_dispatch;
988 break;
989 case LTTNG_SYSCALL_ABI_COMPAT:
990 dispatch_list = &syscall_table->compat_unknown_syscall_dispatch;
991 break;
992 default:
993 ret = -EINVAL;
994 goto end;
995 }
9cd106a6 996 break;
99903379
MD
997 case LTTNG_SYSCALL_EXIT:
998 switch (event->priv->u.syscall.abi) {
999 case LTTNG_SYSCALL_ABI_NATIVE:
1000 dispatch_list = &syscall_table->unknown_syscall_exit_dispatch;
1001 break;
1002 case LTTNG_SYSCALL_ABI_COMPAT:
1003 dispatch_list = &syscall_table->compat_unknown_syscall_exit_dispatch;
1004 break;
1005 default:
1006 ret = -EINVAL;
1007 goto end;
1008 }
9cd106a6
MD
1009 break;
1010 default:
1011 ret = -EINVAL;
1012 goto end;
1013 }
99903379
MD
1014 } else {
1015 ret = lttng_syscall_filter_enable(syscall_table->sc_filter,
1016 event->priv->desc->event_name, event->priv->u.syscall.abi,
1017 event->priv->u.syscall.entryexit, syscall_id);
1018 if (ret)
1019 return ret;
1020
1021 switch (event->priv->u.syscall.entryexit) {
1022 case LTTNG_SYSCALL_ENTRY:
1023 switch (event->priv->u.syscall.abi) {
1024 case LTTNG_SYSCALL_ABI_NATIVE:
1025 dispatch_list = &syscall_table->syscall_dispatch[syscall_id];
1026 break;
1027 case LTTNG_SYSCALL_ABI_COMPAT:
1028 dispatch_list = &syscall_table->compat_syscall_dispatch[syscall_id];
1029 break;
1030 default:
1031 ret = -EINVAL;
1032 goto end;
1033 }
8a8ac9a8 1034 break;
99903379
MD
1035 case LTTNG_SYSCALL_EXIT:
1036 switch (event->priv->u.syscall.abi) {
1037 case LTTNG_SYSCALL_ABI_NATIVE:
1038 dispatch_list = &syscall_table->syscall_exit_dispatch[syscall_id];
1039 break;
1040 case LTTNG_SYSCALL_ABI_COMPAT:
1041 dispatch_list = &syscall_table->compat_syscall_exit_dispatch[syscall_id];
1042 break;
1043 default:
1044 ret = -EINVAL;
1045 goto end;
1046 }
8a8ac9a8 1047 break;
6866b1c7
MJ
1048 default:
1049 ret = -EINVAL;
1050 goto end;
8a8ac9a8 1051 }
8a8ac9a8 1052 }
9cd106a6
MD
1053
1054 hlist_add_head_rcu(&event->priv->u.syscall.node, dispatch_list);
8a8ac9a8 1055end:
9b2f1c54 1056 return ret;
ade8a729
FD
1057}
1058
1059static
f2db8be3 1060int lttng_syscall_filter_disable(struct lttng_syscall_filter *filter,
ade8a729 1061 const char *desc_name, enum lttng_syscall_abi abi,
99903379
MD
1062 enum lttng_syscall_entryexit entryexit,
1063 unsigned int syscall_id)
ade8a729 1064{
badfe9f5
MD
1065 const char *syscall_name;
1066 unsigned long *bitmap;
7f52f0d4 1067 u32 *refcount_map;
80f87dd2 1068
ade8a729 1069 syscall_name = get_syscall_name(desc_name, abi, entryexit);
80f87dd2 1070
ade8a729 1071 switch (entryexit) {
badfe9f5 1072 case LTTNG_SYSCALL_ENTRY:
ade8a729 1073 switch (abi) {
badfe9f5
MD
1074 case LTTNG_SYSCALL_ABI_NATIVE:
1075 bitmap = filter->sc_entry;
7f52f0d4 1076 refcount_map = filter->sc_entry_refcount_map;
badfe9f5
MD
1077 break;
1078 case LTTNG_SYSCALL_ABI_COMPAT:
1079 bitmap = filter->sc_compat_entry;
7f52f0d4 1080 refcount_map = filter->sc_compat_entry_refcount_map;
badfe9f5 1081 break;
6d9694d8
MD
1082 default:
1083 return -EINVAL;
80f87dd2 1084 }
badfe9f5
MD
1085 break;
1086 case LTTNG_SYSCALL_EXIT:
ade8a729 1087 switch (abi) {
badfe9f5
MD
1088 case LTTNG_SYSCALL_ABI_NATIVE:
1089 bitmap = filter->sc_exit;
7f52f0d4 1090 refcount_map = filter->sc_exit_refcount_map;
badfe9f5
MD
1091 break;
1092 case LTTNG_SYSCALL_ABI_COMPAT:
1093 bitmap = filter->sc_compat_exit;
7f52f0d4 1094 refcount_map = filter->sc_compat_exit_refcount_map;
badfe9f5 1095 break;
6d9694d8
MD
1096 default:
1097 return -EINVAL;
80f87dd2 1098 }
badfe9f5
MD
1099 break;
1100 default:
1101 return -EINVAL;
80f87dd2 1102 }
99903379 1103 if (refcount_map[syscall_id] == 0)
7f52f0d4 1104 return -ENOENT;
99903379
MD
1105 if (--refcount_map[syscall_id] == 0)
1106 bitmap_clear(bitmap, syscall_id, 1);
badfe9f5 1107 return 0;
259b6cb3 1108}
2d2464bd 1109
9b2f1c54 1110int lttng_syscall_filter_disable_event(struct lttng_kernel_event_common *event)
8a8ac9a8 1111{
9b2f1c54 1112 struct lttng_kernel_syscall_table *syscall_table = get_syscall_table_from_event(event);
7f52f0d4 1113 unsigned int syscall_id = event->priv->u.syscall.syscall_id;
8a8ac9a8
FD
1114 int ret;
1115
99903379
MD
1116 /* Except for unknown syscall */
1117 if (syscall_id != -1U) {
1118 ret = lttng_syscall_filter_disable(syscall_table->sc_filter,
1119 event->priv->desc->event_name, event->priv->u.syscall.abi,
1120 event->priv->u.syscall.entryexit, syscall_id);
1121 if (ret)
1122 return ret;
1123 }
9cd106a6 1124 hlist_del_rcu(&event->priv->u.syscall.node);
8a8ac9a8
FD
1125 return 0;
1126}
1127
9cb5be7e
MD
1128void lttng_syscall_table_set_wildcard_all(struct lttng_event_enabler_common *event_enabler)
1129{
1130 struct lttng_kernel_syscall_table *syscall_table = get_syscall_table_from_enabler(event_enabler);
1131 enum lttng_kernel_abi_syscall_entryexit entryexit;
1132 int enabled = event_enabler->enabled;
1133
552f7c79 1134 if (!lttng_syscall_event_enabler_is_wildcard_all(event_enabler))
9cb5be7e 1135 return;
9cb5be7e
MD
1136 entryexit = event_enabler->event_param.u.syscall.entryexit;
1137 if (entryexit == LTTNG_KERNEL_ABI_SYSCALL_ENTRY || entryexit == LTTNG_KERNEL_ABI_SYSCALL_ENTRYEXIT)
1138 WRITE_ONCE(syscall_table->syscall_all_entry, enabled);
1139
1140 if (entryexit == LTTNG_KERNEL_ABI_SYSCALL_EXIT || entryexit == LTTNG_KERNEL_ABI_SYSCALL_ENTRYEXIT)
1141 WRITE_ONCE(syscall_table->syscall_all_exit, enabled);
1142}
1143
2d2464bd
MD
1144static
1145const struct trace_syscall_entry *syscall_list_get_entry(loff_t *pos)
1146{
1147 const struct trace_syscall_entry *entry;
1148 int iter = 0;
1149
ebcc64cd
FD
1150 for (entry = sc_table.table;
1151 entry < sc_table.table + sc_table.len;
2d2464bd
MD
1152 entry++) {
1153 if (iter++ >= *pos)
1154 return entry;
1155 }
ebcc64cd
FD
1156 for (entry = compat_sc_table.table;
1157 entry < compat_sc_table.table + compat_sc_table.len;
2d2464bd
MD
1158 entry++) {
1159 if (iter++ >= *pos)
1160 return entry;
1161 }
1162 /* End of list */
1163 return NULL;
1164}
1165
1166static
1167void *syscall_list_start(struct seq_file *m, loff_t *pos)
1168{
1169 return (void *) syscall_list_get_entry(pos);
1170}
1171
1172static
1173void *syscall_list_next(struct seq_file *m, void *p, loff_t *ppos)
1174{
1175 (*ppos)++;
1176 return (void *) syscall_list_get_entry(ppos);
1177}
1178
1179static
1180void syscall_list_stop(struct seq_file *m, void *p)
1181{
1182}
1183
12e579db
MD
1184static
1185int get_sc_table(const struct trace_syscall_entry *entry,
1186 const struct trace_syscall_entry **table,
1187 unsigned int *bitness)
1188{
ebcc64cd 1189 if (entry >= sc_table.table && entry < sc_table.table + sc_table.len) {
12e579db
MD
1190 if (bitness)
1191 *bitness = BITS_PER_LONG;
1192 if (table)
ebcc64cd 1193 *table = sc_table.table;
12e579db
MD
1194 return 0;
1195 }
ebcc64cd
FD
1196 if (!(entry >= compat_sc_table.table
1197 && entry < compat_sc_table.table + compat_sc_table.len)) {
12e579db
MD
1198 return -EINVAL;
1199 }
1200 if (bitness)
1201 *bitness = 32;
1202 if (table)
ebcc64cd 1203 *table = compat_sc_table.table;
12e579db
MD
1204 return 0;
1205}
1206
2d2464bd
MD
1207static
1208int syscall_list_show(struct seq_file *m, void *p)
1209{
1210 const struct trace_syscall_entry *table, *entry = p;
1211 unsigned int bitness;
d4291869 1212 unsigned long index;
12e579db 1213 int ret;
d4291869 1214 const char *name;
2d2464bd 1215
12e579db
MD
1216 ret = get_sc_table(entry, &table, &bitness);
1217 if (ret)
1218 return ret;
f4855b46
MD
1219 if (!entry->desc)
1220 return 0;
ebcc64cd 1221 if (table == sc_table.table) {
d4291869 1222 index = entry - table;
437d5aa5 1223 name = &entry->desc->event_name[strlen(SYSCALL_ENTRY_STR)];
d4291869 1224 } else {
ebcc64cd 1225 index = (entry - table) + sc_table.len;
437d5aa5 1226 name = &entry->desc->event_name[strlen(COMPAT_SYSCALL_ENTRY_STR)];
d4291869 1227 }
12e579db 1228 seq_printf(m, "syscall { index = %lu; name = %s; bitness = %u; };\n",
d4291869 1229 index, name, bitness);
2d2464bd
MD
1230 return 0;
1231}
1232
1233static
1234const struct seq_operations lttng_syscall_list_seq_ops = {
1235 .start = syscall_list_start,
1236 .next = syscall_list_next,
1237 .stop = syscall_list_stop,
1238 .show = syscall_list_show,
1239};
1240
1241static
1242int lttng_syscall_list_open(struct inode *inode, struct file *file)
1243{
1244 return seq_open(file, &lttng_syscall_list_seq_ops);
1245}
1246
1247const struct file_operations lttng_syscall_list_fops = {
1248 .owner = THIS_MODULE,
1249 .open = lttng_syscall_list_open,
1250 .read = seq_read,
1251 .llseek = seq_lseek,
1252 .release = seq_release,
1253};
12e579db 1254
badfe9f5
MD
1255/*
1256 * A syscall is enabled if it is traced for either entry or exit.
1257 */
c970b655 1258long lttng_syscall_table_get_active_mask(struct lttng_kernel_syscall_table *syscall_table,
606828e4 1259 struct lttng_kernel_abi_syscall_mask __user *usyscall_mask)
12e579db
MD
1260{
1261 uint32_t len, sc_tables_len, bitmask_len;
1262 int ret = 0, bit;
1263 char *tmp_mask;
1264 struct lttng_syscall_filter *filter;
1265
1266 ret = get_user(len, &usyscall_mask->len);
1267 if (ret)
1268 return ret;
1269 sc_tables_len = get_sc_tables_len();
1270 bitmask_len = ALIGN(sc_tables_len, 8) >> 3;
1271 if (len < sc_tables_len) {
1272 return put_user(sc_tables_len, &usyscall_mask->len);
1273 }
1274 /* Array is large enough, we can copy array to user-space. */
1275 tmp_mask = kzalloc(bitmask_len, GFP_KERNEL);
1276 if (!tmp_mask)
1277 return -ENOMEM;
0bb716a8 1278 filter = syscall_table->sc_filter;
12e579db 1279
ebcc64cd 1280 for (bit = 0; bit < sc_table.len; bit++) {
e2129868 1281 char state;
2f25059d 1282
0bb716a8
MD
1283 if (syscall_table->syscall_dispatch) {
1284 if (!(READ_ONCE(syscall_table->syscall_all_entry)
1285 || READ_ONCE(syscall_table->syscall_all_exit)) && filter)
badfe9f5
MD
1286 state = test_bit(bit, filter->sc_entry)
1287 || test_bit(bit, filter->sc_exit);
2f25059d
MD
1288 else
1289 state = 1;
1290 } else {
1291 state = 0;
1292 }
1293 bt_bitfield_write_be(tmp_mask, char, bit, 1, state);
12e579db
MD
1294 }
1295 for (; bit < sc_tables_len; bit++) {
e2129868 1296 char state;
2f25059d 1297
0bb716a8
MD
1298 if (syscall_table->compat_syscall_dispatch) {
1299 if (!(READ_ONCE(syscall_table->syscall_all_entry)
1300 || READ_ONCE(syscall_table->syscall_all_exit)) && filter)
ebcc64cd 1301 state = test_bit(bit - sc_table.len,
badfe9f5 1302 filter->sc_compat_entry)
ebcc64cd 1303 || test_bit(bit - sc_table.len,
badfe9f5 1304 filter->sc_compat_exit);
2f25059d
MD
1305 else
1306 state = 1;
1307 } else {
1308 state = 0;
1309 }
1310 bt_bitfield_write_be(tmp_mask, char, bit, 1, state);
12e579db
MD
1311 }
1312 if (copy_to_user(usyscall_mask->mask, tmp_mask, bitmask_len))
1313 ret = -EFAULT;
1314 kfree(tmp_mask);
1315 return ret;
1316}
082d4946
MD
1317
1318int lttng_abi_syscall_list(void)
1319{
1320 struct file *syscall_list_file;
1321 int file_fd, ret;
1322
4ac10b76 1323 file_fd = lttng_get_unused_fd();
082d4946
MD
1324 if (file_fd < 0) {
1325 ret = file_fd;
1326 goto fd_error;
1327 }
1328
1329 syscall_list_file = anon_inode_getfile("[lttng_syscall_list]",
1330 &lttng_syscall_list_fops,
1331 NULL, O_RDWR);
1332 if (IS_ERR(syscall_list_file)) {
1333 ret = PTR_ERR(syscall_list_file);
1334 goto file_error;
1335 }
1336 ret = lttng_syscall_list_fops.open(NULL, syscall_list_file);
1337 if (ret < 0)
1338 goto open_error;
1339 fd_install(file_fd, syscall_list_file);
082d4946
MD
1340 return file_fd;
1341
1342open_error:
1343 fput(syscall_list_file);
1344file_error:
1345 put_unused_fd(file_fd);
1346fd_error:
1347 return ret;
1348}
This page took 0.132795 seconds and 4 git commands to generate.