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