Fix: scsi: sd: Atomic write support added in 6.11-rc1
[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:
48c210a7
MD
495 lttng_fallthrough;
496 case LTTNG_EVENT_ENABLER_TYPE_COUNTER:
0bb716a8 497 {
48c210a7
MD
498 struct lttng_event_enabler_session_common *event_enabler_session =
499 container_of(event_enabler, struct lttng_event_enabler_session_common, parent);
500 return &event_enabler_session->chan->priv->syscall_table;
8a8ac9a8 501 }
0bb716a8
MD
502 case LTTNG_EVENT_ENABLER_TYPE_NOTIFIER:
503 {
504 struct lttng_event_notifier_enabler *event_notifier_enabler =
505 container_of(event_enabler, struct lttng_event_notifier_enabler, parent);
506 return &event_notifier_enabler->group->syscall_table;
8a8ac9a8 507 }
0bb716a8
MD
508 default:
509 return NULL;
8a8ac9a8 510 }
0bb716a8 511}
8a8ac9a8 512
0bb716a8
MD
513static
514struct lttng_kernel_syscall_table *get_syscall_table_from_event(struct lttng_kernel_event_common *event)
515{
516 switch (event->type) {
517 case LTTNG_KERNEL_EVENT_TYPE_RECORDER:
48c210a7
MD
518 lttng_fallthrough;
519 case LTTNG_KERNEL_EVENT_TYPE_COUNTER:
0bb716a8 520 {
48c210a7
MD
521 struct lttng_kernel_event_common_private *event_priv = event->priv;
522 struct lttng_kernel_event_session_common_private *event_session_priv =
523 container_of(event_priv, struct lttng_kernel_event_session_common_private, parent);
524 return &event_session_priv->chan->priv->syscall_table;
0bb716a8
MD
525 }
526 case LTTNG_KERNEL_EVENT_TYPE_NOTIFIER:
527 {
528 struct lttng_kernel_event_notifier *event_notifier =
529 container_of(event, struct lttng_kernel_event_notifier, parent);
530 return &event_notifier->priv->group->syscall_table;
531 }
532 default:
533 return NULL;
8a8ac9a8 534 }
8a8ac9a8 535}
0bb716a8 536
5408b6d6
MD
537static
538void lttng_syscall_event_enabler_create_event(struct lttng_event_enabler_common *syscall_event_enabler,
99903379 539 const struct lttng_kernel_event_desc *desc, enum sc_type type, unsigned int syscall_nr)
5408b6d6
MD
540{
541 struct lttng_kernel_event_common *event;
542
543 switch (syscall_event_enabler->enabler_type) {
544 case LTTNG_EVENT_ENABLER_TYPE_RECORDER:
545 {
546 struct lttng_event_recorder_enabler *syscall_event_recorder_enabler =
4a46ca39 547 container_of(syscall_event_enabler, struct lttng_event_recorder_enabler, parent.parent);
5408b6d6
MD
548 struct lttng_event_recorder_enabler *event_recorder_enabler;
549 struct lttng_kernel_abi_event ev;
550
551 /* We need to create an event for this syscall/enabler. */
552 memset(&ev, 0, sizeof(ev));
553 switch (type) {
554 case SC_TYPE_ENTRY:
555 ev.u.syscall.entryexit = LTTNG_KERNEL_ABI_SYSCALL_ENTRY;
556 ev.u.syscall.abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_NATIVE;
557 break;
558 case SC_TYPE_EXIT:
559 ev.u.syscall.entryexit = LTTNG_KERNEL_ABI_SYSCALL_EXIT;
560 ev.u.syscall.abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_NATIVE;
561 break;
562 case SC_TYPE_COMPAT_ENTRY:
563 ev.u.syscall.entryexit = LTTNG_KERNEL_ABI_SYSCALL_ENTRY;
564 ev.u.syscall.abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_COMPAT;
565 break;
566 case SC_TYPE_COMPAT_EXIT:
567 ev.u.syscall.entryexit = LTTNG_KERNEL_ABI_SYSCALL_EXIT;
568 ev.u.syscall.abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_COMPAT;
569 break;
570 }
571 strncpy(ev.name, desc->event_name, LTTNG_KERNEL_ABI_SYM_NAME_LEN - 1);
572 ev.name[LTTNG_KERNEL_ABI_SYM_NAME_LEN - 1] = '\0';
573 ev.instrumentation = LTTNG_KERNEL_ABI_SYSCALL;
6ef1e2f5 574 ev.token = syscall_event_enabler->user_token;
5408b6d6
MD
575 event_recorder_enabler = lttng_event_recorder_enabler_create(LTTNG_ENABLER_FORMAT_NAME, &ev,
576 syscall_event_recorder_enabler->chan);
577 WARN_ON_ONCE(!event_recorder_enabler);
578 if (!event_recorder_enabler)
579 return;
44d1600b 580 event = _lttng_kernel_event_create(&event_recorder_enabler->parent.parent, desc, NULL);
c3fb484e 581 WARN_ON_ONCE(IS_ERR(event));
4a46ca39 582 lttng_event_enabler_destroy(&event_recorder_enabler->parent.parent);
c3fb484e 583 if (IS_ERR(event)) {
5408b6d6
MD
584 printk(KERN_INFO "Unable to create event recorder %s\n", desc->event_name);
585 return;
586 }
9cd106a6 587 event->priv->u.syscall.syscall_id = syscall_nr;
5408b6d6
MD
588 break;
589 }
590 case LTTNG_EVENT_ENABLER_TYPE_NOTIFIER:
591 {
592 struct lttng_event_notifier_enabler *syscall_event_notifier_enabler =
593 container_of(syscall_event_enabler, struct lttng_event_notifier_enabler, parent);
594 struct lttng_event_notifier_enabler *event_notifier_enabler;
595 struct lttng_kernel_abi_event_notifier event_notifier_param;
5408b6d6
MD
596 uint64_t error_counter_index = syscall_event_notifier_enabler->error_counter_index;
597
598 memset(&event_notifier_param, 0, sizeof(event_notifier_param));
599 switch (type) {
600 case SC_TYPE_ENTRY:
601 event_notifier_param.event.u.syscall.entryexit = LTTNG_KERNEL_ABI_SYSCALL_ENTRY;
602 event_notifier_param.event.u.syscall.abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_NATIVE;
603 break;
604 case SC_TYPE_EXIT:
605 event_notifier_param.event.u.syscall.entryexit = LTTNG_KERNEL_ABI_SYSCALL_EXIT;
606 event_notifier_param.event.u.syscall.abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_NATIVE;
607 break;
608 case SC_TYPE_COMPAT_ENTRY:
609 event_notifier_param.event.u.syscall.entryexit = LTTNG_KERNEL_ABI_SYSCALL_ENTRY;
610 event_notifier_param.event.u.syscall.abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_COMPAT;
611 break;
612 case SC_TYPE_COMPAT_EXIT:
613 event_notifier_param.event.u.syscall.entryexit = LTTNG_KERNEL_ABI_SYSCALL_EXIT;
614 event_notifier_param.event.u.syscall.abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_COMPAT;
615 break;
616 }
617 strncat(event_notifier_param.event.name, desc->event_name,
618 LTTNG_KERNEL_ABI_SYM_NAME_LEN - strlen(event_notifier_param.event.name) - 1);
619 event_notifier_param.event.name[LTTNG_KERNEL_ABI_SYM_NAME_LEN - 1] = '\0';
620 event_notifier_param.event.instrumentation = LTTNG_KERNEL_ABI_SYSCALL;
6ef1e2f5 621 event_notifier_param.event.token = syscall_event_enabler->user_token;
5408b6d6
MD
622 event_notifier_param.error_counter_index = error_counter_index;
623
624 event_notifier_enabler = lttng_event_notifier_enabler_create(LTTNG_ENABLER_FORMAT_NAME,
625 &event_notifier_param, syscall_event_notifier_enabler->group);
626 WARN_ON_ONCE(!event_notifier_enabler);
44d1600b 627 event = _lttng_kernel_event_create(&event_notifier_enabler->parent, desc, NULL);
c3fb484e 628 WARN_ON_ONCE(IS_ERR(event));
5408b6d6 629 lttng_event_enabler_destroy(&event_notifier_enabler->parent);
c3fb484e 630 if (IS_ERR(event)) {
5408b6d6
MD
631 printk(KERN_INFO "Unable to create event notifier %s\n", desc->event_name);
632 return;
633 }
634 event->priv->u.syscall.syscall_id = syscall_nr;
635 break;
6ef1e2f5
MD
636 case LTTNG_EVENT_ENABLER_TYPE_COUNTER:
637 {
638 struct lttng_event_counter_enabler *syscall_event_counter_enabler =
639 container_of(syscall_event_enabler, struct lttng_event_counter_enabler, parent.parent);
640 struct lttng_event_counter_enabler *event_counter_enabler;
641 struct lttng_kernel_abi_event ev;
642
643 /* We need to create an event for this syscall/enabler. */
644 memset(&ev, 0, sizeof(ev));
645 switch (type) {
646 case SC_TYPE_ENTRY:
647 ev.u.syscall.entryexit = LTTNG_KERNEL_ABI_SYSCALL_ENTRY;
648 ev.u.syscall.abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_NATIVE;
649 break;
650 case SC_TYPE_EXIT:
651 ev.u.syscall.entryexit = LTTNG_KERNEL_ABI_SYSCALL_EXIT;
652 ev.u.syscall.abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_NATIVE;
653 break;
654 case SC_TYPE_COMPAT_ENTRY:
655 ev.u.syscall.entryexit = LTTNG_KERNEL_ABI_SYSCALL_ENTRY;
656 ev.u.syscall.abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_COMPAT;
657 break;
658 case SC_TYPE_COMPAT_EXIT:
659 ev.u.syscall.entryexit = LTTNG_KERNEL_ABI_SYSCALL_EXIT;
660 ev.u.syscall.abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_COMPAT;
661 break;
662 }
663 strncpy(ev.name, desc->event_name, LTTNG_KERNEL_ABI_SYM_NAME_LEN - 1);
664 ev.name[LTTNG_KERNEL_ABI_SYM_NAME_LEN - 1] = '\0';
665 ev.instrumentation = LTTNG_KERNEL_ABI_SYSCALL;
666 ev.token = syscall_event_enabler->user_token;
667 event_counter_enabler = lttng_event_counter_enabler_create(LTTNG_ENABLER_FORMAT_NAME, &ev,
7b0f1e69 668 syscall_event_counter_enabler->key, syscall_event_counter_enabler->chan);
6ef1e2f5
MD
669 WARN_ON_ONCE(!event_counter_enabler);
670 if (!event_counter_enabler)
671 return;
44d1600b 672 event = _lttng_kernel_event_create(&event_counter_enabler->parent.parent, desc, NULL);
6ef1e2f5
MD
673 lttng_event_enabler_destroy(&event_counter_enabler->parent.parent);
674 if (IS_ERR(event)) {
675 if (PTR_ERR(event) != -EEXIST)
676 printk(KERN_INFO "Unable to create event counter %s\n", desc->event_name);
677 return;
678 }
679 event->priv->u.syscall.syscall_id = syscall_nr;
680 break;
681 }
682
5408b6d6
MD
683 }
684 default:
685 break;
686 }
687}
688
49c50022 689static
67233a18
MD
690void lttng_syscall_event_enabler_create_matching_syscall_table_events(struct lttng_event_enabler_common *syscall_event_enabler_common,
691 const struct trace_syscall_entry *table, size_t table_len, enum sc_type type)
259b6cb3 692{
49b1a300 693 struct lttng_event_ht *events_name_ht = lttng_get_events_name_ht_from_enabler(syscall_event_enabler_common);
063f0825 694 const struct lttng_kernel_event_desc *desc;
259b6cb3 695 unsigned int i;
49c50022 696
1d303f69
MD
697#ifndef CONFIG_COMPAT
698 if (type == SC_TYPE_COMPAT_ENTRY || type == SC_TYPE_COMPAT_EXIT)
1ab4126a 699 return;
1d303f69 700#endif
67233a18 701 /* iterate over all syscall and create event that match */
49c50022 702 for (i = 0; i < table_len; i++) {
7b0f1e69 703 char key_string[LTTNG_KERNEL_COUNTER_KEY_LEN] = { 0 };
19bef247 704 struct lttng_kernel_event_common_private *event_priv;
3b82c4e1 705 struct hlist_head *head;
6768203a 706 bool found = false;
49c50022 707
063f0825 708 desc = table[i].desc;
49c50022
MD
709 if (!desc) {
710 /* Unknown syscall */
711 continue;
712 }
063f0825
MD
713
714 if (!lttng_desc_match_enabler(desc, syscall_event_enabler_common))
3b82c4e1 715 continue;
063f0825 716
d9f47662
MD
717 if (format_event_key(syscall_event_enabler_common, key_string, desc->event_name))
718 continue;
719
49c50022 720 /*
3b82c4e1 721 * Check if already created.
49c50022 722 */
49b1a300
MD
723 head = utils_borrow_hash_table_bucket(events_name_ht->table, LTTNG_EVENT_HT_SIZE, desc->event_name);
724 lttng_hlist_for_each_entry(event_priv, head, hlist_name_node) {
d9f47662 725 if (lttng_event_enabler_event_name_key_match_event(syscall_event_enabler_common, desc->event_name, key_string, event_priv->pub)) {
6768203a
MD
726 found = true;
727 break;
728 }
3b82c4e1
MD
729 }
730 if (found)
49c50022 731 continue;
3b82c4e1 732
99903379 733 lttng_syscall_event_enabler_create_event(syscall_event_enabler_common, desc, type, i);
49c50022 734 }
49c50022
MD
735}
736
552f7c79
MD
737static
738bool lttng_syscall_event_enabler_is_wildcard_all(struct lttng_event_enabler_common *event_enabler)
739{
740 if (event_enabler->event_param.instrumentation != LTTNG_KERNEL_ABI_SYSCALL)
741 return false;
742 if (event_enabler->event_param.u.syscall.abi != LTTNG_KERNEL_ABI_SYSCALL_ABI_ALL)
743 return false;
744 if (event_enabler->event_param.u.syscall.match != LTTNG_KERNEL_ABI_SYSCALL_MATCH_NAME)
745 return false;
746 if (strcmp(event_enabler->event_param.name, "*"))
747 return false;
748 return true;
749}
750
9f6f4507
MD
751static
752void create_unknown_syscall_event(struct lttng_event_enabler_common *event_enabler, enum sc_type type)
753{
7b0f1e69 754 char key_string[LTTNG_KERNEL_COUNTER_KEY_LEN] = { 0 };
49b1a300 755 struct lttng_event_ht *events_name_ht = lttng_get_events_name_ht_from_enabler(event_enabler);
9f6f4507
MD
756 struct lttng_kernel_event_common_private *event_priv;
757 const struct lttng_kernel_event_desc *desc;
9f6f4507
MD
758 bool found = false;
759 struct hlist_head *head;
760
1d303f69
MD
761#ifndef CONFIG_COMPAT
762 if (type == SC_TYPE_COMPAT_ENTRY || type == SC_TYPE_COMPAT_EXIT)
1ab4126a 763 return;
1d303f69 764#endif
552f7c79
MD
765 /*
766 * Considering that currently system calls can only be enabled on a per
767 * name basis (or wildcard based on a name), unknown syscall events are
768 * only used when matching *all* system calls, because this is the only
769 * case which can be associated with an unknown system call.
770 *
771 * When enabling system call on a per system call number basis will be
772 * supported, this will need to be revisited.
773 */
774 if (!lttng_syscall_event_enabler_is_wildcard_all(event_enabler))
775 return;
776
9f6f4507
MD
777 switch (type) {
778 case SC_TYPE_ENTRY:
779 desc = &__event_desc___syscall_entry_unknown;
9f6f4507
MD
780 break;
781 case SC_TYPE_EXIT:
782 desc = &__event_desc___syscall_exit_unknown;
9f6f4507
MD
783 break;
784 case SC_TYPE_COMPAT_ENTRY:
785 desc = &__event_desc___compat_syscall_entry_unknown;
9f6f4507
MD
786 break;
787 case SC_TYPE_COMPAT_EXIT:
788 desc = &__event_desc___compat_syscall_exit_unknown;
9f6f4507
MD
789 break;
790 default:
791 WARN_ON_ONCE(1);
792 }
793
d9f47662
MD
794 if (format_event_key(event_enabler, key_string, desc->event_name))
795 return;
796
9f6f4507
MD
797 /*
798 * Check if already created.
799 */
49b1a300
MD
800 head = utils_borrow_hash_table_bucket(events_name_ht->table, LTTNG_EVENT_HT_SIZE, desc->event_name);
801 lttng_hlist_for_each_entry(event_priv, head, hlist_name_node) {
d9f47662 802 if (lttng_event_enabler_event_name_key_match_event(event_enabler, desc->event_name, key_string, event_priv->pub)) {
9f6f4507 803 found = true;
6768203a
MD
804 break;
805 }
9f6f4507
MD
806 }
807 if (!found)
99903379 808 lttng_syscall_event_enabler_create_event(event_enabler, desc, type, -1U);
9f6f4507
MD
809}
810
d26015f6 811static
15a00134 812void lttng_syscall_event_enabler_create_matching_events(struct lttng_event_enabler_common *event_enabler)
49c50022 813{
15a00134 814 enum lttng_kernel_abi_syscall_entryexit entryexit = event_enabler->event_param.u.syscall.entryexit;
5b7ac358 815
15a00134
MD
816 if (entryexit == LTTNG_KERNEL_ABI_SYSCALL_ENTRY || entryexit == LTTNG_KERNEL_ABI_SYSCALL_ENTRYEXIT) {
817 lttng_syscall_event_enabler_create_matching_syscall_table_events(event_enabler,
818 sc_table.table, sc_table.len, SC_TYPE_ENTRY);
819 lttng_syscall_event_enabler_create_matching_syscall_table_events(event_enabler,
820 compat_sc_table.table, compat_sc_table.len, SC_TYPE_COMPAT_ENTRY);
821 create_unknown_syscall_event(event_enabler, SC_TYPE_ENTRY);
822 create_unknown_syscall_event(event_enabler, SC_TYPE_COMPAT_ENTRY);
823 }
1ab4126a 824
15a00134
MD
825 if (entryexit == LTTNG_KERNEL_ABI_SYSCALL_EXIT || entryexit == LTTNG_KERNEL_ABI_SYSCALL_ENTRYEXIT) {
826 lttng_syscall_event_enabler_create_matching_syscall_table_events(event_enabler,
827 sc_exit_table.table, sc_exit_table.len, SC_TYPE_EXIT);
828 lttng_syscall_event_enabler_create_matching_syscall_table_events(event_enabler,
829 compat_sc_exit_table.table, compat_sc_exit_table.len, SC_TYPE_COMPAT_EXIT);
830 create_unknown_syscall_event(event_enabler, SC_TYPE_EXIT);
831 create_unknown_syscall_event(event_enabler, SC_TYPE_COMPAT_EXIT);
832 }
259b6cb3
MD
833}
834
835/*
8a8ac9a8
FD
836 * Should be called with sessions lock held.
837 */
b2f63bde 838int lttng_event_enabler_create_syscall_events_if_missing(struct lttng_event_enabler_common *syscall_event_enabler)
8a8ac9a8 839{
d26015f6
MD
840 struct lttng_kernel_syscall_table *syscall_table = get_syscall_table_from_enabler(syscall_event_enabler);
841 int ret;
8a8ac9a8 842
0bb716a8 843 if (!syscall_table->syscall_dispatch) {
d26015f6 844 /* create syscall table mapping syscall to events */
0bb716a8
MD
845 syscall_table->syscall_dispatch = kzalloc(sizeof(struct hlist_head) * sc_table.len, GFP_KERNEL);
846 if (!syscall_table->syscall_dispatch)
8a8ac9a8 847 return -ENOMEM;
8a8ac9a8 848 }
0bb716a8 849 if (!syscall_table->syscall_exit_dispatch) {
d26015f6
MD
850 /* create syscall table mapping syscall to events */
851 syscall_table->syscall_exit_dispatch = kzalloc(sizeof(struct hlist_head) * sc_exit_table.len, GFP_KERNEL);
0bb716a8 852 if (!syscall_table->syscall_exit_dispatch)
8a8ac9a8 853 return -ENOMEM;
8a8ac9a8
FD
854 }
855
856#ifdef CONFIG_COMPAT
0bb716a8 857 if (!syscall_table->compat_syscall_dispatch) {
d26015f6 858 /* create syscall table mapping compat syscall to events */
0bb716a8
MD
859 syscall_table->compat_syscall_dispatch = kzalloc(sizeof(struct hlist_head) * compat_sc_table.len, GFP_KERNEL);
860 if (!syscall_table->compat_syscall_dispatch)
8a8ac9a8 861 return -ENOMEM;
8a8ac9a8
FD
862 }
863
0bb716a8 864 if (!syscall_table->compat_syscall_exit_dispatch) {
d26015f6
MD
865 /* create syscall table mapping compat syscall to events */
866 syscall_table->compat_syscall_exit_dispatch = kzalloc(sizeof(struct hlist_head) * compat_sc_exit_table.len, GFP_KERNEL);
0bb716a8 867 if (!syscall_table->compat_syscall_exit_dispatch)
8a8ac9a8 868 return -ENOMEM;
8a8ac9a8
FD
869 }
870#endif
0bb716a8
MD
871 if (!syscall_table->sc_filter) {
872 syscall_table->sc_filter = kzalloc(sizeof(struct lttng_syscall_filter),
8a8ac9a8 873 GFP_KERNEL);
0bb716a8 874 if (!syscall_table->sc_filter)
8a8ac9a8
FD
875 return -ENOMEM;
876 }
877
0bb716a8 878 if (!syscall_table->sys_enter_registered) {
a6837bed 879 ret = lttng_tracepoint_probe_register("sys_enter",
0bb716a8 880 (void *) syscall_entry_event_probe, syscall_table);
8a8ac9a8
FD
881 if (ret)
882 return ret;
0bb716a8 883 syscall_table->sys_enter_registered = 1;
8a8ac9a8 884 }
0bb716a8 885 if (!syscall_table->sys_exit_registered) {
a6837bed 886 ret = lttng_tracepoint_probe_register("sys_exit",
0bb716a8 887 (void *) syscall_exit_event_probe, syscall_table);
8a8ac9a8 888 if (ret) {
a6837bed 889 WARN_ON_ONCE(lttng_tracepoint_probe_unregister("sys_enter",
0bb716a8 890 (void *) syscall_entry_event_probe, syscall_table));
8a8ac9a8
FD
891 return ret;
892 }
0bb716a8 893 syscall_table->sys_exit_registered = 1;
8a8ac9a8 894 }
0fab709d 895
86e12a51
MD
896 lttng_syscall_event_enabler_create_matching_events(syscall_event_enabler);
897
fad51c94 898 return 0;
8a8ac9a8
FD
899}
900
6053e75e 901int lttng_syscalls_unregister_syscall_table(struct lttng_kernel_syscall_table *syscall_table)
259b6cb3
MD
902{
903 int ret;
904
0bb716a8 905 if (!syscall_table->syscall_dispatch)
259b6cb3 906 return 0;
0bb716a8 907 if (syscall_table->sys_enter_registered) {
a6837bed 908 ret = lttng_tracepoint_probe_unregister("sys_enter",
0bb716a8 909 (void *) syscall_entry_event_probe, syscall_table);
80f87dd2
MD
910 if (ret)
911 return ret;
0bb716a8 912 syscall_table->sys_enter_registered = 0;
80f87dd2 913 }
0bb716a8 914 if (syscall_table->sys_exit_registered) {
a6837bed 915 ret = lttng_tracepoint_probe_unregister("sys_exit",
0bb716a8 916 (void *) syscall_exit_event_probe, syscall_table);
80f87dd2
MD
917 if (ret)
918 return ret;
0bb716a8 919 syscall_table->sys_exit_registered = 0;
80f87dd2 920 }
badfe9f5
MD
921 return 0;
922}
923
6053e75e 924int lttng_syscalls_destroy_syscall_table(struct lttng_kernel_syscall_table *syscall_table)
badfe9f5 925{
0bb716a8
MD
926 kfree(syscall_table->syscall_dispatch);
927 kfree(syscall_table->syscall_exit_dispatch);
49c50022 928#ifdef CONFIG_COMPAT
0bb716a8
MD
929 kfree(syscall_table->compat_syscall_dispatch);
930 kfree(syscall_table->compat_syscall_exit_dispatch);
49c50022 931#endif
0bb716a8 932 kfree(syscall_table->sc_filter);
80f87dd2
MD
933 return 0;
934}
935
12e579db
MD
936static
937uint32_t get_sc_tables_len(void)
938{
ebcc64cd 939 return sc_table.len + compat_sc_table.len;
12e579db
MD
940}
941
badfe9f5 942static
ade8a729
FD
943const char *get_syscall_name(const char *desc_name,
944 enum lttng_syscall_abi abi,
945 enum lttng_syscall_entryexit entryexit)
80f87dd2 946{
badfe9f5 947 size_t prefix_len = 0;
80f87dd2 948
80f87dd2 949
ade8a729 950 switch (entryexit) {
badfe9f5 951 case LTTNG_SYSCALL_ENTRY:
ade8a729 952 switch (abi) {
badfe9f5
MD
953 case LTTNG_SYSCALL_ABI_NATIVE:
954 prefix_len = strlen(SYSCALL_ENTRY_STR);
955 break;
956 case LTTNG_SYSCALL_ABI_COMPAT:
957 prefix_len = strlen(COMPAT_SYSCALL_ENTRY_STR);
958 break;
80f87dd2 959 }
badfe9f5
MD
960 break;
961 case LTTNG_SYSCALL_EXIT:
ade8a729 962 switch (abi) {
badfe9f5
MD
963 case LTTNG_SYSCALL_ABI_NATIVE:
964 prefix_len = strlen(SYSCALL_EXIT_STR);
965 break;
966 case LTTNG_SYSCALL_ABI_COMPAT:
967 prefix_len = strlen(COMPAT_SYSCALL_EXIT_STR);
968 break;
80f87dd2 969 }
badfe9f5 970 break;
80f87dd2 971 }
badfe9f5 972 WARN_ON_ONCE(prefix_len == 0);
ade8a729 973 return desc_name + prefix_len;
badfe9f5
MD
974}
975
ade8a729
FD
976static
977int lttng_syscall_filter_enable(
978 struct lttng_syscall_filter *filter,
979 const char *desc_name, enum lttng_syscall_abi abi,
99903379
MD
980 enum lttng_syscall_entryexit entryexit,
981 unsigned int syscall_id)
badfe9f5 982{
badfe9f5
MD
983 const char *syscall_name;
984 unsigned long *bitmap;
7f52f0d4 985 u32 *refcount_map;
badfe9f5 986
ade8a729 987 syscall_name = get_syscall_name(desc_name, abi, entryexit);
badfe9f5 988
ade8a729 989 switch (entryexit) {
badfe9f5 990 case LTTNG_SYSCALL_ENTRY:
ade8a729 991 switch (abi) {
badfe9f5
MD
992 case LTTNG_SYSCALL_ABI_NATIVE:
993 bitmap = filter->sc_entry;
7f52f0d4 994 refcount_map = filter->sc_entry_refcount_map;
badfe9f5
MD
995 break;
996 case LTTNG_SYSCALL_ABI_COMPAT:
997 bitmap = filter->sc_compat_entry;
7f52f0d4 998 refcount_map = filter->sc_compat_entry_refcount_map;
badfe9f5 999 break;
6d9694d8
MD
1000 default:
1001 return -EINVAL;
80f87dd2 1002 }
badfe9f5
MD
1003 break;
1004 case LTTNG_SYSCALL_EXIT:
ade8a729 1005 switch (abi) {
badfe9f5
MD
1006 case LTTNG_SYSCALL_ABI_NATIVE:
1007 bitmap = filter->sc_exit;
7f52f0d4 1008 refcount_map = filter->sc_exit_refcount_map;
badfe9f5
MD
1009 break;
1010 case LTTNG_SYSCALL_ABI_COMPAT:
1011 bitmap = filter->sc_compat_exit;
7f52f0d4 1012 refcount_map = filter->sc_compat_exit_refcount_map;
badfe9f5 1013 break;
6d9694d8
MD
1014 default:
1015 return -EINVAL;
80f87dd2 1016 }
badfe9f5
MD
1017 break;
1018 default:
1019 return -EINVAL;
80f87dd2 1020 }
99903379 1021 if (refcount_map[syscall_id] == U32_MAX)
7f52f0d4 1022 return -EOVERFLOW;
99903379
MD
1023 if (refcount_map[syscall_id]++ == 0)
1024 bitmap_set(bitmap, syscall_id, 1);
80f87dd2 1025 return 0;
80f87dd2
MD
1026}
1027
9b2f1c54 1028int lttng_syscall_filter_enable_event(struct lttng_kernel_event_common *event)
8a8ac9a8 1029{
9b2f1c54 1030 struct lttng_kernel_syscall_table *syscall_table = get_syscall_table_from_event(event);
9cd106a6
MD
1031 unsigned int syscall_id = event->priv->u.syscall.syscall_id;
1032 struct hlist_head *dispatch_list;
ca62543e 1033 int ret = 0;
8a8ac9a8 1034
9b2f1c54 1035 WARN_ON_ONCE(event->priv->instrumentation != LTTNG_KERNEL_ABI_SYSCALL);
8a8ac9a8 1036
99903379
MD
1037 /* Unknown syscall */
1038 if (syscall_id == -1U) {
1039 switch (event->priv->u.syscall.entryexit) {
1040 case LTTNG_SYSCALL_ENTRY:
1041 switch (event->priv->u.syscall.abi) {
1042 case LTTNG_SYSCALL_ABI_NATIVE:
1043 dispatch_list = &syscall_table->unknown_syscall_dispatch;
1044 break;
1045 case LTTNG_SYSCALL_ABI_COMPAT:
1046 dispatch_list = &syscall_table->compat_unknown_syscall_dispatch;
1047 break;
1048 default:
1049 ret = -EINVAL;
1050 goto end;
1051 }
9cd106a6 1052 break;
99903379
MD
1053 case LTTNG_SYSCALL_EXIT:
1054 switch (event->priv->u.syscall.abi) {
1055 case LTTNG_SYSCALL_ABI_NATIVE:
1056 dispatch_list = &syscall_table->unknown_syscall_exit_dispatch;
1057 break;
1058 case LTTNG_SYSCALL_ABI_COMPAT:
1059 dispatch_list = &syscall_table->compat_unknown_syscall_exit_dispatch;
1060 break;
1061 default:
1062 ret = -EINVAL;
1063 goto end;
1064 }
9cd106a6
MD
1065 break;
1066 default:
1067 ret = -EINVAL;
1068 goto end;
1069 }
99903379
MD
1070 } else {
1071 ret = lttng_syscall_filter_enable(syscall_table->sc_filter,
1072 event->priv->desc->event_name, event->priv->u.syscall.abi,
1073 event->priv->u.syscall.entryexit, syscall_id);
1074 if (ret)
1075 return ret;
1076
1077 switch (event->priv->u.syscall.entryexit) {
1078 case LTTNG_SYSCALL_ENTRY:
1079 switch (event->priv->u.syscall.abi) {
1080 case LTTNG_SYSCALL_ABI_NATIVE:
1081 dispatch_list = &syscall_table->syscall_dispatch[syscall_id];
1082 break;
1083 case LTTNG_SYSCALL_ABI_COMPAT:
1084 dispatch_list = &syscall_table->compat_syscall_dispatch[syscall_id];
1085 break;
1086 default:
1087 ret = -EINVAL;
1088 goto end;
1089 }
8a8ac9a8 1090 break;
99903379
MD
1091 case LTTNG_SYSCALL_EXIT:
1092 switch (event->priv->u.syscall.abi) {
1093 case LTTNG_SYSCALL_ABI_NATIVE:
1094 dispatch_list = &syscall_table->syscall_exit_dispatch[syscall_id];
1095 break;
1096 case LTTNG_SYSCALL_ABI_COMPAT:
1097 dispatch_list = &syscall_table->compat_syscall_exit_dispatch[syscall_id];
1098 break;
1099 default:
1100 ret = -EINVAL;
1101 goto end;
1102 }
8a8ac9a8 1103 break;
6866b1c7
MJ
1104 default:
1105 ret = -EINVAL;
1106 goto end;
8a8ac9a8 1107 }
8a8ac9a8 1108 }
9cd106a6
MD
1109
1110 hlist_add_head_rcu(&event->priv->u.syscall.node, dispatch_list);
8a8ac9a8 1111end:
9b2f1c54 1112 return ret;
ade8a729
FD
1113}
1114
1115static
f2db8be3 1116int lttng_syscall_filter_disable(struct lttng_syscall_filter *filter,
ade8a729 1117 const char *desc_name, enum lttng_syscall_abi abi,
99903379
MD
1118 enum lttng_syscall_entryexit entryexit,
1119 unsigned int syscall_id)
ade8a729 1120{
badfe9f5
MD
1121 const char *syscall_name;
1122 unsigned long *bitmap;
7f52f0d4 1123 u32 *refcount_map;
80f87dd2 1124
ade8a729 1125 syscall_name = get_syscall_name(desc_name, abi, entryexit);
80f87dd2 1126
ade8a729 1127 switch (entryexit) {
badfe9f5 1128 case LTTNG_SYSCALL_ENTRY:
ade8a729 1129 switch (abi) {
badfe9f5
MD
1130 case LTTNG_SYSCALL_ABI_NATIVE:
1131 bitmap = filter->sc_entry;
7f52f0d4 1132 refcount_map = filter->sc_entry_refcount_map;
badfe9f5
MD
1133 break;
1134 case LTTNG_SYSCALL_ABI_COMPAT:
1135 bitmap = filter->sc_compat_entry;
7f52f0d4 1136 refcount_map = filter->sc_compat_entry_refcount_map;
badfe9f5 1137 break;
6d9694d8
MD
1138 default:
1139 return -EINVAL;
80f87dd2 1140 }
badfe9f5
MD
1141 break;
1142 case LTTNG_SYSCALL_EXIT:
ade8a729 1143 switch (abi) {
badfe9f5
MD
1144 case LTTNG_SYSCALL_ABI_NATIVE:
1145 bitmap = filter->sc_exit;
7f52f0d4 1146 refcount_map = filter->sc_exit_refcount_map;
badfe9f5
MD
1147 break;
1148 case LTTNG_SYSCALL_ABI_COMPAT:
1149 bitmap = filter->sc_compat_exit;
7f52f0d4 1150 refcount_map = filter->sc_compat_exit_refcount_map;
badfe9f5 1151 break;
6d9694d8
MD
1152 default:
1153 return -EINVAL;
80f87dd2 1154 }
badfe9f5
MD
1155 break;
1156 default:
1157 return -EINVAL;
80f87dd2 1158 }
99903379 1159 if (refcount_map[syscall_id] == 0)
7f52f0d4 1160 return -ENOENT;
99903379
MD
1161 if (--refcount_map[syscall_id] == 0)
1162 bitmap_clear(bitmap, syscall_id, 1);
badfe9f5 1163 return 0;
259b6cb3 1164}
2d2464bd 1165
9b2f1c54 1166int lttng_syscall_filter_disable_event(struct lttng_kernel_event_common *event)
8a8ac9a8 1167{
9b2f1c54 1168 struct lttng_kernel_syscall_table *syscall_table = get_syscall_table_from_event(event);
7f52f0d4 1169 unsigned int syscall_id = event->priv->u.syscall.syscall_id;
8a8ac9a8
FD
1170 int ret;
1171
99903379
MD
1172 /* Except for unknown syscall */
1173 if (syscall_id != -1U) {
1174 ret = lttng_syscall_filter_disable(syscall_table->sc_filter,
1175 event->priv->desc->event_name, event->priv->u.syscall.abi,
1176 event->priv->u.syscall.entryexit, syscall_id);
1177 if (ret)
1178 return ret;
1179 }
9cd106a6 1180 hlist_del_rcu(&event->priv->u.syscall.node);
8a8ac9a8
FD
1181 return 0;
1182}
1183
9cb5be7e
MD
1184void lttng_syscall_table_set_wildcard_all(struct lttng_event_enabler_common *event_enabler)
1185{
1186 struct lttng_kernel_syscall_table *syscall_table = get_syscall_table_from_enabler(event_enabler);
1187 enum lttng_kernel_abi_syscall_entryexit entryexit;
1188 int enabled = event_enabler->enabled;
1189
552f7c79 1190 if (!lttng_syscall_event_enabler_is_wildcard_all(event_enabler))
9cb5be7e 1191 return;
9cb5be7e
MD
1192 entryexit = event_enabler->event_param.u.syscall.entryexit;
1193 if (entryexit == LTTNG_KERNEL_ABI_SYSCALL_ENTRY || entryexit == LTTNG_KERNEL_ABI_SYSCALL_ENTRYEXIT)
1194 WRITE_ONCE(syscall_table->syscall_all_entry, enabled);
1195
1196 if (entryexit == LTTNG_KERNEL_ABI_SYSCALL_EXIT || entryexit == LTTNG_KERNEL_ABI_SYSCALL_ENTRYEXIT)
1197 WRITE_ONCE(syscall_table->syscall_all_exit, enabled);
1198}
1199
2d2464bd
MD
1200static
1201const struct trace_syscall_entry *syscall_list_get_entry(loff_t *pos)
1202{
1203 const struct trace_syscall_entry *entry;
1204 int iter = 0;
1205
ebcc64cd
FD
1206 for (entry = sc_table.table;
1207 entry < sc_table.table + sc_table.len;
2d2464bd
MD
1208 entry++) {
1209 if (iter++ >= *pos)
1210 return entry;
1211 }
ebcc64cd
FD
1212 for (entry = compat_sc_table.table;
1213 entry < compat_sc_table.table + compat_sc_table.len;
2d2464bd
MD
1214 entry++) {
1215 if (iter++ >= *pos)
1216 return entry;
1217 }
1218 /* End of list */
1219 return NULL;
1220}
1221
1222static
1223void *syscall_list_start(struct seq_file *m, loff_t *pos)
1224{
1225 return (void *) syscall_list_get_entry(pos);
1226}
1227
1228static
1229void *syscall_list_next(struct seq_file *m, void *p, loff_t *ppos)
1230{
1231 (*ppos)++;
1232 return (void *) syscall_list_get_entry(ppos);
1233}
1234
1235static
1236void syscall_list_stop(struct seq_file *m, void *p)
1237{
1238}
1239
12e579db
MD
1240static
1241int get_sc_table(const struct trace_syscall_entry *entry,
1242 const struct trace_syscall_entry **table,
1243 unsigned int *bitness)
1244{
ebcc64cd 1245 if (entry >= sc_table.table && entry < sc_table.table + sc_table.len) {
12e579db
MD
1246 if (bitness)
1247 *bitness = BITS_PER_LONG;
1248 if (table)
ebcc64cd 1249 *table = sc_table.table;
12e579db
MD
1250 return 0;
1251 }
ebcc64cd
FD
1252 if (!(entry >= compat_sc_table.table
1253 && entry < compat_sc_table.table + compat_sc_table.len)) {
12e579db
MD
1254 return -EINVAL;
1255 }
1256 if (bitness)
1257 *bitness = 32;
1258 if (table)
ebcc64cd 1259 *table = compat_sc_table.table;
12e579db
MD
1260 return 0;
1261}
1262
2d2464bd
MD
1263static
1264int syscall_list_show(struct seq_file *m, void *p)
1265{
1266 const struct trace_syscall_entry *table, *entry = p;
1267 unsigned int bitness;
d4291869 1268 unsigned long index;
12e579db 1269 int ret;
d4291869 1270 const char *name;
2d2464bd 1271
12e579db
MD
1272 ret = get_sc_table(entry, &table, &bitness);
1273 if (ret)
1274 return ret;
f4855b46
MD
1275 if (!entry->desc)
1276 return 0;
ebcc64cd 1277 if (table == sc_table.table) {
d4291869 1278 index = entry - table;
437d5aa5 1279 name = &entry->desc->event_name[strlen(SYSCALL_ENTRY_STR)];
d4291869 1280 } else {
ebcc64cd 1281 index = (entry - table) + sc_table.len;
437d5aa5 1282 name = &entry->desc->event_name[strlen(COMPAT_SYSCALL_ENTRY_STR)];
d4291869 1283 }
12e579db 1284 seq_printf(m, "syscall { index = %lu; name = %s; bitness = %u; };\n",
d4291869 1285 index, name, bitness);
2d2464bd
MD
1286 return 0;
1287}
1288
1289static
1290const struct seq_operations lttng_syscall_list_seq_ops = {
1291 .start = syscall_list_start,
1292 .next = syscall_list_next,
1293 .stop = syscall_list_stop,
1294 .show = syscall_list_show,
1295};
1296
1297static
1298int lttng_syscall_list_open(struct inode *inode, struct file *file)
1299{
1300 return seq_open(file, &lttng_syscall_list_seq_ops);
1301}
1302
1303const struct file_operations lttng_syscall_list_fops = {
1304 .owner = THIS_MODULE,
1305 .open = lttng_syscall_list_open,
1306 .read = seq_read,
1307 .llseek = seq_lseek,
1308 .release = seq_release,
1309};
12e579db 1310
badfe9f5
MD
1311/*
1312 * A syscall is enabled if it is traced for either entry or exit.
1313 */
c970b655 1314long lttng_syscall_table_get_active_mask(struct lttng_kernel_syscall_table *syscall_table,
606828e4 1315 struct lttng_kernel_abi_syscall_mask __user *usyscall_mask)
12e579db
MD
1316{
1317 uint32_t len, sc_tables_len, bitmask_len;
1318 int ret = 0, bit;
1319 char *tmp_mask;
1320 struct lttng_syscall_filter *filter;
1321
1322 ret = get_user(len, &usyscall_mask->len);
1323 if (ret)
1324 return ret;
1325 sc_tables_len = get_sc_tables_len();
1326 bitmask_len = ALIGN(sc_tables_len, 8) >> 3;
1327 if (len < sc_tables_len) {
1328 return put_user(sc_tables_len, &usyscall_mask->len);
1329 }
1330 /* Array is large enough, we can copy array to user-space. */
1331 tmp_mask = kzalloc(bitmask_len, GFP_KERNEL);
1332 if (!tmp_mask)
1333 return -ENOMEM;
0bb716a8 1334 filter = syscall_table->sc_filter;
12e579db 1335
ebcc64cd 1336 for (bit = 0; bit < sc_table.len; bit++) {
e2129868 1337 char state;
2f25059d 1338
0bb716a8
MD
1339 if (syscall_table->syscall_dispatch) {
1340 if (!(READ_ONCE(syscall_table->syscall_all_entry)
1341 || READ_ONCE(syscall_table->syscall_all_exit)) && filter)
badfe9f5
MD
1342 state = test_bit(bit, filter->sc_entry)
1343 || test_bit(bit, filter->sc_exit);
2f25059d
MD
1344 else
1345 state = 1;
1346 } else {
1347 state = 0;
1348 }
1349 bt_bitfield_write_be(tmp_mask, char, bit, 1, state);
12e579db
MD
1350 }
1351 for (; bit < sc_tables_len; bit++) {
e2129868 1352 char state;
2f25059d 1353
0bb716a8
MD
1354 if (syscall_table->compat_syscall_dispatch) {
1355 if (!(READ_ONCE(syscall_table->syscall_all_entry)
1356 || READ_ONCE(syscall_table->syscall_all_exit)) && filter)
ebcc64cd 1357 state = test_bit(bit - sc_table.len,
badfe9f5 1358 filter->sc_compat_entry)
ebcc64cd 1359 || test_bit(bit - sc_table.len,
badfe9f5 1360 filter->sc_compat_exit);
2f25059d
MD
1361 else
1362 state = 1;
1363 } else {
1364 state = 0;
1365 }
1366 bt_bitfield_write_be(tmp_mask, char, bit, 1, state);
12e579db
MD
1367 }
1368 if (copy_to_user(usyscall_mask->mask, tmp_mask, bitmask_len))
1369 ret = -EFAULT;
1370 kfree(tmp_mask);
1371 return ret;
1372}
This page took 0.148319 seconds and 5 git commands to generate.