diff options
author | David Daney <david.daney@cavium.com> | 2017-06-13 19:49:38 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2017-06-14 15:03:23 -0400 |
commit | 4b7190e8416d9238e995da993a7fb851996654e2 (patch) | |
tree | cd9223768849c8dc218787198acdc37d4ba2dc17 /samples | |
parent | c1932cdb275e65cbef2f230f0df0c490fdd03c62 (diff) |
samples/bpf: Fix tracex5 to work with MIPS syscalls.
There are two problems:
1) In MIPS the __NR_* macros expand to an expression, this causes the
sections of the object file to be named like:
.
.
.
[ 5] kprobe/(5000 + 1) PROGBITS 0000000000000000 000160 ...
[ 6] kprobe/(5000 + 0) PROGBITS 0000000000000000 000258 ...
[ 7] kprobe/(5000 + 9) PROGBITS 0000000000000000 000348 ...
.
.
.
The fix here is to use the "asm_offsets" trick to evaluate the macros
in the C compiler and generate a header file with a usable form of the
macros.
2) MIPS syscall numbers start at 5000, so we need a bigger map to hold
the sub-programs.
Signed-off-by: David Daney <david.daney@cavium.com>
Acked-by: Daniel Borkmann <daniel@iogearbox.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'samples')
-rw-r--r-- | samples/bpf/Makefile | 13 | ||||
-rw-r--r-- | samples/bpf/syscall_nrs.c | 12 | ||||
-rw-r--r-- | samples/bpf/tracex5_kern.c | 11 |
3 files changed, 33 insertions, 3 deletions
diff --git a/samples/bpf/Makefile b/samples/bpf/Makefile index 6c7468eb3684..a0561dc762fe 100644 --- a/samples/bpf/Makefile +++ b/samples/bpf/Makefile | |||
@@ -160,6 +160,17 @@ clean: | |||
160 | $(MAKE) -C ../../ M=$(CURDIR) clean | 160 | $(MAKE) -C ../../ M=$(CURDIR) clean |
161 | @rm -f *~ | 161 | @rm -f *~ |
162 | 162 | ||
163 | $(obj)/syscall_nrs.s: $(src)/syscall_nrs.c | ||
164 | $(call if_changed_dep,cc_s_c) | ||
165 | |||
166 | $(obj)/syscall_nrs.h: $(obj)/syscall_nrs.s FORCE | ||
167 | $(call filechk,offsets,__SYSCALL_NRS_H__) | ||
168 | |||
169 | clean-files += syscall_nrs.h | ||
170 | |||
171 | FORCE: | ||
172 | |||
173 | |||
163 | # Verify LLVM compiler tools are available and bpf target is supported by llc | 174 | # Verify LLVM compiler tools are available and bpf target is supported by llc |
164 | .PHONY: verify_cmds verify_target_bpf $(CLANG) $(LLC) | 175 | .PHONY: verify_cmds verify_target_bpf $(CLANG) $(LLC) |
165 | 176 | ||
@@ -180,6 +191,8 @@ verify_target_bpf: verify_cmds | |||
180 | 191 | ||
181 | $(src)/*.c: verify_target_bpf | 192 | $(src)/*.c: verify_target_bpf |
182 | 193 | ||
194 | $(obj)/tracex5_kern.o: $(obj)/syscall_nrs.h | ||
195 | |||
183 | # asm/sysreg.h - inline assembly used by it is incompatible with llvm. | 196 | # asm/sysreg.h - inline assembly used by it is incompatible with llvm. |
184 | # But, there is no easy way to fix it, so just exclude it since it is | 197 | # But, there is no easy way to fix it, so just exclude it since it is |
185 | # useless for BPF samples. | 198 | # useless for BPF samples. |
diff --git a/samples/bpf/syscall_nrs.c b/samples/bpf/syscall_nrs.c new file mode 100644 index 000000000000..ce2a30b11248 --- /dev/null +++ b/samples/bpf/syscall_nrs.c | |||
@@ -0,0 +1,12 @@ | |||
1 | #include <uapi/linux/unistd.h> | ||
2 | #include <linux/kbuild.h> | ||
3 | |||
4 | #define SYSNR(_NR) DEFINE(SYS ## _NR, _NR) | ||
5 | |||
6 | void syscall_defines(void) | ||
7 | { | ||
8 | COMMENT("Linux system call numbers."); | ||
9 | SYSNR(__NR_write); | ||
10 | SYSNR(__NR_read); | ||
11 | SYSNR(__NR_mmap); | ||
12 | } | ||
diff --git a/samples/bpf/tracex5_kern.c b/samples/bpf/tracex5_kern.c index 7e4cf74553ff..f57f4e1ea1ec 100644 --- a/samples/bpf/tracex5_kern.c +++ b/samples/bpf/tracex5_kern.c | |||
@@ -9,6 +9,7 @@ | |||
9 | #include <uapi/linux/bpf.h> | 9 | #include <uapi/linux/bpf.h> |
10 | #include <uapi/linux/seccomp.h> | 10 | #include <uapi/linux/seccomp.h> |
11 | #include <uapi/linux/unistd.h> | 11 | #include <uapi/linux/unistd.h> |
12 | #include "syscall_nrs.h" | ||
12 | #include "bpf_helpers.h" | 13 | #include "bpf_helpers.h" |
13 | 14 | ||
14 | #define PROG(F) SEC("kprobe/"__stringify(F)) int bpf_func_##F | 15 | #define PROG(F) SEC("kprobe/"__stringify(F)) int bpf_func_##F |
@@ -17,7 +18,11 @@ struct bpf_map_def SEC("maps") progs = { | |||
17 | .type = BPF_MAP_TYPE_PROG_ARRAY, | 18 | .type = BPF_MAP_TYPE_PROG_ARRAY, |
18 | .key_size = sizeof(u32), | 19 | .key_size = sizeof(u32), |
19 | .value_size = sizeof(u32), | 20 | .value_size = sizeof(u32), |
21 | #ifdef __mips__ | ||
22 | .max_entries = 6000, /* MIPS n64 syscalls start at 5000 */ | ||
23 | #else | ||
20 | .max_entries = 1024, | 24 | .max_entries = 1024, |
25 | #endif | ||
21 | }; | 26 | }; |
22 | 27 | ||
23 | SEC("kprobe/__seccomp_filter") | 28 | SEC("kprobe/__seccomp_filter") |
@@ -37,7 +42,7 @@ int bpf_prog1(struct pt_regs *ctx) | |||
37 | } | 42 | } |
38 | 43 | ||
39 | /* we jump here when syscall number == __NR_write */ | 44 | /* we jump here when syscall number == __NR_write */ |
40 | PROG(__NR_write)(struct pt_regs *ctx) | 45 | PROG(SYS__NR_write)(struct pt_regs *ctx) |
41 | { | 46 | { |
42 | struct seccomp_data sd; | 47 | struct seccomp_data sd; |
43 | 48 | ||
@@ -50,7 +55,7 @@ PROG(__NR_write)(struct pt_regs *ctx) | |||
50 | return 0; | 55 | return 0; |
51 | } | 56 | } |
52 | 57 | ||
53 | PROG(__NR_read)(struct pt_regs *ctx) | 58 | PROG(SYS__NR_read)(struct pt_regs *ctx) |
54 | { | 59 | { |
55 | struct seccomp_data sd; | 60 | struct seccomp_data sd; |
56 | 61 | ||
@@ -63,7 +68,7 @@ PROG(__NR_read)(struct pt_regs *ctx) | |||
63 | return 0; | 68 | return 0; |
64 | } | 69 | } |
65 | 70 | ||
66 | PROG(__NR_mmap)(struct pt_regs *ctx) | 71 | PROG(SYS__NR_mmap)(struct pt_regs *ctx) |
67 | { | 72 | { |
68 | char fmt[] = "mmap\n"; | 73 | char fmt[] = "mmap\n"; |
69 | bpf_trace_printk(fmt, sizeof(fmt)); | 74 | bpf_trace_printk(fmt, sizeof(fmt)); |