1 // SPDX-License-Identifier: GPL-2.0
3 * Augment the raw_syscalls tracepoints with the contents of the pointer arguments.
7 * perf trace -e tools/perf/examples/bpf/augmented_raw_syscalls.c cat /etc/passwd > /dev/null
9 * This exactly matches what is marshalled into the raw_syscall:sys_enter
10 * payload expected by the 'perf trace' beautifiers.
12 * For now it just uses the existing tracepoint augmentation code in 'perf
13 * trace', in the next csets we'll hook up these with the sys_enter/sys_exit
14 * code that will combine entry/exit in a strace like way.
19 #include <pid_filter.h>
21 /* bpf-output associated map */
22 struct bpf_map
SEC("maps") __augmented_syscalls__
= {
23 .type
= BPF_MAP_TYPE_PERF_EVENT_ARRAY
,
24 .key_size
= sizeof(int),
25 .value_size
= sizeof(u32
),
26 .max_entries
= __NR_CPUS__
,
29 struct syscall_enter_args
{
30 unsigned long long common_tp_fields
;
32 unsigned long args
[6];
35 struct syscall_exit_args
{
36 unsigned long long common_tp_fields
;
41 struct augmented_filename
{
50 #define SYS_OPENAT 257
52 pid_filter(pids_filtered
);
54 SEC("raw_syscalls:sys_enter")
55 int sys_enter(struct syscall_enter_args
*args
)
58 struct syscall_enter_args args
;
59 struct augmented_filename filename
;
61 unsigned int len
= sizeof(augmented_args
);
62 const void *filename_arg
= NULL
;
64 if (pid_filter__has(&pids_filtered
, getpid()))
67 probe_read(&augmented_args
.args
, sizeof(augmented_args
.args
), args
);
69 * Yonghong and Edward Cree sayz:
71 * https://www.spinics.net/lists/netdev/msg531645.html
73 * >> R0=inv(id=0) R1=inv2 R6=ctx(id=0,off=0,imm=0) R7=inv64 R10=fp0,call_-1
75 * >> 11: (07) r1 += 16
76 * >> 12: (05) goto pc+2
77 * >> 15: (79) r3 = *(u64 *)(r1 +0)
78 * >> dereference of modified ctx ptr R1 off=16 disallowed
79 * > Aha, we at least got a different error message this time.
80 * > And indeed llvm has done that optimisation, rather than the more obvious
81 * > 11: r3 = *(u64 *)(r1 +16)
82 * > because it wants to have lots of reads share a single insn. You may be able
83 * > to defeat that optimisation by adding compiler barriers, idk. Maybe someone
84 * > with llvm knowledge can figure out how to stop it (ideally, llvm would know
85 * > when it's generating for bpf backend and not do that). -O0? ¯\_(ツ)_/¯
87 * The optimization mostly likes below:
100 * The compiler tries to merge common loads. There is no easy way to
101 * stop this compiler optimization without turning off a lot of other
102 * optimizations. The easiest way is to add barriers:
104 * __asm__ __volatile__("": : :"memory")
106 * after the ctx memory access to prevent their down stream merging.
108 switch (augmented_args
.args
.syscall_nr
) {
110 case SYS_POLL
: return 0;
111 case SYS_OPEN
: filename_arg
= (const void *)args
->args
[0];
112 __asm__
__volatile__("": : :"memory");
114 case SYS_OPENAT
: filename_arg
= (const void *)args
->args
[1];
118 if (filename_arg
!= NULL
) {
119 augmented_args
.filename
.reserved
= 0;
120 augmented_args
.filename
.size
= probe_read_str(&augmented_args
.filename
.value
,
121 sizeof(augmented_args
.filename
.value
),
123 if (augmented_args
.filename
.size
< sizeof(augmented_args
.filename
.value
)) {
124 len
-= sizeof(augmented_args
.filename
.value
) - augmented_args
.filename
.size
;
125 len
&= sizeof(augmented_args
.filename
.value
) - 1;
128 len
= sizeof(augmented_args
.args
);
131 perf_event_output(args
, &__augmented_syscalls__
, BPF_F_CURRENT_CPU
, &augmented_args
, len
);
135 SEC("raw_syscalls:sys_exit")
136 int sys_exit(struct syscall_exit_args
*args
)
138 return !pid_filter__has(&pids_filtered
, getpid());