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