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