Clean-up: fix stale #endif comments
[lttng-modules.git] / instrumentation / syscalls / headers / syscalls_pointers_override.h
1 #ifndef CREATE_SYSCALL_TABLE
2
3 #define OVERRIDE_32_execve
4 #define OVERRIDE_64_execve
5 SC_LTTNG_TRACEPOINT_EVENT(execve,
6 TP_PROTO(sc_exit(long ret,) const char *filename, char *const *argv, char *const *envp),
7 TP_ARGS(sc_exit(ret,) filename, argv, envp),
8 TP_FIELDS(sc_exit(ctf_integer(long, ret, ret))
9 sc_in(ctf_user_string(filename, filename))
10 sc_in(ctf_integer_hex(char *const *, argv, argv))
11 sc_in(ctf_integer_hex(char *const *, envp, envp))
12 )
13 )
14
15 #define OVERRIDE_32_clone
16 #define OVERRIDE_64_clone
17 SC_LTTNG_TRACEPOINT_EVENT(clone,
18 TP_PROTO(sc_exit(long ret,) unsigned long clone_flags, unsigned long newsp,
19 void __user *parent_tid,
20 void __user *child_tid),
21 TP_ARGS(sc_exit(ret,) clone_flags, newsp, parent_tid, child_tid),
22 TP_FIELDS(
23 sc_exit(ctf_integer(long, ret, ret))
24 sc_in(ctf_integer_hex(unsigned long, clone_flags, clone_flags))
25 sc_in(ctf_integer_hex(unsigned long, newsp, newsp))
26 sc_in(ctf_integer_hex(void *, parent_tid, parent_tid))
27 sc_in(ctf_integer_hex(void *, child_tid, child_tid))
28 )
29 )
30
31 /* present in 32, missing in 64 due to old kernel headers */
32 #define OVERRIDE_32_getcpu
33 #define OVERRIDE_64_getcpu
34 SC_LTTNG_TRACEPOINT_EVENT(getcpu,
35 TP_PROTO(sc_exit(long ret,) unsigned __user *cpup, unsigned __user *nodep, void *tcache),
36 TP_ARGS(sc_exit(ret,) cpup, nodep, tcache),
37 TP_FIELDS(
38 sc_exit(ctf_integer(long, ret, ret))
39 sc_out(ctf_integer_hex(unsigned *, cpup, cpup))
40 sc_out(ctf_integer_hex(unsigned *, nodep, nodep))
41 sc_inout(ctf_integer_hex(void *, tcache, tcache))
42 )
43 )
44
45 #define OVERRIDE_32_pipe2
46 #define OVERRIDE_64_pipe2
47 SC_LTTNG_TRACEPOINT_EVENT(pipe2,
48 TP_PROTO(sc_exit(long ret,) int * fildes, int flags),
49 TP_ARGS(sc_exit(ret,) fildes, flags),
50 TP_FIELDS(sc_exit(ctf_integer(long, ret, ret))
51 sc_out(ctf_user_array(int, fildes, fildes, 2))
52 sc_in(ctf_integer(int, flags, flags))
53 )
54 )
55
56 #define LTTNG_SYSCALL_SELECT_locvar \
57 unsigned long *fds_in, *fds_out, *fds_ex; \
58 unsigned long nr_bytes, nr_ulong; \
59 uint8_t overflow;
60
61 #define LTTNG_SYSCALL_SELECT_code_pre \
62 sc_inout( \
63 { \
64 int err; \
65 unsigned int n_in_bytes; \
66 \
67 tp_locvar->fds_in = NULL; \
68 tp_locvar->fds_out = NULL; \
69 tp_locvar->fds_ex = NULL; \
70 tp_locvar->overflow = 0; \
71 \
72 sc_out( \
73 if (ret <= 0) \
74 goto error; \
75 ) \
76 \
77 if (n <= 0) \
78 goto error; \
79 \
80 /* On error or bogus input, don't copy anything. */ \
81 if (n >__FD_SETSIZE) \
82 goto error; \
83 \
84 n_in_bytes = DIV_ROUND_UP((unsigned int) n, BITS_PER_BYTE); \
85 \
86 /* \
87 * Limit atomic memory allocation to one page, since n \
88 * is limited to 1024 and the smallest page size on Linux \
89 * is 4k, this should not happen, don't try to make it work. \
90 */ \
91 if (n_in_bytes > PAGE_SIZE) { \
92 WARN_ON_ONCE(1); \
93 /* Inform the user that we did not output everything. */ \
94 tp_locvar->overflow = 1; \
95 goto error; \
96 } else { \
97 tp_locvar->nr_bytes = n_in_bytes; \
98 tp_locvar->nr_ulong = DIV_ROUND_UP(n_in_bytes, \
99 sizeof(unsigned long)); \
100 } \
101 \
102 if (inp) { \
103 tp_locvar->fds_in = kmalloc( \
104 tp_locvar->nr_ulong * sizeof(unsigned long), \
105 GFP_ATOMIC | GFP_NOWAIT); \
106 if (!tp_locvar->fds_in) \
107 goto error; \
108 \
109 err = lib_ring_buffer_copy_from_user_check_nofault( \
110 tp_locvar->fds_in, inp, \
111 tp_locvar->nr_ulong * sizeof(unsigned long)); \
112 if (err != 0) \
113 goto error; \
114 } \
115 if (outp) { \
116 tp_locvar->fds_out = kmalloc( \
117 tp_locvar->nr_ulong * sizeof(unsigned long), \
118 GFP_ATOMIC | GFP_NOWAIT); \
119 if (!tp_locvar->fds_out) \
120 goto error; \
121 \
122 err = lib_ring_buffer_copy_from_user_check_nofault( \
123 tp_locvar->fds_out, outp, \
124 tp_locvar->nr_ulong * sizeof(unsigned long)); \
125 if (err != 0) \
126 goto error; \
127 } \
128 if (exp) { \
129 tp_locvar->fds_ex = kmalloc( \
130 tp_locvar->nr_ulong * sizeof(unsigned long), \
131 GFP_ATOMIC | GFP_NOWAIT); \
132 if (!tp_locvar->fds_ex) \
133 goto error; \
134 \
135 err = lib_ring_buffer_copy_from_user_check_nofault( \
136 tp_locvar->fds_ex, exp, \
137 tp_locvar->nr_ulong * sizeof(unsigned long)); \
138 if (err != 0) \
139 goto error; \
140 } \
141 goto end; \
142 \
143 error: \
144 tp_locvar->nr_bytes = 0; \
145 tp_locvar->nr_ulong = 0; \
146 end: ; /* Label at end of compound statement. */ \
147 } \
148 )
149
150 #define LTTNG_SYSCALL_SELECT_fds_field_LE(name, input) \
151 ctf_custom_field( \
152 ctf_custom_type( \
153 .atype = atype_sequence, \
154 .u.sequence.length_type = __type_integer( \
155 uint8_t, 0, 0, 0, __BYTE_ORDER, 10, none), \
156 .u.sequence.elem_type = __type_integer(uint8_t, 0, 0, 0, \
157 __BYTE_ORDER, 16, none), \
158 ), \
159 name, \
160 ctf_custom_code( \
161 unsigned int src; \
162 unsigned int nr_bytes_out = 0; \
163 \
164 if (input) { \
165 ctf_integer_type(uint8_t, tp_locvar->nr_bytes) \
166 ctf_align(uint8_t) \
167 } else { \
168 ctf_integer_type(uint8_t, 0) \
169 ctf_align(uint8_t) \
170 goto skip_##name; \
171 } \
172 \
173 for (src = 0; src < tp_locvar->nr_ulong; src++) { \
174 int dst; \
175 for (dst = 0; dst < sizeof(long); dst++) { \
176 if (nr_bytes_out++ >= tp_locvar->nr_bytes) { \
177 goto skip_##name; \
178 } \
179 ctf_user_integer_type(uint8_t, \
180 ((uint8_t __user *) (input->fds_bits + src))[dst]); \
181 } \
182 } \
183 skip_##name: ; \
184 ) \
185 )
186
187 #define LTTNG_SYSCALL_SELECT_fds_field_BE(name, input) \
188 ctf_custom_field( \
189 ctf_custom_type( \
190 .atype = atype_sequence, \
191 .u.sequence.length_type = __type_integer( \
192 uint8_t, 0, 0, 0, __BYTE_ORDER, 10, none), \
193 .u.sequence.elem_type = __type_integer(uint8_t, 0, 0, 0, \
194 __BYTE_ORDER, 16, none), \
195 ), \
196 name, \
197 ctf_custom_code( \
198 unsigned int src, nr_bytes_out = 0; \
199 \
200 if (input) { \
201 ctf_integer_type(uint8_t, tp_locvar->nr_bytes) \
202 ctf_align(uint8_t) \
203 } else { \
204 ctf_integer_type(uint8_t, 0) \
205 ctf_align(uint8_t) \
206 goto skip_##name; \
207 } \
208 \
209 for (src = 0; src < tp_locvar->nr_ulong; src++) { \
210 int dst; \
211 for (dst = sizeof(long); dst >= 0; dst--) { \
212 if (nr_bytes_out++ >= tp_locvar->nr_bytes) { \
213 goto skip_##name; \
214 } \
215 ctf_user_integer_type(uint8_t, \
216 ((uint8_t __user *) (input->fds_bits + src))[dst]); \
217 } \
218 } \
219 skip_##name: ; \
220 ) \
221 )
222
223 #define LTTNG_SYSCALL_SELECT_code_post \
224 kfree(tp_locvar->fds_in); \
225 kfree(tp_locvar->fds_out); \
226 kfree(tp_locvar->fds_ex);
227
228 #if defined(CONFIG_X86_32) || defined(CONFIG_X86_64) || defined(CONFIG_ARM)
229 #define OVERRIDE_32_select
230 #define OVERRIDE_64_select
231 SC_LTTNG_TRACEPOINT_EVENT_CODE(select,
232 TP_PROTO(sc_exit(long ret,) int n, fd_set __user *inp, fd_set __user *outp,
233 fd_set __user *exp, struct timeval *tvp),
234 TP_ARGS(sc_exit(ret,) n, inp, outp, exp, tvp),
235 TP_locvar(
236 LTTNG_SYSCALL_SELECT_locvar
237 ),
238 TP_code_pre(
239 LTTNG_SYSCALL_SELECT_code_pre
240 ),
241 TP_FIELDS(
242 sc_exit(ctf_integer(long, ret, ret))
243 sc_in(ctf_integer(int, n, n))
244 sc_inout(ctf_integer(uint8_t, overflow, tp_locvar->overflow))
245 sc_inout(ctf_integer(struct timeval *, tvp, tvp))
246
247 sc_inout(
248 #if (__BYTE_ORDER == __LITTLE_ENDIAN)
249 LTTNG_SYSCALL_SELECT_fds_field_LE(readfds, inp)
250 LTTNG_SYSCALL_SELECT_fds_field_LE(writefds, outp)
251 LTTNG_SYSCALL_SELECT_fds_field_LE(exceptfds, exp)
252 #else
253 LTTNG_SYSCALL_SELECT_fds_field_BE(readfds, inp)
254 LTTNG_SYSCALL_SELECT_fds_field_BE(writefds, outp)
255 LTTNG_SYSCALL_SELECT_fds_field_BE(exceptfds, exp)
256 #endif
257 )
258 ),
259 TP_code_post(
260 LTTNG_SYSCALL_SELECT_code_post
261 )
262 )
263 #endif /* defined(CONFIG_X86_32) || defined(CONFIG_X86_64) || defined(CONFIG_ARM) */
264
265 #if defined(CONFIG_X86_32) || defined(CONFIG_X86_64) || defined(CONFIG_ARM64) || defined(CONFIG_ARM)
266 #define OVERRIDE_32_pselect6
267 #define OVERRIDE_64_pselect6
268 SC_LTTNG_TRACEPOINT_EVENT_CODE(pselect6,
269 TP_PROTO(sc_exit(long ret,) int n, fd_set __user * inp, fd_set __user * outp,
270 fd_set __user * exp, struct timeval __user * tvp, void __user * sig),
271 TP_ARGS(sc_exit(ret,) n, inp, outp, exp, tvp, sig),
272 TP_locvar(
273 LTTNG_SYSCALL_SELECT_locvar
274 ),
275 TP_code_pre(
276 LTTNG_SYSCALL_SELECT_code_pre
277 ),
278 TP_FIELDS(
279 sc_exit(ctf_integer(long, ret, ret))
280 sc_in(ctf_integer(int, n, n))
281 sc_inout(ctf_integer(uint8_t, overflow, tp_locvar->overflow))
282 sc_inout(ctf_integer(struct timeval *, tvp, tvp))
283 sc_in(ctf_integer_hex(void *, sig, sig))
284
285 sc_inout(
286 #if (__BYTE_ORDER == __LITTLE_ENDIAN)
287 LTTNG_SYSCALL_SELECT_fds_field_LE(readfds, inp)
288 LTTNG_SYSCALL_SELECT_fds_field_LE(writefds, outp)
289 LTTNG_SYSCALL_SELECT_fds_field_LE(exceptfds, exp)
290 #else
291 LTTNG_SYSCALL_SELECT_fds_field_BE(readfds, inp)
292 LTTNG_SYSCALL_SELECT_fds_field_BE(writefds, outp)
293 LTTNG_SYSCALL_SELECT_fds_field_BE(exceptfds, exp)
294 #endif
295 )
296 ),
297 TP_code_post(
298 LTTNG_SYSCALL_SELECT_code_post
299 )
300 )
301 #endif /* defined(CONFIG_X86_32) || defined(CONFIG_X86_64) || defined(CONFIG_ARM64) || defined(CONFIG_ARM) */
302
303 #ifndef ONCE_LTTNG_TRACE_POLL_H
304 #define ONCE_LTTNG_TRACE_POLL_H
305
306 #define LTTNG_POLL_NRFLAGS (POLLNVAL + 1)
307 #define POLL_FLAGS_PADDING_SIZE (sizeof(uint8_t) * BITS_PER_BYTE) - \
308 ilog2(LTTNG_POLL_NRFLAGS - 1)
309
310 /*
311 * Only extract the values specified by iBCS2 for now.
312 */
313 static struct lttng_event_field lttng_pollfd_flag_fields[] = {
314 [ilog2(POLLIN)] = {
315 .name = "POLLIN",
316 .type = __type_integer(int, 1, 1, 0, __LITTLE_ENDIAN, 10, none),
317 },
318 [ilog2(POLLPRI)] = {
319 .name = "POLLPRI",
320 .type = __type_integer(int, 1, 1, 0, __LITTLE_ENDIAN, 10, none),
321 },
322 [ilog2(POLLOUT)] = {
323 .name = "POLLOUT",
324 .type = __type_integer(int, 1, 1, 0, __LITTLE_ENDIAN, 10, none),
325 },
326 [ilog2(POLLERR)] = {
327 .name = "POLLERR",
328 .type = __type_integer(int, 1, 1, 0, __LITTLE_ENDIAN, 10, none),
329 },
330 [ilog2(POLLHUP)] = {
331 .name = "POLLHUP",
332 .type = __type_integer(int, 1, 1, 0, __LITTLE_ENDIAN, 10, none),
333 },
334 [ilog2(POLLNVAL)] = {
335 .name = "POLLNVAL",
336 .type = __type_integer(int, 1, 1, 0, __LITTLE_ENDIAN, 10, none),
337 },
338 [ilog2(LTTNG_POLL_NRFLAGS)] = {
339 .name = "padding",
340 .type = __type_integer(int, POLL_FLAGS_PADDING_SIZE, 1, 0,
341 __LITTLE_ENDIAN, 10, none),
342 },
343 };
344
345 static struct lttng_event_field lttng_pollfd_fields[] = {
346 [0] = {
347 .name = "fd",
348 .type = __type_integer(int, 0, 0, 0, __BYTE_ORDER, 10, none),
349 },
350 [1] = {
351 .name = "raw_events",
352 .type = __type_integer(short, 0, 0, 0, __BYTE_ORDER, 16, none),
353 },
354 [2] = {
355 .name = "events",
356 .type = {
357 .atype = atype_struct,
358 .u._struct.nr_fields = ARRAY_SIZE(lttng_pollfd_flag_fields),
359 .u._struct.fields = lttng_pollfd_flag_fields,
360 }
361 },
362 };
363
364 static struct lttng_type lttng_pollfd_elem = {
365 .atype = atype_struct,
366 .u._struct.nr_fields = ARRAY_SIZE(lttng_pollfd_fields),
367 .u._struct.fields = lttng_pollfd_fields,
368 };
369 #endif /* ONCE_LTTNG_TRACE_POLL_H */
370
371 #define LTTNG_SYSCALL_POLL_locvar \
372 unsigned int fds_length, fds_max_len, alloc_fds; \
373 struct pollfd *fds; \
374 uint8_t overflow;
375
376 #define LTTNG_SYSCALL_POLL_code_pre \
377 BUILD_BUG_ON(((ARRAY_SIZE(lttng_pollfd_flag_fields) - 1) + \
378 POLL_FLAGS_PADDING_SIZE) != \
379 sizeof(uint8_t) * BITS_PER_BYTE); \
380 tp_locvar->fds = NULL; \
381 tp_locvar->overflow = 0; \
382 \
383 sc_in( \
384 if (nfds > PAGE_SIZE / sizeof(struct pollfd)) { \
385 tp_locvar->fds_length = PAGE_SIZE / sizeof(struct pollfd); \
386 tp_locvar->fds_max_len = PAGE_SIZE / sizeof(struct pollfd); \
387 tp_locvar->overflow = 1; \
388 } else { \
389 tp_locvar->fds_length = nfds; \
390 tp_locvar->fds_max_len = nfds; \
391 } \
392 tp_locvar->alloc_fds = tp_locvar->fds_length * sizeof(struct pollfd); \
393 ) \
394 /* \
395 * On exit, the number of active FDs is determined by ret, \
396 * nfds stays the same as the entry, but we only want to \
397 * output the FDs that are relevant. \
398 */ \
399 sc_out( \
400 if (ret <= 0 || ret > nfds) \
401 goto error; \
402 \
403 if (nfds > PAGE_SIZE / sizeof(struct pollfd)) { \
404 tp_locvar->fds_length = PAGE_SIZE / sizeof(struct pollfd); \
405 tp_locvar->fds_max_len = PAGE_SIZE / sizeof(struct pollfd); \
406 tp_locvar->overflow = 1; \
407 } else { \
408 tp_locvar->fds_length = ret; \
409 tp_locvar->fds_max_len = nfds; \
410 } \
411 tp_locvar->alloc_fds = tp_locvar->fds_max_len * sizeof(struct pollfd); \
412 ) \
413 { \
414 int err; \
415 \
416 tp_locvar->fds = kmalloc(tp_locvar->alloc_fds, \
417 GFP_ATOMIC | GFP_NOWAIT); \
418 if (!tp_locvar->fds) \
419 goto error; \
420 err = lib_ring_buffer_copy_from_user_check_nofault( \
421 tp_locvar->fds, ufds, tp_locvar->alloc_fds); \
422 if (err != 0) \
423 goto error; \
424 } \
425 goto end; \
426 \
427 error: \
428 tp_locvar->fds_length = 0; \
429 tp_locvar->fds_max_len = 0; \
430 end: \
431 ;
432
433 #define LTTNG_SYSCALL_POLL_fds_field \
434 sc_in( \
435 ctf_custom_field( \
436 ctf_custom_type( \
437 .atype = atype_sequence_compound, \
438 .u.sequence_compound.length_name = "fds_length", \
439 .u.sequence_compound.elem_type = &lttng_pollfd_elem, \
440 ), \
441 fds, \
442 ctf_custom_code( \
443 uint32_t i; \
444 \
445 ctf_align(int) /* Align on largest field in struct. */ \
446 for (i = 0; i < tp_locvar->fds_length; i++) { \
447 ctf_integer_type(int, tp_locvar->fds[i].fd) \
448 ctf_integer_type(short, tp_locvar->fds[i].events) \
449 ctf_integer_bitfield_type(uint8_t, \
450 (uint8_t) tp_locvar->fds[i].events) \
451 } \
452 ) \
453 ) \
454 ) \
455 sc_out( \
456 ctf_custom_field( \
457 ctf_custom_type( \
458 .atype = atype_sequence_compound, \
459 .u.sequence_compound.length_name = "fds_length", \
460 .u.sequence_compound.elem_type = &lttng_pollfd_elem, \
461 ), \
462 fds, \
463 ctf_custom_code( \
464 unsigned int i, nr = 0; \
465 \
466 ctf_align(int) /* Align on largest field in struct. */ \
467 /* \
468 * Iterate over the complete array, but only output \
469 * "ret" active FDs. \
470 */ \
471 for (i = 0; i < tp_locvar->fds_max_len; i++) { \
472 if (!tp_locvar->fds[i].revents) \
473 continue; \
474 if (nr++ >= tp_locvar->fds_length) \
475 break; \
476 ctf_integer_type(int, tp_locvar->fds[i].fd) \
477 ctf_integer_type(short, tp_locvar->fds[i].revents) \
478 ctf_integer_bitfield_type(uint8_t, \
479 (uint8_t) tp_locvar->fds[i].revents) \
480 } \
481 /* \
482 * If there is a discrepancy between ret and the \
483 * content of revents (e.g. caused by userspace corrupting \
484 * the array from a concurrent thread), we have to output \
485 * zeros to keep the trace readable. \
486 */ \
487 for (i = nr; i < tp_locvar->fds_length; i++) { \
488 ctf_integer_type(int, 0) \
489 ctf_integer_type(short, 0) \
490 ctf_integer_bitfield_type(uint8_t, 0) \
491 } \
492 ) \
493 ) \
494 )
495
496 #define LTTNG_SYSCALL_POLL_code_post \
497 kfree(tp_locvar->fds);
498
499 #if defined(CONFIG_X86_32) || defined(CONFIG_X86_64) || defined(CONFIG_ARM)
500 #define OVERRIDE_32_poll
501 #define OVERRIDE_64_poll
502 SC_LTTNG_TRACEPOINT_EVENT_CODE(poll,
503 TP_PROTO(sc_exit(long ret,) struct pollfd __user * ufds,
504 unsigned int nfds, int timeout_msecs),
505 TP_ARGS(sc_exit(ret,) ufds, nfds, timeout_msecs),
506 TP_locvar(
507 LTTNG_SYSCALL_POLL_locvar
508 ),
509 TP_code_pre(
510 LTTNG_SYSCALL_POLL_code_pre
511 ),
512 TP_FIELDS(
513 sc_exit(ctf_integer(long, ret, ret))
514 sc_in(ctf_integer(int, timeout_msecs, timeout_msecs))
515 sc_inout(ctf_integer(unsigned int, nfds, nfds))
516 sc_inout(ctf_integer(unsigned int, fds_length, tp_locvar->fds_length))
517 sc_in(ctf_integer(uint8_t, overflow, tp_locvar->overflow))
518 LTTNG_SYSCALL_POLL_fds_field
519 ),
520 TP_code_post(
521 LTTNG_SYSCALL_POLL_code_post
522 )
523 )
524 #endif /* defined(CONFIG_X86_32) || defined(CONFIG_X86_64) || defined(CONFIG_ARM) */
525
526 #if defined(CONFIG_X86_32) || defined(CONFIG_X86_64) || defined(CONFIG_ARM64) || defined(CONFIG_ARM)
527 #define OVERRIDE_32_ppoll
528 #define OVERRIDE_64_ppoll
529 SC_LTTNG_TRACEPOINT_EVENT_CODE(ppoll,
530 TP_PROTO(sc_exit(long ret,) struct pollfd __user * ufds,
531 unsigned int nfds, struct timespec * tsp, const sigset_t * sigmask, size_t sigsetsize),
532 TP_ARGS(sc_exit(ret,) ufds, nfds, tsp, sigmask, sigsetsize),
533 TP_locvar(
534 LTTNG_SYSCALL_POLL_locvar
535 ),
536 TP_code_pre(
537 LTTNG_SYSCALL_POLL_code_pre
538 ),
539 TP_FIELDS(
540 sc_exit(ctf_integer(long, ret, ret))
541 sc_in(ctf_integer(struct timespec *, tsp, tsp))
542 sc_in(ctf_integer(const sigset_t *, sigmask, sigmask))
543 sc_in(ctf_integer(size_t, sigsetsize, sigsetsize))
544 sc_inout(ctf_integer(unsigned int, nfds, nfds))
545 sc_inout(ctf_integer(unsigned int, fds_length, tp_locvar->fds_length))
546 sc_inout(ctf_integer(uint8_t, overflow, tp_locvar->overflow))
547 LTTNG_SYSCALL_POLL_fds_field
548 ),
549 TP_code_post(
550 LTTNG_SYSCALL_POLL_code_post
551 )
552 )
553 #endif /* defined(CONFIG_X86_32) || defined(CONFIG_X86_64) || defined(CONFIG_ARM64) || defined(CONFIG_ARM) */
554
555 #include <linux/eventpoll.h>
556
557 SC_LTTNG_TRACEPOINT_ENUM(lttng_epoll_op,
558 TP_ENUM_VALUES(
559 ctf_enum_value("EPOLL_CTL_ADD", EPOLL_CTL_ADD)
560 ctf_enum_value("EPOLL_CTL_DEL", EPOLL_CTL_DEL)
561 ctf_enum_value("EPOLL_CTL_MOD", EPOLL_CTL_MOD)
562 )
563 )
564
565 #ifndef ONCE_LTTNG_TRACE_EPOLL_CTL_H
566 #define ONCE_LTTNG_TRACE_EPOLL_CTL_H
567
568 #define LTTNG_EPOLL_NRFLAGS (POLLHUP + 1)
569 #define EPOLL_FLAGS_PADDING_SIZE (sizeof(uint8_t) * BITS_PER_BYTE) - \
570 ilog2(LTTNG_EPOLL_NRFLAGS - 1)
571
572 /*
573 * Only extract the values specified by iBCS2 for now.
574 */
575 static struct lttng_event_field lttng_epoll_ctl_events_fields[] = {
576 /* 0x0001 */
577 [ilog2(POLLIN)] = {
578 .name = "EPOLLIN",
579 .type = __type_integer(int, 1, 1, 0, __LITTLE_ENDIAN, 10, none),
580 },
581 /* 0x0002 */
582 [ilog2(POLLPRI)] = {
583 .name = "EPOLLPRI",
584 .type = __type_integer(int, 1, 1, 0, __LITTLE_ENDIAN, 10, none),
585 },
586 /* 0x0004 */
587 [ilog2(POLLOUT)] = {
588 .name = "EPOLLOUT",
589 .type = __type_integer(int, 1, 1, 0, __LITTLE_ENDIAN, 10, none),
590 },
591 /* 0x0008 */
592 [ilog2(POLLERR)] = {
593 .name = "EPOLLERR",
594 .type = __type_integer(int, 1, 1, 0, __LITTLE_ENDIAN, 10, none),
595 },
596 /* 0x0010 */
597 [ilog2(POLLHUP)] = {
598 .name = "EPOLLHUP",
599 .type = __type_integer(int, 1, 1, 0, __LITTLE_ENDIAN, 10, none),
600 },
601 [ilog2(LTTNG_EPOLL_NRFLAGS)] = {
602 .name = "padding",
603 .type = __type_integer(int, EPOLL_FLAGS_PADDING_SIZE, 1, 0,
604 __LITTLE_ENDIAN, 10, none),
605 },
606
607 };
608
609 static struct lttng_event_field lttng_epoll_data_fields[] = {
610 [0] = {
611 .name = "u64",
612 .type = __type_integer(uint64_t, 0, 0, 0, __BYTE_ORDER, 16, none),
613 },
614 [1] = {
615 .name = "fd",
616 .type = __type_integer(int, 0, 0, 0, __BYTE_ORDER, 10, none),
617 },
618 };
619
620 static struct lttng_event_field epoll_ctl_fields[] = {
621 [0] = {
622 .name = "data_union",
623 .type = {
624 .atype = atype_struct,
625 .u._struct.nr_fields = ARRAY_SIZE(lttng_epoll_data_fields),
626 .u._struct.fields = lttng_epoll_data_fields,
627 }
628 },
629 [1] = {
630 .name = "raw_events",
631 .type = __type_integer(uint32_t, 0, 0, 0, __BYTE_ORDER, 16, none),
632 },
633 [2] = {
634 .name = "events",
635 .type = {
636 .atype = atype_struct,
637 .u._struct.nr_fields = ARRAY_SIZE(lttng_epoll_ctl_events_fields),
638 .u._struct.fields = lttng_epoll_ctl_events_fields,
639 }
640 },
641 };
642 #endif /* ONCE_LTTNG_TRACE_EPOLL_CTL_H */
643
644 #if defined(CONFIG_X86_32) || defined(CONFIG_X86_64) || defined(CONFIG_ARM64) || defined(CONFIG_ARM)
645 #define OVERRIDE_32_epoll_ctl
646 #define OVERRIDE_64_epoll_ctl
647 SC_LTTNG_TRACEPOINT_EVENT_CODE(epoll_ctl,
648 TP_PROTO(sc_exit(long ret,) int epfd, int op, int fd,
649 struct epoll_event __user * uevent),
650 TP_ARGS(sc_exit(ret,) epfd, op, fd, uevent),
651 TP_locvar(
652 struct epoll_event event;
653 int err;
654 ),
655 TP_code_pre(
656 tp_locvar->err = lib_ring_buffer_copy_from_user_check_nofault(
657 &tp_locvar->event, uevent, sizeof(struct epoll_event));
658 ),
659 TP_FIELDS(
660 sc_exit(ctf_integer(long, ret, ret))
661 sc_in(ctf_integer(int, epfd, epfd))
662 sc_in(ctf_enum(lttng_epoll_op, int, op_enum, op))
663 sc_in(ctf_integer(int, fd, fd))
664 sc_in(
665 ctf_custom_field(
666 ctf_custom_type(
667 .atype = atype_struct,
668 .u._struct.nr_fields = ARRAY_SIZE(epoll_ctl_fields),
669 .u._struct.fields = epoll_ctl_fields,
670 ),
671 event,
672 ctf_custom_code(
673 ctf_align(uint64_t)
674 if (!tp_locvar->err) {
675 ctf_integer_type(uint64_t, tp_locvar->event.data)
676 ctf_integer_type(int, tp_locvar->event.data)
677 ctf_integer_bitfield_type(uint32_t,
678 tp_locvar->event.events)
679 ctf_integer_bitfield_type(uint8_t,
680 (uint8_t) tp_locvar->event.events)
681 } else {
682 ctf_integer_type(uint64_t, 0)
683 ctf_integer_type(int, 0)
684 ctf_integer_bitfield_type(uint32_t, 0)
685 ctf_integer_bitfield_type(uint8_t, 0)
686 }
687 )
688 )
689 )
690 ),
691 TP_code_post()
692 )
693 #endif /* defined(CONFIG_X86_32) || defined(CONFIG_X86_64) || defined(CONFIG_ARM64) || defined(CONFIG_ARM) */
694
695 #ifndef ONCE_LTTNG_TRACE_EPOLL_H
696 #define ONCE_LTTNG_TRACE_EPOLL_H
697
698 static struct lttng_event_field lttng_epoll_wait_fields[] = {
699 [0] = {
700 .name = "data_union",
701 .type = {
702 .atype = atype_struct,
703 .u._struct.nr_fields = ARRAY_SIZE(lttng_epoll_data_fields),
704 .u._struct.fields = lttng_epoll_data_fields,
705 }
706 },
707 [1] = {
708 .name = "raw_events",
709 .type = __type_integer(uint32_t, 0, 0, 0, __BYTE_ORDER, 16, none),
710 },
711 [2] = {
712 .name = "events",
713 .type = {
714 .atype = atype_struct,
715 .u._struct.nr_fields = ARRAY_SIZE(lttng_epoll_ctl_events_fields),
716 .u._struct.fields = lttng_epoll_ctl_events_fields,
717 }
718 },
719 };
720
721 static struct lttng_type lttng_epoll_wait_elem = {
722 .atype = atype_struct,
723 .u._struct.nr_fields = ARRAY_SIZE(lttng_epoll_wait_fields),
724 .u._struct.fields = lttng_epoll_wait_fields,
725 };
726
727 #endif /* ONCE_LTTNG_TRACE_EPOLL_H */
728
729 #define LTTNG_SYSCALL_EPOLL_WAIT_locvar \
730 sc_out( \
731 unsigned int fds_length; \
732 uint8_t overflow; \
733 struct epoll_event *events; \
734 )
735
736 #define LTTNG_SYSCALL_EPOLL_WAIT_code_pre \
737 BUILD_BUG_ON(((ARRAY_SIZE(lttng_epoll_ctl_events_fields) - 1) + \
738 EPOLL_FLAGS_PADDING_SIZE) != \
739 sizeof(uint8_t) * BITS_PER_BYTE); \
740 sc_out({ \
741 int err; \
742 unsigned long maxalloc; \
743 \
744 tp_locvar->fds_length = 0; \
745 tp_locvar->events = NULL; \
746 tp_locvar->overflow = 0; \
747 \
748 if (maxevents <= 0 || ret <= 0 || ret > maxevents) \
749 goto skip_code; \
750 \
751 if (maxevents > PAGE_SIZE / sizeof(struct epoll_event)) { \
752 maxalloc = PAGE_SIZE / sizeof(struct epoll_event); \
753 } else { \
754 maxalloc = maxevents; \
755 } \
756 \
757 if (ret > maxalloc) { \
758 tp_locvar->fds_length = maxalloc; \
759 tp_locvar->overflow = 1; \
760 } else { \
761 tp_locvar->fds_length = ret; \
762 } \
763 \
764 tp_locvar->events = kmalloc( \
765 maxalloc * sizeof(struct epoll_event), \
766 GFP_ATOMIC | GFP_NOWAIT); \
767 if (!tp_locvar->events) { \
768 tp_locvar->fds_length = 0; \
769 goto skip_code; \
770 } \
771 \
772 err = lib_ring_buffer_copy_from_user_check_nofault( \
773 tp_locvar->events, uevents, \
774 maxalloc * sizeof(struct epoll_event)); \
775 if (err != 0) \
776 tp_locvar->fds_length = 0; \
777 } \
778 skip_code: \
779 )
780
781 #define LTTNG_SYSCALL_EPOLL_WAIT_fds_field \
782 ctf_custom_field( \
783 ctf_custom_type( \
784 .atype = atype_sequence_compound, \
785 .u.sequence_compound.length_name = \
786 "fds_length", \
787 .u.sequence_compound.elem_type = \
788 &lttng_epoll_wait_elem, \
789 ), \
790 fds, \
791 ctf_custom_code( \
792 uint32_t i; \
793 \
794 ctf_align(uint64_t) \
795 for (i = 0; i < tp_locvar->fds_length; i++) { \
796 ctf_integer_type(uint64_t, tp_locvar->events[i].data) \
797 ctf_integer_type(int, tp_locvar->events[i].data) \
798 ctf_integer_bitfield_type(uint32_t, \
799 tp_locvar->events[i].events) \
800 ctf_integer_bitfield_type(uint8_t, \
801 (uint8_t) tp_locvar->events[i].events) \
802 } \
803 ) \
804 )
805
806 #define LTTNG_SYSCALL_EPOLL_WAIT_code_post \
807 sc_out( \
808 kfree(tp_locvar->events); \
809 )
810
811
812 #if defined(CONFIG_X86_32) || defined(CONFIG_X86_64) || defined(CONFIG_ARM)
813 #define OVERRIDE_32_epoll_wait
814 #define OVERRIDE_64_epoll_wait
815 SC_LTTNG_TRACEPOINT_EVENT_CODE(epoll_wait,
816 TP_PROTO(sc_exit(long ret,) int epfd, struct epoll_event __user * uevents,
817 int maxevents, int timeout),
818 TP_ARGS(sc_exit(ret,) epfd, uevents, maxevents, timeout),
819 TP_locvar(
820 LTTNG_SYSCALL_EPOLL_WAIT_locvar
821 ),
822 TP_code_pre(
823 LTTNG_SYSCALL_EPOLL_WAIT_code_pre
824 ),
825 TP_FIELDS(
826 sc_exit(ctf_integer(long, ret, ret))
827 sc_in(ctf_integer(int, epfd, epfd))
828 sc_in(ctf_integer(int, maxevents, maxevents))
829 sc_in(ctf_integer(int, timeout, timeout))
830 sc_out(ctf_integer(unsigned int, fds_length, tp_locvar->fds_length))
831 sc_out(ctf_integer(uint8_t, overflow, tp_locvar->overflow))
832 sc_out(
833 LTTNG_SYSCALL_EPOLL_WAIT_fds_field
834 )
835 ),
836 TP_code_post(
837 LTTNG_SYSCALL_EPOLL_WAIT_code_post
838 )
839 )
840 #endif /* defined(CONFIG_X86_32) || defined(CONFIG_X86_64) || defined(CONFIG_ARM) */
841
842 #if defined(CONFIG_X86_32) || defined(CONFIG_X86_64) || defined(CONFIG_ARM64) || defined(CONFIG_ARM)
843 #define OVERRIDE_32_epoll_pwait
844 #define OVERRIDE_64_epoll_pwait
845 SC_LTTNG_TRACEPOINT_EVENT_CODE(epoll_pwait,
846 TP_PROTO(sc_exit(long ret,) int epfd, struct epoll_event __user * uevents,
847 int maxevents, int timeout, const sigset_t __user * sigmask, size_t sigsetsize),
848 TP_ARGS(sc_exit(ret,) epfd, uevents, maxevents, timeout, sigmask, sigsetsize),
849 TP_locvar(
850 LTTNG_SYSCALL_EPOLL_WAIT_locvar
851 ),
852 TP_code_pre(
853 LTTNG_SYSCALL_EPOLL_WAIT_code_pre
854 ),
855 TP_FIELDS(
856 sc_exit(ctf_integer(long, ret, ret))
857 sc_in(ctf_integer(int, epfd, epfd))
858 sc_in(ctf_integer(int, maxevents, maxevents))
859 sc_in(ctf_integer(int, timeout, timeout))
860 sc_in(ctf_integer_hex(const sigset_t *, sigmask, sigmask))
861 sc_in(ctf_integer(size_t, sigsetsize, sigsetsize))
862 sc_out(ctf_integer(unsigned int, fds_length, tp_locvar->fds_length))
863 sc_out(ctf_integer(uint8_t, overflow, tp_locvar->overflow))
864 sc_out(
865 LTTNG_SYSCALL_EPOLL_WAIT_fds_field
866 )
867 ),
868 TP_code_post(
869 LTTNG_SYSCALL_EPOLL_WAIT_code_post
870 )
871 )
872 #endif /* defined(CONFIG_X86_32) || defined(CONFIG_X86_64) || defined(CONFIG_ARM64) || defined(CONFIG_ARM) */
873
874 #if (defined(CONFIG_X86_64) && !defined(LTTNG_SC_COMPAT)) || defined(CONFIG_ARM64) || defined(CONFIG_ARM)
875 #define OVERRIDE_32_socketpair
876 #define OVERRIDE_64_socketpair
877 SC_LTTNG_TRACEPOINT_EVENT(socketpair,
878 TP_PROTO(sc_exit(long ret,) int family, int type, int protocol, int *usockvec),
879 TP_ARGS(sc_exit(ret,) family, type, protocol, usockvec),
880 TP_FIELDS(
881 sc_exit(ctf_integer(long, ret, ret))
882 sc_in(ctf_integer(int, family, family))
883 sc_in(ctf_integer(int, type, type))
884 sc_in(ctf_integer(int, protocol, protocol))
885 sc_out(ctf_user_array(int, socket, usockvec, 2))
886 )
887 )
888 #endif /* (defined(CONFIG_X86_64) && !defined(LTTNG_SC_COMPAT)) || defined(CONFIG_ARM64) || defined(CONFIG_ARM) */
889
890 #endif /* CREATE_SYSCALL_TABLE */
This page took 0.081638 seconds and 4 git commands to generate.