History

Merge git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next

Alexei Starovoitov says: ==================== pull-request: bpf-next 2021-12-30 The following pull-request contains BPF updates for your *net-next* tree. We've added 72 non-merge commits during the last 20 day(s) which contain a total of 223 files changed, 3510 insertions(+), 1591 deletions(-). The main changes are: 1) Automatic setrlimit in libbpf when bpf is memcg's in the kernel, from Andrii. 2) Beautify and de-verbose verifier logs, from Christy. 3) Composable verifier types, from Hao. 4) bpf_strncmp helper, from Hou. 5) bpf.h header dependency cleanup, from Jakub. 6) get_func_[arg|ret|arg_cnt] helpers, from Jiri. 7) Sleepable local storage, from KP. 8) Extend kfunc with PTR_TO_CTX, PTR_TO_MEM argument support, from Kumar. ====================

David S. Miller committed 4 years ago

Commit e63a0232 parents ce2b6eb 9e6b19a221 files · +3506 −1591Browse files

Showing the changes to tools/testing (42 of 221 files). Show all

Unified · Split

42 files
  1. tools/testing/selftests/bpf/Makefile +7 −5
  2. tools/testing/selftests/bpf/bench.c +7 −17
  3. tools/testing/selftests/bpf/bench.h +5 −4
  4. tools/testing/selftests/bpf/benchs/bench_count.c +1 −1
  5. tools/testing/selftests/bpf/benchs/bench_rename.c +8 −8
  6. tools/testing/selftests/bpf/benchs/bench_ringbufs.c +7 −7
  7. tools/testing/selftests/bpf/benchs/bench_strncmp.c +161 −0
  8. tools/testing/selftests/bpf/benchs/bench_trigger.c +12 −12
  9. tools/testing/selftests/bpf/benchs/run_bench_strncmp.sh +12 −0
  10. tools/testing/selftests/bpf/config +2 −0
  11. tools/testing/selftests/bpf/prog_tests/align.c +103 −88
  12. tools/testing/selftests/bpf/prog_tests/bpf_obj_id.c +2 −2
  13. tools/testing/selftests/bpf/prog_tests/bpf_tcp_ca.c +3 −4
  14. tools/testing/selftests/bpf/prog_tests/btf.c +0 −1
  15. tools/testing/selftests/bpf/prog_tests/connect_force_port.c +9 −9
  16. tools/testing/selftests/bpf/prog_tests/core_reloc.c +53 −26
  17. tools/testing/selftests/bpf/prog_tests/fexit_bpf2bpf.c +13 −4
  18. tools/testing/selftests/bpf/prog_tests/get_func_args_test.c +44 −0
  19. tools/testing/selftests/bpf/prog_tests/get_stack_raw_tp.c +2 −2
  20. tools/testing/selftests/bpf/prog_tests/ksyms_btf.c +14 −0
  21. tools/testing/selftests/bpf/prog_tests/libbpf_probes.c +124 −0
  22. tools/testing/selftests/bpf/prog_tests/select_reuseport.c +0 −1
  23. tools/testing/selftests/bpf/prog_tests/sk_lookup.c +0 −1
  24. tools/testing/selftests/bpf/prog_tests/sock_fields.c +0 −1
  25. tools/testing/selftests/bpf/prog_tests/sockopt_inherit.c +8 −7
  26. tools/testing/selftests/bpf/prog_tests/stacktrace_map.c +2 −2
  27. tools/testing/selftests/bpf/prog_tests/stacktrace_map_raw_tp.c +2 −2
  28. tools/testing/selftests/bpf/prog_tests/test_local_storage.c +6 −14
  29. tools/testing/selftests/bpf/prog_tests/test_overhead.c +10 −10
  30. tools/testing/selftests/bpf/prog_tests/test_strncmp.c +167 −0
  31. tools/testing/selftests/bpf/prog_tests/trampoline_count.c +3 −3
  32. tools/testing/selftests/bpf/progs/get_func_args_test.c +123 −0
  33. tools/testing/selftests/bpf/progs/local_storage.c +5 −19
  34. tools/testing/selftests/bpf/progs/strncmp_bench.c +50 −0
  35. tools/testing/selftests/bpf/progs/strncmp_test.c +54 −0
  36. tools/testing/selftests/bpf/progs/test_ksyms_btf_write_check.c +29 −0
  37. tools/testing/selftests/bpf/test_cpp.cpp +8 −1
  38. tools/testing/selftests/bpf/test_maps.c +0 −1
  39. tools/testing/selftests/bpf/test_progs.c +0 −2
  40. tools/testing/selftests/bpf/test_verifier.c +8 −10
  41. tools/testing/selftests/bpf/verifier/btf_ctx_access.c +12 −0
  42. tools/testing/selftests/bpf/vmtest.sh +1 −1
tools/testing/selftests/bpf/Makefile+7−5
@@ -170,7 +170,7 @@ $(OUTPUT)/%:%.c · 169 unmodified lines
170 170
171$(OUTPUT)/urandom_read: urandom_read.c171$(OUTPUT)/urandom_read: urandom_read.c
172 $(call msg,BINARY,,$@)172 $(call msg,BINARY,,$@)
173 $(Q)$(CC) $(LDFLAGS) $< $(LDLIBS) -Wl,--build-id=sha1 -o $@173 $(Q)$(CC) $(CFLAGS) $(LDFLAGS) $< $(LDLIBS) -Wl,--build-id=sha1 -o $@
174 174
175$(OUTPUT)/bpf_testmod.ko: $(VMLINUX_BTF) $(wildcard bpf_testmod/Makefile bpf_testmod/*.[ch])175$(OUTPUT)/bpf_testmod.ko: $(VMLINUX_BTF) $(wildcard bpf_testmod/Makefile bpf_testmod/*.[ch])
176 $(call msg,MOD,,$@)176 $(call msg,MOD,,$@)
@@ -217,7 +217,7 @@ BPFTOOL ?= $(DEFAULT_BPFTOOL) · 40 unmodified lines
217$(DEFAULT_BPFTOOL): $(wildcard $(BPFTOOLDIR)/*.[ch] $(BPFTOOLDIR)/Makefile) \217$(DEFAULT_BPFTOOL): $(wildcard $(BPFTOOLDIR)/*.[ch] $(BPFTOOLDIR)/Makefile) \
218 $(HOST_BPFOBJ) | $(HOST_BUILD_DIR)/bpftool218 $(HOST_BPFOBJ) | $(HOST_BUILD_DIR)/bpftool
219 $(Q)$(MAKE) $(submake_extras) -C $(BPFTOOLDIR) \219 $(Q)$(MAKE) $(submake_extras) -C $(BPFTOOLDIR) \
220 CC=$(HOSTCC) LD=$(HOSTLD) \220 ARCH= CROSS_COMPILE= CC=$(HOSTCC) LD=$(HOSTLD) \
221 EXTRA_CFLAGS='-g -O0' \221 EXTRA_CFLAGS='-g -O0' \
222 OUTPUT=$(HOST_BUILD_DIR)/bpftool/ \222 OUTPUT=$(HOST_BUILD_DIR)/bpftool/ \
223 LIBBPF_OUTPUT=$(HOST_BUILD_DIR)/libbpf/ \223 LIBBPF_OUTPUT=$(HOST_BUILD_DIR)/libbpf/ \
@@ -248,7 +248,7 @@ $(HOST_BPFOBJ): $(wildcard $(BPFDIR)/*.[ch] $(BPFDIR)/Makefile) \ · 24 unmodified lines
248 $(APIDIR)/linux/bpf.h \248 $(APIDIR)/linux/bpf.h \
249 | $(HOST_BUILD_DIR)/libbpf249 | $(HOST_BUILD_DIR)/libbpf
250 $(Q)$(MAKE) $(submake_extras) -C $(BPFDIR) \250 $(Q)$(MAKE) $(submake_extras) -C $(BPFDIR) \
251 EXTRA_CFLAGS='-g -O0' \251 EXTRA_CFLAGS='-g -O0' ARCH= CROSS_COMPILE= \
252 OUTPUT=$(HOST_BUILD_DIR)/libbpf/ CC=$(HOSTCC) LD=$(HOSTLD) \252 OUTPUT=$(HOST_BUILD_DIR)/libbpf/ CC=$(HOSTCC) LD=$(HOSTLD) \
253 DESTDIR=$(HOST_SCRATCH_DIR)/ prefix= all install_headers253 DESTDIR=$(HOST_SCRATCH_DIR)/ prefix= all install_headers
254endif254endif
@@ -537,6 +537,7 @@ $(OUTPUT)/bench_ringbufs.o: $(OUTPUT)/ringbuf_bench.skel.h \ · 282 unmodified lines
537 $(OUTPUT)/perfbuf_bench.skel.h537 $(OUTPUT)/perfbuf_bench.skel.h
538$(OUTPUT)/bench_bloom_filter_map.o: $(OUTPUT)/bloom_filter_bench.skel.h538$(OUTPUT)/bench_bloom_filter_map.o: $(OUTPUT)/bloom_filter_bench.skel.h
539$(OUTPUT)/bench_bpf_loop.o: $(OUTPUT)/bpf_loop_bench.skel.h539$(OUTPUT)/bench_bpf_loop.o: $(OUTPUT)/bpf_loop_bench.skel.h
540$(OUTPUT)/bench_strncmp.o: $(OUTPUT)/strncmp_bench.skel.h
540$(OUTPUT)/bench.o: bench.h testing_helpers.h $(BPFOBJ)541$(OUTPUT)/bench.o: bench.h testing_helpers.h $(BPFOBJ)
541$(OUTPUT)/bench: LDLIBS += -lm542$(OUTPUT)/bench: LDLIBS += -lm
542$(OUTPUT)/bench: $(OUTPUT)/bench.o \543$(OUTPUT)/bench: $(OUTPUT)/bench.o \
@@ -547,9 +548,10 @@ $(OUTPUT)/bench: $(OUTPUT)/bench.o \ · 4 unmodified lines
547 $(OUTPUT)/bench_trigger.o \548 $(OUTPUT)/bench_trigger.o \
548 $(OUTPUT)/bench_ringbufs.o \549 $(OUTPUT)/bench_ringbufs.o \
549 $(OUTPUT)/bench_bloom_filter_map.o \550 $(OUTPUT)/bench_bloom_filter_map.o \
550 $(OUTPUT)/bench_bpf_loop.o551 $(OUTPUT)/bench_bpf_loop.o \
552 $(OUTPUT)/bench_strncmp.o
551 $(call msg,BINARY,,$@)553 $(call msg,BINARY,,$@)
552 $(Q)$(CC) $(LDFLAGS) $(filter %.a %.o,$^) $(LDLIBS) -o $@554 $(Q)$(CC) $(CFLAGS) $(LDFLAGS) $(filter %.a %.o,$^) $(LDLIBS) -o $@
553 555
554EXTRA_CLEAN := $(TEST_CUSTOM_PROGS) $(SCRATCH_DIR) $(HOST_SCRATCH_DIR) \556EXTRA_CLEAN := $(TEST_CUSTOM_PROGS) $(SCRATCH_DIR) $(HOST_SCRATCH_DIR) \
555 prog_tests/tests.h map_tests/tests.h verifier/tests.h \557 prog_tests/tests.h map_tests/tests.h verifier/tests.h \
tools/testing/selftests/bpf/bench.c+7−17
@@ -29,26 +29,10 @@ static int libbpf_print_fn(enum libbpf_print_level level, · 28 unmodified lines
29 return vfprintf(stderr, format, args);29 return vfprintf(stderr, format, args);
30}30}
31 31
32static int bump_memlock_rlimit(void)32void setup_libbpf(void)
33{33{
34 struct rlimit rlim_new = {
35 .rlim_cur = RLIM_INFINITY,
36 .rlim_max = RLIM_INFINITY,
37 };
38
39 return setrlimit(RLIMIT_MEMLOCK, &rlim_new);
40}
41
42void setup_libbpf()
43{
44 int err;
45
46 libbpf_set_strict_mode(LIBBPF_STRICT_ALL);34 libbpf_set_strict_mode(LIBBPF_STRICT_ALL);
47 libbpf_set_print(libbpf_print_fn);35 libbpf_set_print(libbpf_print_fn);
48
49 err = bump_memlock_rlimit();
50 if (err)
51 fprintf(stderr, "failed to increase RLIMIT_MEMLOCK: %d", err);
52}36}
53 37
54void false_hits_report_progress(int iter, struct bench_res *res, long delta_ns)38void false_hits_report_progress(int iter, struct bench_res *res, long delta_ns)
@@ -205,11 +189,13 @@ static const struct argp_option opts[] = { · 150 unmodified lines
205extern struct argp bench_ringbufs_argp;189extern struct argp bench_ringbufs_argp;
206extern struct argp bench_bloom_map_argp;190extern struct argp bench_bloom_map_argp;
207extern struct argp bench_bpf_loop_argp;191extern struct argp bench_bpf_loop_argp;
192extern struct argp bench_strncmp_argp;
208 193
209static const struct argp_child bench_parsers[] = {194static const struct argp_child bench_parsers[] = {
210 { &bench_ringbufs_argp, 0, "Ring buffers benchmark", 0 },195 { &bench_ringbufs_argp, 0, "Ring buffers benchmark", 0 },
211 { &bench_bloom_map_argp, 0, "Bloom filter map benchmark", 0 },196 { &bench_bloom_map_argp, 0, "Bloom filter map benchmark", 0 },
212 { &bench_bpf_loop_argp, 0, "bpf_loop helper benchmark", 0 },197 { &bench_bpf_loop_argp, 0, "bpf_loop helper benchmark", 0 },
198 { &bench_strncmp_argp, 0, "bpf_strncmp helper benchmark", 0 },
213 {},199 {},
214};200};
215 201
@@ -409,6 +395,8 @@ extern const struct bench bench_bloom_false_positive; · 193 unmodified lines
409extern const struct bench bench_hashmap_without_bloom;395extern const struct bench bench_hashmap_without_bloom;
410extern const struct bench bench_hashmap_with_bloom;396extern const struct bench bench_hashmap_with_bloom;
411extern const struct bench bench_bpf_loop;397extern const struct bench bench_bpf_loop;
398extern const struct bench bench_strncmp_no_helper;
399extern const struct bench bench_strncmp_helper;
412 400
413static const struct bench *benchs[] = {401static const struct bench *benchs[] = {
414 &bench_count_global,402 &bench_count_global,
@@ -441,6 +429,8 @@ static const struct bench *benchs[] = { · 26 unmodified lines
441 &bench_hashmap_without_bloom,429 &bench_hashmap_without_bloom,
442 &bench_hashmap_with_bloom,430 &bench_hashmap_with_bloom,
443 &bench_bpf_loop,431 &bench_bpf_loop,
432 &bench_strncmp_no_helper,
433 &bench_strncmp_helper,
444};434};
445 435
446static void setup_benchmark()436static void setup_benchmark()
tools/testing/selftests/bpf/bench.h+5−4
@@ -38,8 +38,8 @@ struct bench_res { · 37 unmodified lines
38 38
39struct bench {39struct bench {
40 const char *name;40 const char *name;
41 void (*validate)();41 void (*validate)(void);
42 void (*setup)();42 void (*setup)(void);
43 void *(*producer_thread)(void *ctx);43 void *(*producer_thread)(void *ctx);
44 void *(*consumer_thread)(void *ctx);44 void *(*consumer_thread)(void *ctx);
45 void (*measure)(struct bench_res* res);45 void (*measure)(struct bench_res* res);
@@ -54,7 +54,7 @@ struct counter { · 8 unmodified lines
54extern struct env env;54extern struct env env;
55extern const struct bench *bench;55extern const struct bench *bench;
56 56
57void setup_libbpf();57void setup_libbpf(void);
58void hits_drops_report_progress(int iter, struct bench_res *res, long delta_ns);58void hits_drops_report_progress(int iter, struct bench_res *res, long delta_ns);
59void hits_drops_report_final(struct bench_res res[], int res_cnt);59void hits_drops_report_final(struct bench_res res[], int res_cnt);
60void false_hits_report_progress(int iter, struct bench_res *res, long delta_ns);60void false_hits_report_progress(int iter, struct bench_res *res, long delta_ns);
@@ -62,7 +62,8 @@ void false_hits_report_final(struct bench_res res[], int res_cnt); · 1 unmodified line
62void ops_report_progress(int iter, struct bench_res *res, long delta_ns);62void ops_report_progress(int iter, struct bench_res *res, long delta_ns);
63void ops_report_final(struct bench_res res[], int res_cnt);63void ops_report_final(struct bench_res res[], int res_cnt);
64 64
65static inline __u64 get_time_ns() {65static inline __u64 get_time_ns(void)
66{
66 struct timespec t;67 struct timespec t;
67 68
68 clock_gettime(CLOCK_MONOTONIC, &t);69 clock_gettime(CLOCK_MONOTONIC, &t);
tools/testing/selftests/bpf/benchs/bench_count.c+1−1
@@ -36,7 +36,7 @@ static struct count_local_ctx { · 35 unmodified lines
36 struct counter *hits;36 struct counter *hits;
37} count_local_ctx;37} count_local_ctx;
38 38
39static void count_local_setup()39static void count_local_setup(void)
40{40{
41 struct count_local_ctx *ctx = &count_local_ctx;41 struct count_local_ctx *ctx = &count_local_ctx;
42 42
tools/testing/selftests/bpf/benchs/bench_rename.c+8−8
@@ -11,7 +11,7 @@ static struct ctx { · 10 unmodified lines
11 int fd;11 int fd;
12} ctx;12} ctx;
13 13
14static void validate()14static void validate(void)
15{15{
16 if (env.producer_cnt != 1) {16 if (env.producer_cnt != 1) {
17 fprintf(stderr, "benchmark doesn't support multi-producer!\n");17 fprintf(stderr, "benchmark doesn't support multi-producer!\n");
@@ -43,7 +43,7 @@ static void measure(struct bench_res *res) · 25 unmodified lines
43 res->hits = atomic_swap(&ctx.hits.value, 0);43 res->hits = atomic_swap(&ctx.hits.value, 0);
44}44}
45 45
46static void setup_ctx()46static void setup_ctx(void)
47{47{
48 setup_libbpf();48 setup_libbpf();
49 49
@@ -71,36 +71,36 @@ static void attach_bpf(struct bpf_program *prog) · 21 unmodified lines
71 }71 }
72}72}
73 73
74static void setup_base()74static void setup_base(void)
75{75{
76 setup_ctx();76 setup_ctx();
77}77}
78 78
79static void setup_kprobe()79static void setup_kprobe(void)
80{80{
81 setup_ctx();81 setup_ctx();
82 attach_bpf(ctx.skel->progs.prog1);82 attach_bpf(ctx.skel->progs.prog1);
83}83}
84 84
85static void setup_kretprobe()85static void setup_kretprobe(void)
86{86{
87 setup_ctx();87 setup_ctx();
88 attach_bpf(ctx.skel->progs.prog2);88 attach_bpf(ctx.skel->progs.prog2);
89}89}
90 90
91static void setup_rawtp()91static void setup_rawtp(void)
92{92{
93 setup_ctx();93 setup_ctx();
94 attach_bpf(ctx.skel->progs.prog3);94 attach_bpf(ctx.skel->progs.prog3);
95}95}
96 96
97static void setup_fentry()97static void setup_fentry(void)
98{98{
99 setup_ctx();99 setup_ctx();
100 attach_bpf(ctx.skel->progs.prog4);100 attach_bpf(ctx.skel->progs.prog4);
101}101}
102 102
103static void setup_fexit()103static void setup_fexit(void)
104{104{
105 setup_ctx();105 setup_ctx();
106 attach_bpf(ctx.skel->progs.prog5);106 attach_bpf(ctx.skel->progs.prog5);
tools/testing/selftests/bpf/benchs/bench_ringbufs.c+7−7
@@ -88,12 +88,12 @@ const struct argp bench_ringbufs_argp = { · 87 unmodified lines
88 88
89static struct counter buf_hits;89static struct counter buf_hits;
90 90
91static inline void bufs_trigger_batch()91static inline void bufs_trigger_batch(void)
92{92{
93 (void)syscall(__NR_getpgid);93 (void)syscall(__NR_getpgid);
94}94}
95 95
96static void bufs_validate()96static void bufs_validate(void)
97{97{
98 if (env.consumer_cnt != 1) {98 if (env.consumer_cnt != 1) {
99 fprintf(stderr, "rb-libbpf benchmark doesn't support multi-consumer!\n");99 fprintf(stderr, "rb-libbpf benchmark doesn't support multi-consumer!\n");
@@ -132,7 +132,7 @@ static void ringbuf_libbpf_measure(struct bench_res *res) · 32 unmodified lines
132 res->drops = atomic_swap(&ctx->skel->bss->dropped, 0);132 res->drops = atomic_swap(&ctx->skel->bss->dropped, 0);
133}133}
134 134
135static struct ringbuf_bench *ringbuf_setup_skeleton()135static struct ringbuf_bench *ringbuf_setup_skeleton(void)
136{136{
137 struct ringbuf_bench *skel;137 struct ringbuf_bench *skel;
138 138
@@ -167,7 +167,7 @@ static int buf_process_sample(void *ctx, void *data, size_t len) · 28 unmodified lines
167 return 0;167 return 0;
168}168}
169 169
170static void ringbuf_libbpf_setup()170static void ringbuf_libbpf_setup(void)
171{171{
172 struct ringbuf_libbpf_ctx *ctx = &ringbuf_libbpf_ctx;172 struct ringbuf_libbpf_ctx *ctx = &ringbuf_libbpf_ctx;
173 struct bpf_link *link;173 struct bpf_link *link;
@@ -223,7 +223,7 @@ static void ringbuf_custom_measure(struct bench_res *res) · 49 unmodified lines
223 res->drops = atomic_swap(&ctx->skel->bss->dropped, 0);223 res->drops = atomic_swap(&ctx->skel->bss->dropped, 0);
224}224}
225 225
226static void ringbuf_custom_setup()226static void ringbuf_custom_setup(void)
227{227{
228 struct ringbuf_custom_ctx *ctx = &ringbuf_custom_ctx;228 struct ringbuf_custom_ctx *ctx = &ringbuf_custom_ctx;
229 const size_t page_size = getpagesize();229 const size_t page_size = getpagesize();
@@ -352,7 +352,7 @@ static void perfbuf_measure(struct bench_res *res) · 122 unmodified lines
352 res->drops = atomic_swap(&ctx->skel->bss->dropped, 0);352 res->drops = atomic_swap(&ctx->skel->bss->dropped, 0);
353}353}
354 354
355static struct perfbuf_bench *perfbuf_setup_skeleton()355static struct perfbuf_bench *perfbuf_setup_skeleton(void)
356{356{
357 struct perfbuf_bench *skel;357 struct perfbuf_bench *skel;
358 358
@@ -390,7 +390,7 @@ perfbuf_process_sample_raw(void *input_ctx, int cpu, · 31 unmodified lines
390 return LIBBPF_PERF_EVENT_CONT;390 return LIBBPF_PERF_EVENT_CONT;
391}391}
392 392
393static void perfbuf_libbpf_setup()393static void perfbuf_libbpf_setup(void)
394{394{
395 struct perfbuf_libbpf_ctx *ctx = &perfbuf_libbpf_ctx;395 struct perfbuf_libbpf_ctx *ctx = &perfbuf_libbpf_ctx;
396 struct perf_event_attr attr;396 struct perf_event_attr attr;
tools/testing/selftests/bpf/benchs/bench_strncmp.c+161−0
@@ -0,0 +1,161 @@
1// SPDX-License-Identifier: GPL-2.0
2/* Copyright (C) 2021. Huawei Technologies Co., Ltd */
3#include <argp.h>
4#include "bench.h"
5#include "strncmp_bench.skel.h"
6
7static struct strncmp_ctx {
8 struct strncmp_bench *skel;
9} ctx;
10
11static struct strncmp_args {
12 u32 cmp_str_len;
13} args = {
14 .cmp_str_len = 32,
15};
16
17enum {
18 ARG_CMP_STR_LEN = 5000,
19};
20
21static const struct argp_option opts[] = {
22 { "cmp-str-len", ARG_CMP_STR_LEN, "CMP_STR_LEN", 0,
23 "Set the length of compared string" },
24 {},
25};
26
27static error_t strncmp_parse_arg(int key, char *arg, struct argp_state *state)
28{
29 switch (key) {
30 case ARG_CMP_STR_LEN:
31 args.cmp_str_len = strtoul(arg, NULL, 10);
32 if (!args.cmp_str_len ||
33 args.cmp_str_len >= sizeof(ctx.skel->bss->str)) {
34 fprintf(stderr, "Invalid cmp str len (limit %zu)\n",
35 sizeof(ctx.skel->bss->str));
36 argp_usage(state);
37 }
38 break;
39 default:
40 return ARGP_ERR_UNKNOWN;
41 }
42
43 return 0;
44}
45
46const struct argp bench_strncmp_argp = {
47 .options = opts,
48 .parser = strncmp_parse_arg,
49};
50
51static void strncmp_validate(void)
52{
53 if (env.consumer_cnt != 1) {
54 fprintf(stderr, "strncmp benchmark doesn't support multi-consumer!\n");
55 exit(1);
56 }
57}
58
59static void strncmp_setup(void)
60{
61 int err;
62 char *target;
63 size_t i, sz;
64
65 sz = sizeof(ctx.skel->rodata->target);
66 if (!sz || sz < sizeof(ctx.skel->bss->str)) {
67 fprintf(stderr, "invalid string size (target %zu, src %zu)\n",
68 sz, sizeof(ctx.skel->bss->str));
69 exit(1);
70 }
71
72 setup_libbpf();
73
74 ctx.skel = strncmp_bench__open();
75 if (!ctx.skel) {
76 fprintf(stderr, "failed to open skeleton\n");
77 exit(1);
78 }
79
80 srandom(time(NULL));
81 target = ctx.skel->rodata->target;
82 for (i = 0; i < sz - 1; i++)
83 target[i] = '1' + random() % 9;
84 target[sz - 1] = '\0';
85
86 ctx.skel->rodata->cmp_str_len = args.cmp_str_len;
87
88 memcpy(ctx.skel->bss->str, target, args.cmp_str_len);
89 ctx.skel->bss->str[args.cmp_str_len] = '\0';
90 /* Make bss->str < rodata->target */
91 ctx.skel->bss->str[args.cmp_str_len - 1] -= 1;
92
93 err = strncmp_bench__load(ctx.skel);
94 if (err) {
95 fprintf(stderr, "failed to load skeleton\n");
96 strncmp_bench__destroy(ctx.skel);
97 exit(1);
98 }
99}
100
101static void strncmp_attach_prog(struct bpf_program *prog)
102{
103 struct bpf_link *link;
104
105 link = bpf_program__attach(prog);
106 if (!link) {
107 fprintf(stderr, "failed to attach program!\n");
108 exit(1);
109 }
110}
111
112static void strncmp_no_helper_setup(void)
113{
114 strncmp_setup();
115 strncmp_attach_prog(ctx.skel->progs.strncmp_no_helper);
116}
117
118static void strncmp_helper_setup(void)
119{
120 strncmp_setup();
121 strncmp_attach_prog(ctx.skel->progs.strncmp_helper);
122}
123
124static void *strncmp_producer(void *ctx)
125{
126 while (true)
127 (void)syscall(__NR_getpgid);
128 return NULL;
129}
130
131static void *strncmp_consumer(void *ctx)
132{
133 return NULL;
134}
135
136static void strncmp_measure(struct bench_res *res)
137{
138 res->hits = atomic_swap(&ctx.skel->bss->hits, 0);
139}
140
141const struct bench bench_strncmp_no_helper = {
142 .name = "strncmp-no-helper",
143 .validate = strncmp_validate,
144 .setup = strncmp_no_helper_setup,
145 .producer_thread = strncmp_producer,
146 .consumer_thread = strncmp_consumer,
147 .measure = strncmp_measure,
148 .report_progress = hits_drops_report_progress,
149 .report_final = hits_drops_report_final,
150};
151
152const struct bench bench_strncmp_helper = {
153 .name = "strncmp-helper",
154 .validate = strncmp_validate,
155 .setup = strncmp_helper_setup,
156 .producer_thread = strncmp_producer,
157 .consumer_thread = strncmp_consumer,
158 .measure = strncmp_measure,
159 .report_progress = hits_drops_report_progress,
160 .report_final = hits_drops_report_final,
161};
tools/testing/selftests/bpf/benchs/bench_trigger.c+12−12
@@ -11,7 +11,7 @@ static struct trigger_ctx { · 10 unmodified lines
11 11
12static struct counter base_hits;12static struct counter base_hits;
13 13
14static void trigger_validate()14static void trigger_validate(void)
15{15{
16 if (env.consumer_cnt != 1) {16 if (env.consumer_cnt != 1) {
17 fprintf(stderr, "benchmark doesn't support multi-consumer!\n");17 fprintf(stderr, "benchmark doesn't support multi-consumer!\n");
@@ -45,7 +45,7 @@ static void trigger_measure(struct bench_res *res) · 27 unmodified lines
45 res->hits = atomic_swap(&ctx.skel->bss->hits, 0);45 res->hits = atomic_swap(&ctx.skel->bss->hits, 0);
46}46}
47 47
48static void setup_ctx()48static void setup_ctx(void)
49{49{
50 setup_libbpf();50 setup_libbpf();
51 51
@@ -67,37 +67,37 @@ static void attach_bpf(struct bpf_program *prog) · 15 unmodified lines
67 }67 }
68}68}
69 69
70static void trigger_tp_setup()70static void trigger_tp_setup(void)
71{71{
72 setup_ctx();72 setup_ctx();
73 attach_bpf(ctx.skel->progs.bench_trigger_tp);73 attach_bpf(ctx.skel->progs.bench_trigger_tp);
74}74}
75 75
76static void trigger_rawtp_setup()76static void trigger_rawtp_setup(void)
77{77{
78 setup_ctx();78 setup_ctx();
79 attach_bpf(ctx.skel->progs.bench_trigger_raw_tp);79 attach_bpf(ctx.skel->progs.bench_trigger_raw_tp);
80}80}
81 81
82static void trigger_kprobe_setup()82static void trigger_kprobe_setup(void)
83{83{
84 setup_ctx();84 setup_ctx();
85 attach_bpf(ctx.skel->progs.bench_trigger_kprobe);85 attach_bpf(ctx.skel->progs.bench_trigger_kprobe);
86}86}
87 87
88static void trigger_fentry_setup()88static void trigger_fentry_setup(void)
89{89{
90 setup_ctx();90 setup_ctx();
91 attach_bpf(ctx.skel->progs.bench_trigger_fentry);91 attach_bpf(ctx.skel->progs.bench_trigger_fentry);
92}92}
93 93
94static void trigger_fentry_sleep_setup()94static void trigger_fentry_sleep_setup(void)
95{95{
96 setup_ctx();96 setup_ctx();
97 attach_bpf(ctx.skel->progs.bench_trigger_fentry_sleep);97 attach_bpf(ctx.skel->progs.bench_trigger_fentry_sleep);
98}98}
99 99
100static void trigger_fmodret_setup()100static void trigger_fmodret_setup(void)
101{101{
102 setup_ctx();102 setup_ctx();
103 attach_bpf(ctx.skel->progs.bench_trigger_fmodret);103 attach_bpf(ctx.skel->progs.bench_trigger_fmodret);
@@ -183,22 +183,22 @@ static void usetup(bool use_retprobe, bool use_nop) · 79 unmodified lines
183 ctx.skel->links.bench_trigger_uprobe = link;183 ctx.skel->links.bench_trigger_uprobe = link;
184}184}
185 185
186static void uprobe_setup_with_nop()186static void uprobe_setup_with_nop(void)
187{187{
188 usetup(false, true);188 usetup(false, true);
189}189}
190 190
191static void uretprobe_setup_with_nop()191static void uretprobe_setup_with_nop(void)
192{192{
193 usetup(true, true);193 usetup(true, true);
194}194}
195 195
196static void uprobe_setup_without_nop()196static void uprobe_setup_without_nop(void)
197{197{
198 usetup(false, false);198 usetup(false, false);
199}199}
200 200
201static void uretprobe_setup_without_nop()201static void uretprobe_setup_without_nop(void)
202{202{
203 usetup(true, false);203 usetup(true, false);
204}204}
tools/testing/selftests/bpf/benchs/run_bench_strncmp.sh+12−0
@@ -0,0 +1,12 @@
1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3
4source ./benchs/run_common.sh
5
6set -eufo pipefail
7
8for s in 1 8 64 512 2048 4095; do
9 for b in no-helper helper; do
10 summarize ${b}-${s} "$($RUN_BENCH --cmp-str-len=$s strncmp-${b})"
11 done
12done
tools/testing/selftests/bpf/config+2−0
@@ -38,7 +38,9 @@ CONFIG_IPV6_SIT=m · 37 unmodified lines
38CONFIG_BPF_JIT=y38CONFIG_BPF_JIT=y
39CONFIG_BPF_LSM=y39CONFIG_BPF_LSM=y
40CONFIG_SECURITY=y40CONFIG_SECURITY=y
41CONFIG_RC_CORE=y
41CONFIG_LIRC=y42CONFIG_LIRC=y
43CONFIG_BPF_LIRC_MODE2=y
42CONFIG_IMA=y44CONFIG_IMA=y
43CONFIG_SECURITYFS=y45CONFIG_SECURITYFS=y
44CONFIG_IMA_WRITE_POLICY=y46CONFIG_IMA_WRITE_POLICY=y
tools/testing/selftests/bpf/prog_tests/align.c+103−88
@@ -39,13 +39,13 @@ static struct bpf_align_test tests[] = { · 38 unmodified lines
39 },39 },
40 .prog_type = BPF_PROG_TYPE_SCHED_CLS,40 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
41 .matches = {41 .matches = {
42 {1, "R1=ctx(id=0,off=0,imm=0)"},42 {0, "R1=ctx(id=0,off=0,imm=0)"},
43 {1, "R10=fp0"},43 {0, "R10=fp0"},
44 {1, "R3_w=inv2"},44 {0, "R3_w=inv2"},
45 {2, "R3_w=inv4"},45 {1, "R3_w=inv4"},
46 {3, "R3_w=inv8"},46 {2, "R3_w=inv8"},
47 {4, "R3_w=inv16"},47 {3, "R3_w=inv16"},
48 {5, "R3_w=inv32"},48 {4, "R3_w=inv32"},
49 },49 },
50 },50 },
51 {51 {
@@ -67,19 +67,19 @@ static struct bpf_align_test tests[] = { · 15 unmodified lines
67 },67 },
68 .prog_type = BPF_PROG_TYPE_SCHED_CLS,68 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
69 .matches = {69 .matches = {
70 {1, "R1=ctx(id=0,off=0,imm=0)"},70 {0, "R1=ctx(id=0,off=0,imm=0)"},
71 {1, "R10=fp0"},71 {0, "R10=fp0"},
72 {1, "R3_w=inv1"},72 {0, "R3_w=inv1"},
73 {2, "R3_w=inv2"},73 {1, "R3_w=inv2"},
74 {3, "R3_w=inv4"},74 {2, "R3_w=inv4"},
75 {4, "R3_w=inv8"},75 {3, "R3_w=inv8"},
76 {5, "R3_w=inv16"},76 {4, "R3_w=inv16"},
77 {6, "R3_w=inv1"},77 {5, "R3_w=inv1"},
78 {7, "R4_w=inv32"},78 {6, "R4_w=inv32"},
79 {8, "R4_w=inv16"},79 {7, "R4_w=inv16"},
80 {9, "R4_w=inv8"},80 {8, "R4_w=inv8"},
81 {10, "R4_w=inv4"},81 {9, "R4_w=inv4"},
82 {11, "R4_w=inv2"},82 {10, "R4_w=inv2"},
83 },83 },
84 },84 },
85 {85 {
@@ -96,14 +96,14 @@ static struct bpf_align_test tests[] = { · 10 unmodified lines
96 },96 },
97 .prog_type = BPF_PROG_TYPE_SCHED_CLS,97 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
98 .matches = {98 .matches = {
99 {1, "R1=ctx(id=0,off=0,imm=0)"},99 {0, "R1=ctx(id=0,off=0,imm=0)"},
100 {1, "R10=fp0"},100 {0, "R10=fp0"},
101 {1, "R3_w=inv4"},101 {0, "R3_w=inv4"},
102 {2, "R3_w=inv8"},102 {1, "R3_w=inv8"},
103 {3, "R3_w=inv10"},103 {2, "R3_w=inv10"},
104 {4, "R4_w=inv8"},104 {3, "R4_w=inv8"},
105 {5, "R4_w=inv12"},105 {4, "R4_w=inv12"},
106 {6, "R4_w=inv14"},106 {5, "R4_w=inv14"},
107 },107 },
108 },108 },
109 {109 {
@@ -118,12 +118,12 @@ static struct bpf_align_test tests[] = { · 8 unmodified lines
118 },118 },
119 .prog_type = BPF_PROG_TYPE_SCHED_CLS,119 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
120 .matches = {120 .matches = {
121 {1, "R1=ctx(id=0,off=0,imm=0)"},121 {0, "R1=ctx(id=0,off=0,imm=0)"},
122 {1, "R10=fp0"},122 {0, "R10=fp0"},
123 {0, "R3_w=inv7"},
123 {1, "R3_w=inv7"},124 {1, "R3_w=inv7"},
124 {2, "R3_w=inv7"},125 {2, "R3_w=inv14"},
125 {3, "R3_w=inv14"},126 {3, "R3_w=inv56"},
126 {4, "R3_w=inv56"},
127 },127 },
128 },128 },
129 129
@@ -161,19 +161,19 @@ static struct bpf_align_test tests[] = { · 31 unmodified lines
161 },161 },
162 .prog_type = BPF_PROG_TYPE_SCHED_CLS,162 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
163 .matches = {163 .matches = {
164 {7, "R0_w=pkt(id=0,off=8,r=8,imm=0)"},164 {6, "R0_w=pkt(id=0,off=8,r=8,imm=0)"},
165 {7, "R3_w=inv(id=0,umax_value=255,var_off=(0x0; 0xff))"},165 {6, "R3_w=inv(id=0,umax_value=255,var_off=(0x0; 0xff))"},
166 {8, "R3_w=inv(id=0,umax_value=510,var_off=(0x0; 0x1fe))"},166 {7, "R3_w=inv(id=0,umax_value=510,var_off=(0x0; 0x1fe))"},
167 {9, "R3_w=inv(id=0,umax_value=1020,var_off=(0x0; 0x3fc))"},167 {8, "R3_w=inv(id=0,umax_value=1020,var_off=(0x0; 0x3fc))"},
168 {10, "R3_w=inv(id=0,umax_value=2040,var_off=(0x0; 0x7f8))"},168 {9, "R3_w=inv(id=0,umax_value=2040,var_off=(0x0; 0x7f8))"},
169 {11, "R3_w=inv(id=0,umax_value=4080,var_off=(0x0; 0xff0))"},169 {10, "R3_w=inv(id=0,umax_value=4080,var_off=(0x0; 0xff0))"},
170 {18, "R3=pkt_end(id=0,off=0,imm=0)"},170 {12, "R3_w=pkt_end(id=0,off=0,imm=0)"},
171 {18, "R4_w=inv(id=0,umax_value=255,var_off=(0x0; 0xff))"},171 {17, "R4_w=inv(id=0,umax_value=255,var_off=(0x0; 0xff))"},
172 {19, "R4_w=inv(id=0,umax_value=8160,var_off=(0x0; 0x1fe0))"},172 {18, "R4_w=inv(id=0,umax_value=8160,var_off=(0x0; 0x1fe0))"},
173 {20, "R4_w=inv(id=0,umax_value=4080,var_off=(0x0; 0xff0))"},173 {19, "R4_w=inv(id=0,umax_value=4080,var_off=(0x0; 0xff0))"},
174 {21, "R4_w=inv(id=0,umax_value=2040,var_off=(0x0; 0x7f8))"},174 {20, "R4_w=inv(id=0,umax_value=2040,var_off=(0x0; 0x7f8))"},
175 {22, "R4_w=inv(id=0,umax_value=1020,var_off=(0x0; 0x3fc))"},175 {21, "R4_w=inv(id=0,umax_value=1020,var_off=(0x0; 0x3fc))"},
176 {23, "R4_w=inv(id=0,umax_value=510,var_off=(0x0; 0x1fe))"},176 {22, "R4_w=inv(id=0,umax_value=510,var_off=(0x0; 0x1fe))"},
177 },177 },
178 },178 },
179 {179 {
@@ -194,16 +194,16 @@ static struct bpf_align_test tests[] = { · 14 unmodified lines
194 },194 },
195 .prog_type = BPF_PROG_TYPE_SCHED_CLS,195 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
196 .matches = {196 .matches = {
197 {7, "R3_w=inv(id=0,umax_value=255,var_off=(0x0; 0xff))"},197 {6, "R3_w=inv(id=0,umax_value=255,var_off=(0x0; 0xff))"},
198 {8, "R4_w=inv(id=1,umax_value=255,var_off=(0x0; 0xff))"},198 {7, "R4_w=inv(id=1,umax_value=255,var_off=(0x0; 0xff))"},
199 {9, "R4_w=inv(id=0,umax_value=255,var_off=(0x0; 0xff))"},199 {8, "R4_w=inv(id=0,umax_value=255,var_off=(0x0; 0xff))"},
200 {10, "R4_w=inv(id=1,umax_value=255,var_off=(0x0; 0xff))"},200 {9, "R4_w=inv(id=1,umax_value=255,var_off=(0x0; 0xff))"},
201 {11, "R4_w=inv(id=0,umax_value=510,var_off=(0x0; 0x1fe))"},201 {10, "R4_w=inv(id=0,umax_value=510,var_off=(0x0; 0x1fe))"},
202 {12, "R4_w=inv(id=1,umax_value=255,var_off=(0x0; 0xff))"},202 {11, "R4_w=inv(id=1,umax_value=255,var_off=(0x0; 0xff))"},
203 {13, "R4_w=inv(id=0,umax_value=1020,var_off=(0x0; 0x3fc))"},203 {12, "R4_w=inv(id=0,umax_value=1020,var_off=(0x0; 0x3fc))"},
204 {14, "R4_w=inv(id=1,umax_value=255,var_off=(0x0; 0xff))"},204 {13, "R4_w=inv(id=1,umax_value=255,var_off=(0x0; 0xff))"},
205 {15, "R4_w=inv(id=0,umax_value=2040,var_off=(0x0; 0x7f8))"},205 {14, "R4_w=inv(id=0,umax_value=2040,var_off=(0x0; 0x7f8))"},
206 {16, "R4_w=inv(id=0,umax_value=4080,var_off=(0x0; 0xff0))"},206 {15, "R4_w=inv(id=0,umax_value=4080,var_off=(0x0; 0xff0))"},
207 },207 },
208 },208 },
209 {209 {
@@ -234,14 +234,14 @@ static struct bpf_align_test tests[] = { · 24 unmodified lines
234 },234 },
235 .prog_type = BPF_PROG_TYPE_SCHED_CLS,235 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
236 .matches = {236 .matches = {
237 {4, "R5_w=pkt(id=0,off=0,r=0,imm=0)"},237 {2, "R5_w=pkt(id=0,off=0,r=0,imm=0)"},
238 {5, "R5_w=pkt(id=0,off=14,r=0,imm=0)"},238 {4, "R5_w=pkt(id=0,off=14,r=0,imm=0)"},
239 {6, "R4_w=pkt(id=0,off=14,r=0,imm=0)"},239 {5, "R4_w=pkt(id=0,off=14,r=0,imm=0)"},
240 {10, "R2=pkt(id=0,off=0,r=18,imm=0)"},240 {9, "R2=pkt(id=0,off=0,r=18,imm=0)"},
241 {10, "R5=pkt(id=0,off=14,r=18,imm=0)"},241 {10, "R5=pkt(id=0,off=14,r=18,imm=0)"},
242 {10, "R4_w=inv(id=0,umax_value=255,var_off=(0x0; 0xff))"},242 {10, "R4_w=inv(id=0,umax_value=255,var_off=(0x0; 0xff))"},
243 {13, "R4_w=inv(id=0,umax_value=65535,var_off=(0x0; 0xffff))"},
243 {14, "R4_w=inv(id=0,umax_value=65535,var_off=(0x0; 0xffff))"},244 {14, "R4_w=inv(id=0,umax_value=65535,var_off=(0x0; 0xffff))"},
244 {15, "R4_w=inv(id=0,umax_value=65535,var_off=(0x0; 0xffff))"},
245 },245 },
246 },246 },
247 {247 {
@@ -296,8 +296,8 @@ static struct bpf_align_test tests[] = { · 48 unmodified lines
296 /* Calculated offset in R6 has unknown value, but known296 /* Calculated offset in R6 has unknown value, but known
297 * alignment of 4.297 * alignment of 4.
298 */298 */
299 {8, "R2_w=pkt(id=0,off=0,r=8,imm=0)"},299 {6, "R2_w=pkt(id=0,off=0,r=8,imm=0)"},
300 {8, "R6_w=inv(id=0,umax_value=1020,var_off=(0x0; 0x3fc))"},300 {7, "R6_w=inv(id=0,umax_value=1020,var_off=(0x0; 0x3fc))"},
301 /* Offset is added to packet pointer R5, resulting in301 /* Offset is added to packet pointer R5, resulting in
302 * known fixed offset, and variable offset from R6.302 * known fixed offset, and variable offset from R6.
303 */303 */
@@ -313,11 +313,11 @@ static struct bpf_align_test tests[] = { · 9 unmodified lines
313 /* Variable offset is added to R5 packet pointer,313 /* Variable offset is added to R5 packet pointer,
314 * resulting in auxiliary alignment of 4.314 * resulting in auxiliary alignment of 4.
315 */315 */
316 {18, "R5_w=pkt(id=2,off=0,r=0,umax_value=1020,var_off=(0x0; 0x3fc))"},316 {17, "R5_w=pkt(id=2,off=0,r=0,umax_value=1020,var_off=(0x0; 0x3fc))"},
317 /* Constant offset is added to R5, resulting in317 /* Constant offset is added to R5, resulting in
318 * reg->off of 14.318 * reg->off of 14.
319 */319 */
320 {19, "R5_w=pkt(id=2,off=14,r=0,umax_value=1020,var_off=(0x0; 0x3fc))"},320 {18, "R5_w=pkt(id=2,off=14,r=0,umax_value=1020,var_off=(0x0; 0x3fc))"},
321 /* At the time the word size load is performed from R5,321 /* At the time the word size load is performed from R5,
322 * its total fixed offset is NET_IP_ALIGN + reg->off322 * its total fixed offset is NET_IP_ALIGN + reg->off
323 * (14) which is 16. Then the variable offset is 4-byte323 * (14) which is 16. Then the variable offset is 4-byte
@@ -329,18 +329,18 @@ static struct bpf_align_test tests[] = { · 5 unmodified lines
329 /* Constant offset is added to R5 packet pointer,329 /* Constant offset is added to R5 packet pointer,
330 * resulting in reg->off value of 14.330 * resulting in reg->off value of 14.
331 */331 */
332 {26, "R5_w=pkt(id=0,off=14,r=8"},332 {25, "R5_w=pkt(id=0,off=14,r=8"},
333 /* Variable offset is added to R5, resulting in a333 /* Variable offset is added to R5, resulting in a
334 * variable offset of (4n).334 * variable offset of (4n).
335 */335 */
336 {27, "R5_w=pkt(id=3,off=14,r=0,umax_value=1020,var_off=(0x0; 0x3fc))"},336 {26, "R5_w=pkt(id=3,off=14,r=0,umax_value=1020,var_off=(0x0; 0x3fc))"},
337 /* Constant is added to R5 again, setting reg->off to 18. */337 /* Constant is added to R5 again, setting reg->off to 18. */
338 {28, "R5_w=pkt(id=3,off=18,r=0,umax_value=1020,var_off=(0x0; 0x3fc))"},338 {27, "R5_w=pkt(id=3,off=18,r=0,umax_value=1020,var_off=(0x0; 0x3fc))"},
339 /* And once more we add a variable; resulting var_off339 /* And once more we add a variable; resulting var_off
340 * is still (4n), fixed offset is not changed.340 * is still (4n), fixed offset is not changed.
341 * Also, we create a new reg->id.341 * Also, we create a new reg->id.
342 */342 */
343 {29, "R5_w=pkt(id=4,off=18,r=0,umax_value=2040,var_off=(0x0; 0x7fc)"},343 {28, "R5_w=pkt(id=4,off=18,r=0,umax_value=2040,var_off=(0x0; 0x7fc)"},
344 /* At the time the word size load is performed from R5,344 /* At the time the word size load is performed from R5,
345 * its total fixed offset is NET_IP_ALIGN + reg->off (18)345 * its total fixed offset is NET_IP_ALIGN + reg->off (18)
346 * which is 20. Then the variable offset is (4n), so346 * which is 20. Then the variable offset is (4n), so
@@ -386,13 +386,13 @@ static struct bpf_align_test tests[] = { · 39 unmodified lines
386 /* Calculated offset in R6 has unknown value, but known386 /* Calculated offset in R6 has unknown value, but known
387 * alignment of 4.387 * alignment of 4.
388 */388 */
389 {8, "R2_w=pkt(id=0,off=0,r=8,imm=0)"},389 {6, "R2_w=pkt(id=0,off=0,r=8,imm=0)"},
390 {8, "R6_w=inv(id=0,umax_value=1020,var_off=(0x0; 0x3fc))"},390 {7, "R6_w=inv(id=0,umax_value=1020,var_off=(0x0; 0x3fc))"},
391 /* Adding 14 makes R6 be (4n+2) */391 /* Adding 14 makes R6 be (4n+2) */
392 {9, "R6_w=inv(id=0,umin_value=14,umax_value=1034,var_off=(0x2; 0x7fc))"},392 {8, "R6_w=inv(id=0,umin_value=14,umax_value=1034,var_off=(0x2; 0x7fc))"},
393 /* Packet pointer has (4n+2) offset */393 /* Packet pointer has (4n+2) offset */
394 {11, "R5_w=pkt(id=1,off=0,r=0,umin_value=14,umax_value=1034,var_off=(0x2; 0x7fc)"},394 {11, "R5_w=pkt(id=1,off=0,r=0,umin_value=14,umax_value=1034,var_off=(0x2; 0x7fc)"},
395 {13, "R4=pkt(id=1,off=4,r=0,umin_value=14,umax_value=1034,var_off=(0x2; 0x7fc)"},395 {12, "R4=pkt(id=1,off=4,r=0,umin_value=14,umax_value=1034,var_off=(0x2; 0x7fc)"},
396 /* At the time the word size load is performed from R5,396 /* At the time the word size load is performed from R5,
397 * its total fixed offset is NET_IP_ALIGN + reg->off (0)397 * its total fixed offset is NET_IP_ALIGN + reg->off (0)
398 * which is 2. Then the variable offset is (4n+2), so398 * which is 2. Then the variable offset is (4n+2), so
@@ -403,12 +403,12 @@ static struct bpf_align_test tests[] = { · 4 unmodified lines
403 /* Newly read value in R6 was shifted left by 2, so has403 /* Newly read value in R6 was shifted left by 2, so has
404 * known alignment of 4.404 * known alignment of 4.
405 */405 */
406 {18, "R6_w=inv(id=0,umax_value=1020,var_off=(0x0; 0x3fc))"},406 {17, "R6_w=inv(id=0,umax_value=1020,var_off=(0x0; 0x3fc))"},
407 /* Added (4n) to packet pointer's (4n+2) var_off, giving407 /* Added (4n) to packet pointer's (4n+2) var_off, giving
408 * another (4n+2).408 * another (4n+2).
409 */409 */
410 {19, "R5_w=pkt(id=2,off=0,r=0,umin_value=14,umax_value=2054,var_off=(0x2; 0xffc)"},410 {19, "R5_w=pkt(id=2,off=0,r=0,umin_value=14,umax_value=2054,var_off=(0x2; 0xffc)"},
411 {21, "R4=pkt(id=2,off=4,r=0,umin_value=14,umax_value=2054,var_off=(0x2; 0xffc)"},411 {20, "R4=pkt(id=2,off=4,r=0,umin_value=14,umax_value=2054,var_off=(0x2; 0xffc)"},
412 /* At the time the word size load is performed from R5,412 /* At the time the word size load is performed from R5,
413 * its total fixed offset is NET_IP_ALIGN + reg->off (0)413 * its total fixed offset is NET_IP_ALIGN + reg->off (0)
414 * which is 2. Then the variable offset is (4n+2), so414 * which is 2. Then the variable offset is (4n+2), so
@@ -448,18 +448,18 @@ static struct bpf_align_test tests[] = { · 33 unmodified lines
448 .prog_type = BPF_PROG_TYPE_SCHED_CLS,448 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
449 .result = REJECT,449 .result = REJECT,
450 .matches = {450 .matches = {
451 {4, "R5_w=pkt_end(id=0,off=0,imm=0)"},451 {3, "R5_w=pkt_end(id=0,off=0,imm=0)"},
452 /* (ptr - ptr) << 2 == unknown, (4n) */452 /* (ptr - ptr) << 2 == unknown, (4n) */
453 {6, "R5_w=inv(id=0,smax_value=9223372036854775804,umax_value=18446744073709551612,var_off=(0x0; 0xfffffffffffffffc)"},453 {5, "R5_w=inv(id=0,smax_value=9223372036854775804,umax_value=18446744073709551612,var_off=(0x0; 0xfffffffffffffffc)"},
454 /* (4n) + 14 == (4n+2). We blow our bounds, because454 /* (4n) + 14 == (4n+2). We blow our bounds, because
455 * the add could overflow.455 * the add could overflow.
456 */456 */
457 {7, "R5_w=inv(id=0,smin_value=-9223372036854775806,smax_value=9223372036854775806,umin_value=2,umax_value=18446744073709551614,var_off=(0x2; 0xfffffffffffffffc)"},457 {6, "R5_w=inv(id=0,smin_value=-9223372036854775806,smax_value=9223372036854775806,umin_value=2,umax_value=18446744073709551614,var_off=(0x2; 0xfffffffffffffffc)"},
458 /* Checked s>=0 */458 /* Checked s>=0 */
459 {9, "R5=inv(id=0,umin_value=2,umax_value=9223372036854775806,var_off=(0x2; 0x7ffffffffffffffc)"},459 {9, "R5=inv(id=0,umin_value=2,umax_value=9223372036854775806,var_off=(0x2; 0x7ffffffffffffffc)"},
460 /* packet pointer + nonnegative (4n+2) */460 /* packet pointer + nonnegative (4n+2) */
461 {11, "R6_w=pkt(id=1,off=0,r=0,umin_value=2,umax_value=9223372036854775806,var_off=(0x2; 0x7ffffffffffffffc)"},461 {11, "R6_w=pkt(id=1,off=0,r=0,umin_value=2,umax_value=9223372036854775806,var_off=(0x2; 0x7ffffffffffffffc)"},
462 {13, "R4_w=pkt(id=1,off=4,r=0,umin_value=2,umax_value=9223372036854775806,var_off=(0x2; 0x7ffffffffffffffc)"},462 {12, "R4_w=pkt(id=1,off=4,r=0,umin_value=2,umax_value=9223372036854775806,var_off=(0x2; 0x7ffffffffffffffc)"},
463 /* NET_IP_ALIGN + (4n+2) == (4n), alignment is fine.463 /* NET_IP_ALIGN + (4n+2) == (4n), alignment is fine.
464 * We checked the bounds, but it might have been able464 * We checked the bounds, but it might have been able
465 * to overflow if the packet pointer started in the465 * to overflow if the packet pointer started in the
@@ -502,14 +502,14 @@ static struct bpf_align_test tests[] = { · 36 unmodified lines
502 /* Calculated offset in R6 has unknown value, but known502 /* Calculated offset in R6 has unknown value, but known
503 * alignment of 4.503 * alignment of 4.
504 */504 */
505 {7, "R2_w=pkt(id=0,off=0,r=8,imm=0)"},505 {6, "R2_w=pkt(id=0,off=0,r=8,imm=0)"},
506 {9, "R6_w=inv(id=0,umax_value=1020,var_off=(0x0; 0x3fc))"},506 {8, "R6_w=inv(id=0,umax_value=1020,var_off=(0x0; 0x3fc))"},
507 /* Adding 14 makes R6 be (4n+2) */507 /* Adding 14 makes R6 be (4n+2) */
508 {10, "R6_w=inv(id=0,umin_value=14,umax_value=1034,var_off=(0x2; 0x7fc))"},508 {9, "R6_w=inv(id=0,umin_value=14,umax_value=1034,var_off=(0x2; 0x7fc))"},
509 /* New unknown value in R7 is (4n) */509 /* New unknown value in R7 is (4n) */
510 {11, "R7_w=inv(id=0,umax_value=1020,var_off=(0x0; 0x3fc))"},510 {10, "R7_w=inv(id=0,umax_value=1020,var_off=(0x0; 0x3fc))"},
511 /* Subtracting it from R6 blows our unsigned bounds */511 /* Subtracting it from R6 blows our unsigned bounds */
512 {12, "R6=inv(id=0,smin_value=-1006,smax_value=1034,umin_value=2,umax_value=18446744073709551614,var_off=(0x2; 0xfffffffffffffffc)"},512 {11, "R6=inv(id=0,smin_value=-1006,smax_value=1034,umin_value=2,umax_value=18446744073709551614,var_off=(0x2; 0xfffffffffffffffc)"},
513 /* Checked s>= 0 */513 /* Checked s>= 0 */
514 {14, "R6=inv(id=0,umin_value=2,umax_value=1034,var_off=(0x2; 0x7fc))"},514 {14, "R6=inv(id=0,umin_value=2,umax_value=1034,var_off=(0x2; 0x7fc))"},
515 /* At the time the word size load is performed from R5,515 /* At the time the word size load is performed from R5,
@@ -556,14 +556,14 @@ static struct bpf_align_test tests[] = { · 40 unmodified lines
556 /* Calculated offset in R6 has unknown value, but known556 /* Calculated offset in R6 has unknown value, but known
557 * alignment of 4.557 * alignment of 4.
558 */558 */
559 {7, "R2_w=pkt(id=0,off=0,r=8,imm=0)"},559 {6, "R2_w=pkt(id=0,off=0,r=8,imm=0)"},
560 {10, "R6_w=inv(id=0,umax_value=60,var_off=(0x0; 0x3c))"},560 {9, "R6_w=inv(id=0,umax_value=60,var_off=(0x0; 0x3c))"},
561 /* Adding 14 makes R6 be (4n+2) */561 /* Adding 14 makes R6 be (4n+2) */
562 {11, "R6_w=inv(id=0,umin_value=14,umax_value=74,var_off=(0x2; 0x7c))"},562 {10, "R6_w=inv(id=0,umin_value=14,umax_value=74,var_off=(0x2; 0x7c))"},
563 /* Subtracting from packet pointer overflows ubounds */563 /* Subtracting from packet pointer overflows ubounds */
564 {13, "R5_w=pkt(id=2,off=0,r=8,umin_value=18446744073709551542,umax_value=18446744073709551602,var_off=(0xffffffffffffff82; 0x7c)"},564 {13, "R5_w=pkt(id=2,off=0,r=8,umin_value=18446744073709551542,umax_value=18446744073709551602,var_off=(0xffffffffffffff82; 0x7c)"},
565 /* New unknown value in R7 is (4n), >= 76 */565 /* New unknown value in R7 is (4n), >= 76 */
566 {15, "R7_w=inv(id=0,umin_value=76,umax_value=1096,var_off=(0x0; 0x7fc))"},566 {14, "R7_w=inv(id=0,umin_value=76,umax_value=1096,var_off=(0x0; 0x7fc))"},
567 /* Adding it to packet pointer gives nice bounds again */567 /* Adding it to packet pointer gives nice bounds again */
568 {16, "R5_w=pkt(id=3,off=0,r=0,umin_value=2,umax_value=1082,var_off=(0x2; 0xfffffffc)"},568 {16, "R5_w=pkt(id=3,off=0,r=0,umin_value=2,umax_value=1082,var_off=(0x2; 0xfffffffc)"},
569 /* At the time the word size load is performed from R5,569 /* At the time the word size load is performed from R5,
@@ -625,12 +625,15 @@ static int do_test_single(struct bpf_align_test *test) · 55 unmodified lines
625 line_ptr = strtok(bpf_vlog_copy, "\n");625 line_ptr = strtok(bpf_vlog_copy, "\n");
626 for (i = 0; i < MAX_MATCHES; i++) {626 for (i = 0; i < MAX_MATCHES; i++) {
627 struct bpf_reg_match m = test->matches[i];627 struct bpf_reg_match m = test->matches[i];
628 int tmp;
628 629
629 if (!m.match)630 if (!m.match)
630 break;631 break;
631 while (line_ptr) {632 while (line_ptr) {
632 cur_line = -1;633 cur_line = -1;
633 sscanf(line_ptr, "%u: ", &cur_line);634 sscanf(line_ptr, "%u: ", &cur_line);
635 if (cur_line == -1)
636 sscanf(line_ptr, "from %u to %u: ", &tmp, &cur_line);
634 if (cur_line == m.line)637 if (cur_line == m.line)
635 break;638 break;
636 line_ptr = strtok(NULL, "\n");639 line_ptr = strtok(NULL, "\n");
@@ -642,7 +645,19 @@ static int do_test_single(struct bpf_align_test *test) · 5 unmodified lines
642 printf("%s", bpf_vlog);645 printf("%s", bpf_vlog);
643 break;646 break;
644 }647 }
648 /* Check the next line as well in case the previous line
649 * did not have a corresponding bpf insn. Example:
650 * func#0 @0
651 * 0: R1=ctx(id=0,off=0,imm=0) R10=fp0
652 * 0: (b7) r3 = 2 ; R3_w=inv2
653 */
645 if (!strstr(line_ptr, m.match)) {654 if (!strstr(line_ptr, m.match)) {
655 cur_line = -1;
656 line_ptr = strtok(NULL, "\n");
657 sscanf(line_ptr, "%u: ", &cur_line);
658 }
659 if (cur_line != m.line || !line_ptr ||
660 !strstr(line_ptr, m.match)) {
646 printf("Failed to find match %u: %s\n",661 printf("Failed to find match %u: %s\n",
647 m.line, m.match);662 m.line, m.match);
648 ret = 1;663 ret = 1;
tools/testing/selftests/bpf/prog_tests/bpf_obj_id.c+2−2
@@ -65,8 +65,8 @@ void serial_test_bpf_obj_id(void) · 64 unmodified lines
65 if (CHECK_FAIL(err))65 if (CHECK_FAIL(err))
66 goto done;66 goto done;
67 67
68 prog = bpf_object__find_program_by_title(objs[i],68 prog = bpf_object__find_program_by_name(objs[i],
69 "raw_tp/sys_enter");69 "test_obj_id");
70 if (CHECK_FAIL(!prog))70 if (CHECK_FAIL(!prog))
71 goto done;71 goto done;
72 links[i] = bpf_program__attach(prog);72 links[i] = bpf_program__attach(prog);
tools/testing/selftests/bpf/prog_tests/bpf_tcp_ca.c+3−4
@@ -217,7 +217,7 @@ static bool found; · 216 unmodified lines
217static int libbpf_debug_print(enum libbpf_print_level level,217static int libbpf_debug_print(enum libbpf_print_level level,
218 const char *format, va_list args)218 const char *format, va_list args)
219{219{
220 const char *log_buf;220 const char *prog_name, *log_buf;
221 221
222 if (level != LIBBPF_WARN ||222 if (level != LIBBPF_WARN ||
223 !strstr(format, "-- BEGIN PROG LOAD LOG --")) {223 !strstr(format, "-- BEGIN PROG LOAD LOG --")) {
@@ -225,15 +225,14 @@ static int libbpf_debug_print(enum libbpf_print_level level, · 1 unmodified line
225 return 0;225 return 0;
226 }226 }
227 227
228 /* skip prog_name */228 prog_name = va_arg(args, char *);
229 va_arg(args, char *);
230 log_buf = va_arg(args, char *);229 log_buf = va_arg(args, char *);
231 if (!log_buf)230 if (!log_buf)
232 goto out;231 goto out;
233 if (err_str && strstr(log_buf, err_str) != NULL)232 if (err_str && strstr(log_buf, err_str) != NULL)
234 found = true;233 found = true;
235out:234out:
236 printf(format, log_buf);235 printf(format, prog_name, log_buf);
237 return 0;236 return 0;
238}237}
239 238
tools/testing/selftests/bpf/prog_tests/btf.c+0−1
@@ -22,7 +22,6 @@ · 21 unmodified lines
22#include <bpf/libbpf.h>22#include <bpf/libbpf.h>
23#include <bpf/btf.h>23#include <bpf/btf.h>
24 24
25#include "bpf_rlimit.h"
26#include "bpf_util.h"25#include "bpf_util.h"
27#include "../test_btf.h"26#include "../test_btf.h"
28#include "test_progs.h"27#include "test_progs.h"
tools/testing/selftests/bpf/prog_tests/connect_force_port.c+9−9
@@ -67,9 +67,9 @@ static int run_test(int cgroup_fd, int server_fd, int family, int type) · 66 unmodified lines
67 goto close_bpf_object;67 goto close_bpf_object;
68 }68 }
69 69
70 prog = bpf_object__find_program_by_title(obj, v4 ?70 prog = bpf_object__find_program_by_name(obj, v4 ?
71 "cgroup/connect4" :71 "connect4" :
72 "cgroup/connect6");72 "connect6");
73 if (CHECK(!prog, "find_prog", "connect prog not found\n")) {73 if (CHECK(!prog, "find_prog", "connect prog not found\n")) {
74 err = -EIO;74 err = -EIO;
75 goto close_bpf_object;75 goto close_bpf_object;
@@ -83,9 +83,9 @@ static int run_test(int cgroup_fd, int server_fd, int family, int type) · 7 unmodified lines
83 goto close_bpf_object;83 goto close_bpf_object;
84 }84 }
85 85
86 prog = bpf_object__find_program_by_title(obj, v4 ?86 prog = bpf_object__find_program_by_name(obj, v4 ?
87 "cgroup/getpeername4" :87 "getpeername4" :
88 "cgroup/getpeername6");88 "getpeername6");
89 if (CHECK(!prog, "find_prog", "getpeername prog not found\n")) {89 if (CHECK(!prog, "find_prog", "getpeername prog not found\n")) {
90 err = -EIO;90 err = -EIO;
91 goto close_bpf_object;91 goto close_bpf_object;
@@ -99,9 +99,9 @@ static int run_test(int cgroup_fd, int server_fd, int family, int type) · 7 unmodified lines
99 goto close_bpf_object;99 goto close_bpf_object;
100 }100 }
101 101
102 prog = bpf_object__find_program_by_title(obj, v4 ?102 prog = bpf_object__find_program_by_name(obj, v4 ?
103 "cgroup/getsockname4" :103 "getsockname4" :
104 "cgroup/getsockname6");104 "getsockname6");
105 if (CHECK(!prog, "find_prog", "getsockname prog not found\n")) {105 if (CHECK(!prog, "find_prog", "getsockname prog not found\n")) {
106 err = -EIO;106 err = -EIO;
107 goto close_bpf_object;107 goto close_bpf_object;
tools/testing/selftests/bpf/prog_tests/core_reloc.c+53−26
@@ -10,7 +10,7 @@ static int duration = 0; · 9 unmodified lines
10 10
11#define STRUCT_TO_CHAR_PTR(struct_name) (const char *)&(struct struct_name)11#define STRUCT_TO_CHAR_PTR(struct_name) (const char *)&(struct struct_name)
12 12
13#define MODULES_CASE(name, sec_name, tp_name) { \13#define MODULES_CASE(name, pg_name, tp_name) { \
14 .case_name = name, \14 .case_name = name, \
15 .bpf_obj_file = "test_core_reloc_module.o", \15 .bpf_obj_file = "test_core_reloc_module.o", \
16 .btf_src_file = NULL, /* find in kernel module BTFs */ \16 .btf_src_file = NULL, /* find in kernel module BTFs */ \
@@ -28,7 +28,7 @@ static int duration = 0; · 11 unmodified lines
28 .comm_len = sizeof("test_progs"), \28 .comm_len = sizeof("test_progs"), \
29 }, \29 }, \
30 .output_len = sizeof(struct core_reloc_module_output), \30 .output_len = sizeof(struct core_reloc_module_output), \
31 .prog_sec_name = sec_name, \31 .prog_name = pg_name, \
32 .raw_tp_name = tp_name, \32 .raw_tp_name = tp_name, \
33 .trigger = __trigger_module_test_read, \33 .trigger = __trigger_module_test_read, \
34 .needs_testmod = true, \34 .needs_testmod = true, \
@@ -43,7 +43,9 @@ static int duration = 0; · 8 unmodified lines
43#define FLAVORS_CASE_COMMON(name) \43#define FLAVORS_CASE_COMMON(name) \
44 .case_name = #name, \44 .case_name = #name, \
45 .bpf_obj_file = "test_core_reloc_flavors.o", \45 .bpf_obj_file = "test_core_reloc_flavors.o", \
46 .btf_src_file = "btf__core_reloc_" #name ".o" \46 .btf_src_file = "btf__core_reloc_" #name ".o", \
47 .raw_tp_name = "sys_enter", \
48 .prog_name = "test_core_flavors" \
47 49
48#define FLAVORS_CASE(name) { \50#define FLAVORS_CASE(name) { \
49 FLAVORS_CASE_COMMON(name), \51 FLAVORS_CASE_COMMON(name), \
@@ -66,7 +68,9 @@ static int duration = 0; · 16 unmodified lines
66#define NESTING_CASE_COMMON(name) \68#define NESTING_CASE_COMMON(name) \
67 .case_name = #name, \69 .case_name = #name, \
68 .bpf_obj_file = "test_core_reloc_nesting.o", \70 .bpf_obj_file = "test_core_reloc_nesting.o", \
69 .btf_src_file = "btf__core_reloc_" #name ".o"71 .btf_src_file = "btf__core_reloc_" #name ".o", \
72 .raw_tp_name = "sys_enter", \
73 .prog_name = "test_core_nesting" \
70 74
71#define NESTING_CASE(name) { \75#define NESTING_CASE(name) { \
72 NESTING_CASE_COMMON(name), \76 NESTING_CASE_COMMON(name), \
@@ -91,7 +95,9 @@ static int duration = 0; · 18 unmodified lines
91#define ARRAYS_CASE_COMMON(name) \95#define ARRAYS_CASE_COMMON(name) \
92 .case_name = #name, \96 .case_name = #name, \
93 .bpf_obj_file = "test_core_reloc_arrays.o", \97 .bpf_obj_file = "test_core_reloc_arrays.o", \
94 .btf_src_file = "btf__core_reloc_" #name ".o"98 .btf_src_file = "btf__core_reloc_" #name ".o", \
99 .raw_tp_name = "sys_enter", \
100 .prog_name = "test_core_arrays" \
95 101
96#define ARRAYS_CASE(name) { \102#define ARRAYS_CASE(name) { \
97 ARRAYS_CASE_COMMON(name), \103 ARRAYS_CASE_COMMON(name), \
@@ -123,7 +129,9 @@ static int duration = 0; · 25 unmodified lines
123#define PRIMITIVES_CASE_COMMON(name) \129#define PRIMITIVES_CASE_COMMON(name) \
124 .case_name = #name, \130 .case_name = #name, \
125 .bpf_obj_file = "test_core_reloc_primitives.o", \131 .bpf_obj_file = "test_core_reloc_primitives.o", \
126 .btf_src_file = "btf__core_reloc_" #name ".o"132 .btf_src_file = "btf__core_reloc_" #name ".o", \
133 .raw_tp_name = "sys_enter", \
134 .prog_name = "test_core_primitives" \
127 135
128#define PRIMITIVES_CASE(name) { \136#define PRIMITIVES_CASE(name) { \
129 PRIMITIVES_CASE_COMMON(name), \137 PRIMITIVES_CASE_COMMON(name), \
@@ -158,6 +166,8 @@ static int duration = 0; · 28 unmodified lines
158 .e = 5, .f = 6, .g = 7, .h = 8, \166 .e = 5, .f = 6, .g = 7, .h = 8, \
159 }, \167 }, \
160 .output_len = sizeof(struct core_reloc_mods_output), \168 .output_len = sizeof(struct core_reloc_mods_output), \
169 .raw_tp_name = "sys_enter", \
170 .prog_name = "test_core_mods", \
161}171}
162 172
163#define PTR_AS_ARR_CASE(name) { \173#define PTR_AS_ARR_CASE(name) { \
@@ -174,6 +184,8 @@ static int duration = 0; · 10 unmodified lines
174 .a = 3, \184 .a = 3, \
175 }, \185 }, \
176 .output_len = sizeof(struct core_reloc_ptr_as_arr), \186 .output_len = sizeof(struct core_reloc_ptr_as_arr), \
187 .raw_tp_name = "sys_enter", \
188 .prog_name = "test_core_ptr_as_arr", \
177}189}
178 190
179#define INTS_DATA(struct_name) STRUCT_TO_CHAR_PTR(struct_name) { \191#define INTS_DATA(struct_name) STRUCT_TO_CHAR_PTR(struct_name) { \
@@ -190,7 +202,9 @@ static int duration = 0; · 10 unmodified lines
190#define INTS_CASE_COMMON(name) \202#define INTS_CASE_COMMON(name) \
191 .case_name = #name, \203 .case_name = #name, \
192 .bpf_obj_file = "test_core_reloc_ints.o", \204 .bpf_obj_file = "test_core_reloc_ints.o", \
193 .btf_src_file = "btf__core_reloc_" #name ".o"205 .btf_src_file = "btf__core_reloc_" #name ".o", \
206 .raw_tp_name = "sys_enter", \
207 .prog_name = "test_core_ints"
194 208
195#define INTS_CASE(name) { \209#define INTS_CASE(name) { \
196 INTS_CASE_COMMON(name), \210 INTS_CASE_COMMON(name), \
@@ -208,7 +222,9 @@ static int duration = 0; · 11 unmodified lines
208#define FIELD_EXISTS_CASE_COMMON(name) \222#define FIELD_EXISTS_CASE_COMMON(name) \
209 .case_name = #name, \223 .case_name = #name, \
210 .bpf_obj_file = "test_core_reloc_existence.o", \224 .bpf_obj_file = "test_core_reloc_existence.o", \
211 .btf_src_file = "btf__core_reloc_" #name ".o" \225 .btf_src_file = "btf__core_reloc_" #name ".o", \
226 .raw_tp_name = "sys_enter", \
227 .prog_name = "test_core_existence"
212 228
213#define BITFIELDS_CASE_COMMON(objfile, test_name_prefix, name) \229#define BITFIELDS_CASE_COMMON(objfile, test_name_prefix, name) \
214 .case_name = test_name_prefix#name, \230 .case_name = test_name_prefix#name, \
@@ -223,6 +239,8 @@ static int duration = 0; · 8 unmodified lines
223 .output = STRUCT_TO_CHAR_PTR(core_reloc_bitfields_output) \239 .output = STRUCT_TO_CHAR_PTR(core_reloc_bitfields_output) \
224 __VA_ARGS__, \240 __VA_ARGS__, \
225 .output_len = sizeof(struct core_reloc_bitfields_output), \241 .output_len = sizeof(struct core_reloc_bitfields_output), \
242 .raw_tp_name = "sys_enter", \
243 .prog_name = "test_core_bitfields", \
226}, { \244}, { \
227 BITFIELDS_CASE_COMMON("test_core_reloc_bitfields_direct.o", \245 BITFIELDS_CASE_COMMON("test_core_reloc_bitfields_direct.o", \
228 "direct:", name), \246 "direct:", name), \
@@ -231,7 +249,7 @@ static int duration = 0; · 2 unmodified lines
231 .output = STRUCT_TO_CHAR_PTR(core_reloc_bitfields_output) \249 .output = STRUCT_TO_CHAR_PTR(core_reloc_bitfields_output) \
232 __VA_ARGS__, \250 __VA_ARGS__, \
233 .output_len = sizeof(struct core_reloc_bitfields_output), \251 .output_len = sizeof(struct core_reloc_bitfields_output), \
234 .prog_sec_name = "tp_btf/sys_enter", \252 .prog_name = "test_core_bitfields_direct", \
235}253}
236 254
237 255
@@ -239,17 +257,21 @@ static int duration = 0; · 1 unmodified line
239 BITFIELDS_CASE_COMMON("test_core_reloc_bitfields_probed.o", \257 BITFIELDS_CASE_COMMON("test_core_reloc_bitfields_probed.o", \
240 "probed:", name), \258 "probed:", name), \
241 .fails = true, \259 .fails = true, \
260 .raw_tp_name = "sys_enter", \
261 .prog_name = "test_core_bitfields", \
242}, { \262}, { \
243 BITFIELDS_CASE_COMMON("test_core_reloc_bitfields_direct.o", \263 BITFIELDS_CASE_COMMON("test_core_reloc_bitfields_direct.o", \
244 "direct:", name), \264 "direct:", name), \
245 .prog_sec_name = "tp_btf/sys_enter", \
246 .fails = true, \265 .fails = true, \
266 .prog_name = "test_core_bitfields_direct", \
247}267}
248 268
249#define SIZE_CASE_COMMON(name) \269#define SIZE_CASE_COMMON(name) \
250 .case_name = #name, \270 .case_name = #name, \
251 .bpf_obj_file = "test_core_reloc_size.o", \271 .bpf_obj_file = "test_core_reloc_size.o", \
252 .btf_src_file = "btf__core_reloc_" #name ".o"272 .btf_src_file = "btf__core_reloc_" #name ".o", \
273 .raw_tp_name = "sys_enter", \
274 .prog_name = "test_core_size"
253 275
254#define SIZE_OUTPUT_DATA(type) \276#define SIZE_OUTPUT_DATA(type) \
255 STRUCT_TO_CHAR_PTR(core_reloc_size_output) { \277 STRUCT_TO_CHAR_PTR(core_reloc_size_output) { \
@@ -277,8 +299,10 @@ static int duration = 0; · 21 unmodified lines
277 299
278#define TYPE_BASED_CASE_COMMON(name) \300#define TYPE_BASED_CASE_COMMON(name) \
279 .case_name = #name, \301 .case_name = #name, \
280 .bpf_obj_file = "test_core_reloc_type_based.o", \302 .bpf_obj_file = "test_core_reloc_type_based.o", \
281 .btf_src_file = "btf__core_reloc_" #name ".o" \303 .btf_src_file = "btf__core_reloc_" #name ".o", \
304 .raw_tp_name = "sys_enter", \
305 .prog_name = "test_core_type_based"
282 306
283#define TYPE_BASED_CASE(name, ...) { \307#define TYPE_BASED_CASE(name, ...) { \
284 TYPE_BASED_CASE_COMMON(name), \308 TYPE_BASED_CASE_COMMON(name), \
@@ -295,7 +319,9 @@ static int duration = 0; · 10 unmodified lines
295#define TYPE_ID_CASE_COMMON(name) \319#define TYPE_ID_CASE_COMMON(name) \
296 .case_name = #name, \320 .case_name = #name, \
297 .bpf_obj_file = "test_core_reloc_type_id.o", \321 .bpf_obj_file = "test_core_reloc_type_id.o", \
298 .btf_src_file = "btf__core_reloc_" #name ".o" \322 .btf_src_file = "btf__core_reloc_" #name ".o", \
323 .raw_tp_name = "sys_enter", \
324 .prog_name = "test_core_type_id"
299 325
300#define TYPE_ID_CASE(name, setup_fn) { \326#define TYPE_ID_CASE(name, setup_fn) { \
301 TYPE_ID_CASE_COMMON(name), \327 TYPE_ID_CASE_COMMON(name), \
@@ -312,7 +338,9 @@ static int duration = 0; · 10 unmodified lines
312#define ENUMVAL_CASE_COMMON(name) \338#define ENUMVAL_CASE_COMMON(name) \
313 .case_name = #name, \339 .case_name = #name, \
314 .bpf_obj_file = "test_core_reloc_enumval.o", \340 .bpf_obj_file = "test_core_reloc_enumval.o", \
315 .btf_src_file = "btf__core_reloc_" #name ".o" \341 .btf_src_file = "btf__core_reloc_" #name ".o", \
342 .raw_tp_name = "sys_enter", \
343 .prog_name = "test_core_enumval"
316 344
317#define ENUMVAL_CASE(name, ...) { \345#define ENUMVAL_CASE(name, ...) { \
318 ENUMVAL_CASE_COMMON(name), \346 ENUMVAL_CASE_COMMON(name), \
@@ -342,7 +370,7 @@ struct core_reloc_test_case { · 23 unmodified lines
342 bool fails;370 bool fails;
343 bool needs_testmod;371 bool needs_testmod;
344 bool relaxed_core_relocs;372 bool relaxed_core_relocs;
345 const char *prog_sec_name;373 const char *prog_name;
346 const char *raw_tp_name;374 const char *raw_tp_name;
347 setup_test_fn setup;375 setup_test_fn setup;
348 trigger_test_fn trigger;376 trigger_test_fn trigger;
@@ -497,11 +525,13 @@ static struct core_reloc_test_case test_cases[] = { · 148 unmodified lines
497 .comm_len = sizeof("test_progs"),525 .comm_len = sizeof("test_progs"),
498 },526 },
499 .output_len = sizeof(struct core_reloc_kernel_output),527 .output_len = sizeof(struct core_reloc_kernel_output),
528 .raw_tp_name = "sys_enter",
529 .prog_name = "test_core_kernel",
500 },530 },
501 531
502 /* validate we can find kernel module BTF types for relocs/attach */532 /* validate we can find kernel module BTF types for relocs/attach */
503 MODULES_CASE("module_probed", "raw_tp/bpf_testmod_test_read", "bpf_testmod_test_read"),533 MODULES_CASE("module_probed", "test_core_module_probed", "bpf_testmod_test_read"),
504 MODULES_CASE("module_direct", "tp_btf/bpf_testmod_test_read", NULL),534 MODULES_CASE("module_direct", "test_core_module_direct", NULL),
505 535
506 /* validate BPF program can use multiple flavors to match against536 /* validate BPF program can use multiple flavors to match against
507 * single target BTF type537 * single target BTF type
@@ -580,6 +610,8 @@ static struct core_reloc_test_case test_cases[] = { · 72 unmodified lines
580 .c = 0, /* BUG in clang, should be 3 */610 .c = 0, /* BUG in clang, should be 3 */
581 },611 },
582 .output_len = sizeof(struct core_reloc_misc_output),612 .output_len = sizeof(struct core_reloc_misc_output),
613 .raw_tp_name = "sys_enter",
614 .prog_name = "test_core_misc",
583 },615 },
584 616
585 /* validate field existence checks */617 /* validate field existence checks */
@@ -848,14 +880,9 @@ void test_core_reloc(void) · 262 unmodified lines
848 if (!ASSERT_OK_PTR(obj, "obj_open"))880 if (!ASSERT_OK_PTR(obj, "obj_open"))
849 goto cleanup;881 goto cleanup;
850 882
851 probe_name = "raw_tracepoint/sys_enter";883 probe_name = test_case->prog_name;
852 tp_name = "sys_enter";884 tp_name = test_case->raw_tp_name; /* NULL for tp_btf */
853 if (test_case->prog_sec_name) {885 prog = bpf_object__find_program_by_name(obj, probe_name);
854 probe_name = test_case->prog_sec_name;
855 tp_name = test_case->raw_tp_name; /* NULL for tp_btf */
856 }
857
858 prog = bpf_object__find_program_by_title(obj, probe_name);
859 if (CHECK(!prog, "find_probe",886 if (CHECK(!prog, "find_probe",
860 "prog '%s' not found\n", probe_name))887 "prog '%s' not found\n", probe_name))
861 goto cleanup;888 goto cleanup;
tools/testing/selftests/bpf/prog_tests/fexit_bpf2bpf.c+13−4
@@ -101,6 +101,8 @@ static void test_fexit_bpf2bpf_common(const char *obj_file, · 100 unmodified lines
101 101
102 for (i = 0; i < prog_cnt; i++) {102 for (i = 0; i < prog_cnt; i++) {
103 struct bpf_link_info link_info;103 struct bpf_link_info link_info;
104 struct bpf_program *pos;
105 const char *pos_sec_name;
104 char *tgt_name;106 char *tgt_name;
105 __s32 btf_id;107 __s32 btf_id;
106 108
@@ -109,7 +111,14 @@ static void test_fexit_bpf2bpf_common(const char *obj_file, · 2 unmodified lines
109 goto close_prog;111 goto close_prog;
110 btf_id = btf__find_by_name_kind(btf, tgt_name + 1, BTF_KIND_FUNC);112 btf_id = btf__find_by_name_kind(btf, tgt_name + 1, BTF_KIND_FUNC);
111 113
112 prog[i] = bpf_object__find_program_by_title(obj, prog_name[i]);114 prog[i] = NULL;
115 bpf_object__for_each_program(pos, obj) {
116 pos_sec_name = bpf_program__section_name(pos);
117 if (pos_sec_name && !strcmp(pos_sec_name, prog_name[i])) {
118 prog[i] = pos;
119 break;
120 }
121 }
113 if (!ASSERT_OK_PTR(prog[i], prog_name[i]))122 if (!ASSERT_OK_PTR(prog[i], prog_name[i]))
114 goto close_prog;123 goto close_prog;
115 124
@@ -211,8 +220,8 @@ static void test_func_replace_verify(void) · 95 unmodified lines
211 220
212static int test_second_attach(struct bpf_object *obj)221static int test_second_attach(struct bpf_object *obj)
213{222{
214 const char *prog_name = "freplace/get_constant";223 const char *prog_name = "security_new_get_constant";
215 const char *tgt_name = prog_name + 9; /* cut off freplace/ */224 const char *tgt_name = "get_constant";
216 const char *tgt_obj_file = "./test_pkt_access.o";225 const char *tgt_obj_file = "./test_pkt_access.o";
217 struct bpf_program *prog = NULL;226 struct bpf_program *prog = NULL;
218 struct bpf_object *tgt_obj;227 struct bpf_object *tgt_obj;
@@ -220,7 +229,7 @@ static int test_second_attach(struct bpf_object *obj) · 1 unmodified line
220 struct bpf_link *link;229 struct bpf_link *link;
221 int err = 0, tgt_fd;230 int err = 0, tgt_fd;
222 231
223 prog = bpf_object__find_program_by_title(obj, prog_name);232 prog = bpf_object__find_program_by_name(obj, prog_name);
224 if (CHECK(!prog, "find_prog", "prog %s not found\n", prog_name))233 if (CHECK(!prog, "find_prog", "prog %s not found\n", prog_name))
225 return -ENOENT;234 return -ENOENT;
226 235
tools/testing/selftests/bpf/prog_tests/get_func_args_test.c+44−0
@@ -0,0 +1,44 @@
1// SPDX-License-Identifier: GPL-2.0
2#include <test_progs.h>
3#include "get_func_args_test.skel.h"
4
5void test_get_func_args_test(void)
6{
7 struct get_func_args_test *skel = NULL;
8 __u32 duration = 0, retval;
9 int err, prog_fd;
10
11 skel = get_func_args_test__open_and_load();
12 if (!ASSERT_OK_PTR(skel, "get_func_args_test__open_and_load"))
13 return;
14
15 err = get_func_args_test__attach(skel);
16 if (!ASSERT_OK(err, "get_func_args_test__attach"))
17 goto cleanup;
18
19 /* This runs bpf_fentry_test* functions and triggers
20 * fentry/fexit programs.
21 */
22 prog_fd = bpf_program__fd(skel->progs.test1);
23 err = bpf_prog_test_run(prog_fd, 1, NULL, 0,
24 NULL, NULL, &retval, &duration);
25 ASSERT_OK(err, "test_run");
26 ASSERT_EQ(retval, 0, "test_run");
27
28 /* This runs bpf_modify_return_test function and triggers
29 * fmod_ret_test and fexit_test programs.
30 */
31 prog_fd = bpf_program__fd(skel->progs.fmod_ret_test);
32 err = bpf_prog_test_run(prog_fd, 1, NULL, 0,
33 NULL, NULL, &retval, &duration);
34 ASSERT_OK(err, "test_run");
35 ASSERT_EQ(retval, 1234, "test_run");
36
37 ASSERT_EQ(skel->bss->test1_result, 1, "test1_result");
38 ASSERT_EQ(skel->bss->test2_result, 1, "test2_result");
39 ASSERT_EQ(skel->bss->test3_result, 1, "test3_result");
40 ASSERT_EQ(skel->bss->test4_result, 1, "test4_result");
41
42cleanup:
43 get_func_args_test__destroy(skel);
44}
tools/testing/selftests/bpf/prog_tests/get_stack_raw_tp.c+2−2
@@ -89,7 +89,7 @@ void test_get_stack_raw_tp(void) · 88 unmodified lines
89{89{
90 const char *file = "./test_get_stack_rawtp.o";90 const char *file = "./test_get_stack_rawtp.o";
91 const char *file_err = "./test_get_stack_rawtp_err.o";91 const char *file_err = "./test_get_stack_rawtp_err.o";
92 const char *prog_name = "raw_tracepoint/sys_enter";92 const char *prog_name = "bpf_prog1";
93 int i, err, prog_fd, exp_cnt = MAX_CNT_RAWTP;93 int i, err, prog_fd, exp_cnt = MAX_CNT_RAWTP;
94 struct perf_buffer *pb = NULL;94 struct perf_buffer *pb = NULL;
95 struct bpf_link *link = NULL;95 struct bpf_link *link = NULL;
@@ -107,7 +107,7 @@ void test_get_stack_raw_tp(void) · 11 unmodified lines
107 if (CHECK(err, "prog_load raw tp", "err %d errno %d\n", err, errno))107 if (CHECK(err, "prog_load raw tp", "err %d errno %d\n", err, errno))
108 return;108 return;
109 109
110 prog = bpf_object__find_program_by_title(obj, prog_name);110 prog = bpf_object__find_program_by_name(obj, prog_name);
111 if (CHECK(!prog, "find_probe", "prog '%s' not found\n", prog_name))111 if (CHECK(!prog, "find_probe", "prog '%s' not found\n", prog_name))
112 goto close_prog;112 goto close_prog;
113 113
tools/testing/selftests/bpf/prog_tests/ksyms_btf.c+14−0
@@ -8,6 +8,7 @@ · 7 unmodified lines
8#include "test_ksyms_btf_null_check.skel.h"8#include "test_ksyms_btf_null_check.skel.h"
9#include "test_ksyms_weak.skel.h"9#include "test_ksyms_weak.skel.h"
10#include "test_ksyms_weak.lskel.h"10#include "test_ksyms_weak.lskel.h"
11#include "test_ksyms_btf_write_check.skel.h"
11 12
12static int duration;13static int duration;
13 14
@@ -137,6 +138,16 @@ cleanup: · 123 unmodified lines
137 test_ksyms_weak_lskel__destroy(skel);138 test_ksyms_weak_lskel__destroy(skel);
138}139}
139 140
141static void test_write_check(void)
142{
143 struct test_ksyms_btf_write_check *skel;
144
145 skel = test_ksyms_btf_write_check__open_and_load();
146 ASSERT_ERR_PTR(skel, "unexpected load of a prog writing to ksym memory\n");
147
148 test_ksyms_btf_write_check__destroy(skel);
149}
150
140void test_ksyms_btf(void)151void test_ksyms_btf(void)
141{152{
142 int percpu_datasec;153 int percpu_datasec;
@@ -167,4 +178,7 @@ void test_ksyms_btf(void) · 24 unmodified lines
167 178
168 if (test__start_subtest("weak_ksyms_lskel"))179 if (test__start_subtest("weak_ksyms_lskel"))
169 test_weak_syms_lskel();180 test_weak_syms_lskel();
181
182 if (test__start_subtest("write_check"))
183 test_write_check();
170}184}
tools/testing/selftests/bpf/prog_tests/libbpf_probes.c+124−0
@@ -0,0 +1,124 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2/* Copyright (c) 2021 Facebook */
3
4#include <test_progs.h>
5#include <bpf/btf.h>
6
7void test_libbpf_probe_prog_types(void)
8{
9 struct btf *btf;
10 const struct btf_type *t;
11 const struct btf_enum *e;
12 int i, n, id;
13
14 btf = btf__parse("/sys/kernel/btf/vmlinux", NULL);
15 if (!ASSERT_OK_PTR(btf, "btf_parse"))
16 return;
17
18 /* find enum bpf_prog_type and enumerate each value */
19 id = btf__find_by_name_kind(btf, "bpf_prog_type", BTF_KIND_ENUM);
20 if (!ASSERT_GT(id, 0, "bpf_prog_type_id"))
21 goto cleanup;
22 t = btf__type_by_id(btf, id);
23 if (!ASSERT_OK_PTR(t, "bpf_prog_type_enum"))
24 goto cleanup;
25
26 for (e = btf_enum(t), i = 0, n = btf_vlen(t); i < n; e++, i++) {
27 const char *prog_type_name = btf__str_by_offset(btf, e->name_off);
28 enum bpf_prog_type prog_type = (enum bpf_prog_type)e->val;
29 int res;
30
31 if (prog_type == BPF_PROG_TYPE_UNSPEC)
32 continue;
33
34 if (!test__start_subtest(prog_type_name))
35 continue;
36
37 res = libbpf_probe_bpf_prog_type(prog_type, NULL);
38 ASSERT_EQ(res, 1, prog_type_name);
39 }
40
41cleanup:
42 btf__free(btf);
43}
44
45void test_libbpf_probe_map_types(void)
46{
47 struct btf *btf;
48 const struct btf_type *t;
49 const struct btf_enum *e;
50 int i, n, id;
51
52 btf = btf__parse("/sys/kernel/btf/vmlinux", NULL);
53 if (!ASSERT_OK_PTR(btf, "btf_parse"))
54 return;
55
56 /* find enum bpf_map_type and enumerate each value */
57 id = btf__find_by_name_kind(btf, "bpf_map_type", BTF_KIND_ENUM);
58 if (!ASSERT_GT(id, 0, "bpf_map_type_id"))
59 goto cleanup;
60 t = btf__type_by_id(btf, id);
61 if (!ASSERT_OK_PTR(t, "bpf_map_type_enum"))
62 goto cleanup;
63
64 for (e = btf_enum(t), i = 0, n = btf_vlen(t); i < n; e++, i++) {
65 const char *map_type_name = btf__str_by_offset(btf, e->name_off);
66 enum bpf_map_type map_type = (enum bpf_map_type)e->val;
67 int res;
68
69 if (map_type == BPF_MAP_TYPE_UNSPEC)
70 continue;
71
72 if (!test__start_subtest(map_type_name))
73 continue;
74
75 res = libbpf_probe_bpf_map_type(map_type, NULL);
76 ASSERT_EQ(res, 1, map_type_name);
77 }
78
79cleanup:
80 btf__free(btf);
81}
82
83void test_libbpf_probe_helpers(void)
84{
85#define CASE(prog, helper, supp) { \
86 .prog_type_name = "BPF_PROG_TYPE_" # prog, \
87 .helper_name = "bpf_" # helper, \
88 .prog_type = BPF_PROG_TYPE_ ## prog, \
89 .helper_id = BPF_FUNC_ ## helper, \
90 .supported = supp, \
91}
92 const struct case_def {
93 const char *prog_type_name;
94 const char *helper_name;
95 enum bpf_prog_type prog_type;
96 enum bpf_func_id helper_id;
97 bool supported;
98 } cases[] = {
99 CASE(KPROBE, unspec, false),
100 CASE(KPROBE, map_lookup_elem, true),
101 CASE(KPROBE, loop, true),
102
103 CASE(KPROBE, ktime_get_coarse_ns, false),
104 CASE(SOCKET_FILTER, ktime_get_coarse_ns, true),
105
106 CASE(KPROBE, sys_bpf, false),
107 CASE(SYSCALL, sys_bpf, true),
108 };
109 size_t case_cnt = ARRAY_SIZE(cases), i;
110 char buf[128];
111
112 for (i = 0; i < case_cnt; i++) {
113 const struct case_def *d = &cases[i];
114 int res;
115
116 snprintf(buf, sizeof(buf), "%s+%s", d->prog_type_name, d->helper_name);
117
118 if (!test__start_subtest(buf))
119 continue;
120
121 res = libbpf_probe_bpf_helper(d->prog_type, d->helper_id, NULL);
122 ASSERT_EQ(res, d->supported, buf);
123 }
124}
tools/testing/selftests/bpf/prog_tests/select_reuseport.c+0−1
@@ -18,7 +18,6 @@ · 17 unmodified lines
18#include <netinet/in.h>18#include <netinet/in.h>
19#include <bpf/bpf.h>19#include <bpf/bpf.h>
20#include <bpf/libbpf.h>20#include <bpf/libbpf.h>
21#include "bpf_rlimit.h"
22#include "bpf_util.h"21#include "bpf_util.h"
23 22
24#include "test_progs.h"23#include "test_progs.h"
tools/testing/selftests/bpf/prog_tests/sk_lookup.c+0−1
@@ -30,7 +30,6 @@ · 29 unmodified lines
30#include <bpf/bpf.h>30#include <bpf/bpf.h>
31 31
32#include "test_progs.h"32#include "test_progs.h"
33#include "bpf_rlimit.h"
34#include "bpf_util.h"33#include "bpf_util.h"
35#include "cgroup_helpers.h"34#include "cgroup_helpers.h"
36#include "network_helpers.h"35#include "network_helpers.h"
tools/testing/selftests/bpf/prog_tests/sock_fields.c+0−1
@@ -15,7 +15,6 @@ · 14 unmodified lines
15#include "network_helpers.h"15#include "network_helpers.h"
16#include "cgroup_helpers.h"16#include "cgroup_helpers.h"
17#include "test_progs.h"17#include "test_progs.h"
18#include "bpf_rlimit.h"
19#include "test_sock_fields.skel.h"18#include "test_sock_fields.skel.h"
20 19
21enum bpf_linum_array_idx {20enum bpf_linum_array_idx {
tools/testing/selftests/bpf/prog_tests/sockopt_inherit.c+8−7
@@ -136,7 +136,8 @@ static int start_server(void) · 135 unmodified lines
136 return fd;136 return fd;
137}137}
138 138
139static int prog_attach(struct bpf_object *obj, int cgroup_fd, const char *title)139static int prog_attach(struct bpf_object *obj, int cgroup_fd, const char *title,
140 const char *prog_name)
140{141{
141 enum bpf_attach_type attach_type;142 enum bpf_attach_type attach_type;
142 enum bpf_prog_type prog_type;143 enum bpf_prog_type prog_type;
@@ -145,20 +146,20 @@ static int prog_attach(struct bpf_object *obj, int cgroup_fd, const char *title) · 2 unmodified lines
145 146
146 err = libbpf_prog_type_by_name(title, &prog_type, &attach_type);147 err = libbpf_prog_type_by_name(title, &prog_type, &attach_type);
147 if (err) {148 if (err) {
148 log_err("Failed to deduct types for %s BPF program", title);149 log_err("Failed to deduct types for %s BPF program", prog_name);
149 return -1;150 return -1;
150 }151 }
151 152
152 prog = bpf_object__find_program_by_title(obj, title);153 prog = bpf_object__find_program_by_name(obj, prog_name);
153 if (!prog) {154 if (!prog) {
154 log_err("Failed to find %s BPF program", title);155 log_err("Failed to find %s BPF program", prog_name);
155 return -1;156 return -1;
156 }157 }
157 158
158 err = bpf_prog_attach(bpf_program__fd(prog), cgroup_fd,159 err = bpf_prog_attach(bpf_program__fd(prog), cgroup_fd,
159 attach_type, 0);160 attach_type, 0);
160 if (err) {161 if (err) {
161 log_err("Failed to attach %s BPF program", title);162 log_err("Failed to attach %s BPF program", prog_name);
162 return -1;163 return -1;
163 }164 }
164 165
@@ -181,11 +182,11 @@ static void run_test(int cgroup_fd) · 16 unmodified lines
181 if (!ASSERT_OK(err, "obj_load"))182 if (!ASSERT_OK(err, "obj_load"))
182 goto close_bpf_object;183 goto close_bpf_object;
183 184
184 err = prog_attach(obj, cgroup_fd, "cgroup/getsockopt");185 err = prog_attach(obj, cgroup_fd, "cgroup/getsockopt", "_getsockopt");
185 if (CHECK_FAIL(err))186 if (CHECK_FAIL(err))
186 goto close_bpf_object;187 goto close_bpf_object;
187 188
188 err = prog_attach(obj, cgroup_fd, "cgroup/setsockopt");189 err = prog_attach(obj, cgroup_fd, "cgroup/setsockopt", "_setsockopt");
189 if (CHECK_FAIL(err))190 if (CHECK_FAIL(err))
190 goto close_bpf_object;191 goto close_bpf_object;
191 192
tools/testing/selftests/bpf/prog_tests/stacktrace_map.c+2−2
@@ -4,7 +4,7 @@ · 3 unmodified lines
4void test_stacktrace_map(void)4void test_stacktrace_map(void)
5{5{
6 int control_map_fd, stackid_hmap_fd, stackmap_fd, stack_amap_fd;6 int control_map_fd, stackid_hmap_fd, stackmap_fd, stack_amap_fd;
7 const char *prog_name = "tracepoint/sched/sched_switch";7 const char *prog_name = "oncpu";
8 int err, prog_fd, stack_trace_len;8 int err, prog_fd, stack_trace_len;
9 const char *file = "./test_stacktrace_map.o";9 const char *file = "./test_stacktrace_map.o";
10 __u32 key, val, duration = 0;10 __u32 key, val, duration = 0;
@@ -16,7 +16,7 @@ void test_stacktrace_map(void) · 5 unmodified lines
16 if (CHECK(err, "prog_load", "err %d errno %d\n", err, errno))16 if (CHECK(err, "prog_load", "err %d errno %d\n", err, errno))
17 return;17 return;
18 18
19 prog = bpf_object__find_program_by_title(obj, prog_name);19 prog = bpf_object__find_program_by_name(obj, prog_name);
20 if (CHECK(!prog, "find_prog", "prog '%s' not found\n", prog_name))20 if (CHECK(!prog, "find_prog", "prog '%s' not found\n", prog_name))
21 goto close_prog;21 goto close_prog;
22 22
tools/testing/selftests/bpf/prog_tests/stacktrace_map_raw_tp.c+2−2
@@ -3,7 +3,7 @@ · 2 unmodified lines
3 3
4void test_stacktrace_map_raw_tp(void)4void test_stacktrace_map_raw_tp(void)
5{5{
6 const char *prog_name = "tracepoint/sched/sched_switch";6 const char *prog_name = "oncpu";
7 int control_map_fd, stackid_hmap_fd, stackmap_fd;7 int control_map_fd, stackid_hmap_fd, stackmap_fd;
8 const char *file = "./test_stacktrace_map.o";8 const char *file = "./test_stacktrace_map.o";
9 __u32 key, val, duration = 0;9 __u32 key, val, duration = 0;
@@ -16,7 +16,7 @@ void test_stacktrace_map_raw_tp(void) · 6 unmodified lines
16 if (CHECK(err, "prog_load raw tp", "err %d errno %d\n", err, errno))16 if (CHECK(err, "prog_load raw tp", "err %d errno %d\n", err, errno))
17 return;17 return;
18 18
19 prog = bpf_object__find_program_by_title(obj, prog_name);19 prog = bpf_object__find_program_by_name(obj, prog_name);
20 if (CHECK(!prog, "find_prog", "prog '%s' not found\n", prog_name))20 if (CHECK(!prog, "find_prog", "prog '%s' not found\n", prog_name))
21 goto close_prog;21 goto close_prog;
22 22
tools/testing/selftests/bpf/prog_tests/test_local_storage.c+6−14
@@ -28,10 +28,6 @@ static unsigned int duration; · 27 unmodified lines
28struct storage {28struct storage {
29 void *inode;29 void *inode;
30 unsigned int value;30 unsigned int value;
31 /* Lock ensures that spin locked versions of local stoage operations
32 * also work, most operations in this tests are still single threaded
33 */
34 struct bpf_spin_lock lock;
35};31};
36 32
37/* Fork and exec the provided rm binary and return the exit code of the33/* Fork and exec the provided rm binary and return the exit code of the
@@ -66,27 +62,24 @@ static int run_self_unlink(int *monitored_pid, const char *rm_path) · 28 unmodified lines
66 62
67static bool check_syscall_operations(int map_fd, int obj_fd)63static bool check_syscall_operations(int map_fd, int obj_fd)
68{64{
69 struct storage val = { .value = TEST_STORAGE_VALUE, .lock = { 0 } },65 struct storage val = { .value = TEST_STORAGE_VALUE },
70 lookup_val = { .value = 0, .lock = { 0 } };66 lookup_val = { .value = 0 };
71 int err;67 int err;
72 68
73 /* Looking up an existing element should fail initially */69 /* Looking up an existing element should fail initially */
74 err = bpf_map_lookup_elem_flags(map_fd, &obj_fd, &lookup_val,70 err = bpf_map_lookup_elem_flags(map_fd, &obj_fd, &lookup_val, 0);
75 BPF_F_LOCK);
76 if (CHECK(!err || errno != ENOENT, "bpf_map_lookup_elem",71 if (CHECK(!err || errno != ENOENT, "bpf_map_lookup_elem",
77 "err:%d errno:%d\n", err, errno))72 "err:%d errno:%d\n", err, errno))
78 return false;73 return false;
79 74
80 /* Create a new element */75 /* Create a new element */
81 err = bpf_map_update_elem(map_fd, &obj_fd, &val,76 err = bpf_map_update_elem(map_fd, &obj_fd, &val, BPF_NOEXIST);
82 BPF_NOEXIST | BPF_F_LOCK);
83 if (CHECK(err < 0, "bpf_map_update_elem", "err:%d errno:%d\n", err,77 if (CHECK(err < 0, "bpf_map_update_elem", "err:%d errno:%d\n", err,
84 errno))78 errno))
85 return false;79 return false;
86 80
87 /* Lookup the newly created element */81 /* Lookup the newly created element */
88 err = bpf_map_lookup_elem_flags(map_fd, &obj_fd, &lookup_val,82 err = bpf_map_lookup_elem_flags(map_fd, &obj_fd, &lookup_val, 0);
89 BPF_F_LOCK);
90 if (CHECK(err < 0, "bpf_map_lookup_elem", "err:%d errno:%d", err,83 if (CHECK(err < 0, "bpf_map_lookup_elem", "err:%d errno:%d", err,
91 errno))84 errno))
92 return false;85 return false;
@@ -102,8 +95,7 @@ static bool check_syscall_operations(int map_fd, int obj_fd) · 9 unmodified lines
102 return false;95 return false;
103 96
104 /* The lookup should fail, now that the element has been deleted */97 /* The lookup should fail, now that the element has been deleted */
105 err = bpf_map_lookup_elem_flags(map_fd, &obj_fd, &lookup_val,98 err = bpf_map_lookup_elem_flags(map_fd, &obj_fd, &lookup_val, 0);
106 BPF_F_LOCK);
107 if (CHECK(!err || errno != ENOENT, "bpf_map_lookup_elem",99 if (CHECK(!err || errno != ENOENT, "bpf_map_lookup_elem",
108 "err:%d errno:%d\n", err, errno))100 "err:%d errno:%d\n", err, errno))
109 return false;101 return false;
tools/testing/selftests/bpf/prog_tests/test_overhead.c+10−10
@@ -56,11 +56,11 @@ static void setaffinity(void) · 55 unmodified lines
56 56
57void test_test_overhead(void)57void test_test_overhead(void)
58{58{
59 const char *kprobe_name = "kprobe/__set_task_comm";59 const char *kprobe_name = "prog1";
60 const char *kretprobe_name = "kretprobe/__set_task_comm";60 const char *kretprobe_name = "prog2";
61 const char *raw_tp_name = "raw_tp/task_rename";61 const char *raw_tp_name = "prog3";
62 const char *fentry_name = "fentry/__set_task_comm";62 const char *fentry_name = "prog4";
63 const char *fexit_name = "fexit/__set_task_comm";63 const char *fexit_name = "prog5";
64 const char *kprobe_func = "__set_task_comm";64 const char *kprobe_func = "__set_task_comm";
65 struct bpf_program *kprobe_prog, *kretprobe_prog, *raw_tp_prog;65 struct bpf_program *kprobe_prog, *kretprobe_prog, *raw_tp_prog;
66 struct bpf_program *fentry_prog, *fexit_prog;66 struct bpf_program *fentry_prog, *fexit_prog;
@@ -76,23 +76,23 @@ void test_test_overhead(void) · 9 unmodified lines
76 if (!ASSERT_OK_PTR(obj, "obj_open_file"))76 if (!ASSERT_OK_PTR(obj, "obj_open_file"))
77 return;77 return;
78 78
79 kprobe_prog = bpf_object__find_program_by_title(obj, kprobe_name);79 kprobe_prog = bpf_object__find_program_by_name(obj, kprobe_name);
80 if (CHECK(!kprobe_prog, "find_probe",80 if (CHECK(!kprobe_prog, "find_probe",
81 "prog '%s' not found\n", kprobe_name))81 "prog '%s' not found\n", kprobe_name))
82 goto cleanup;82 goto cleanup;
83 kretprobe_prog = bpf_object__find_program_by_title(obj, kretprobe_name);83 kretprobe_prog = bpf_object__find_program_by_name(obj, kretprobe_name);
84 if (CHECK(!kretprobe_prog, "find_probe",84 if (CHECK(!kretprobe_prog, "find_probe",
85 "prog '%s' not found\n", kretprobe_name))85 "prog '%s' not found\n", kretprobe_name))
86 goto cleanup;86 goto cleanup;
87 raw_tp_prog = bpf_object__find_program_by_title(obj, raw_tp_name);87 raw_tp_prog = bpf_object__find_program_by_name(obj, raw_tp_name);
88 if (CHECK(!raw_tp_prog, "find_probe",88 if (CHECK(!raw_tp_prog, "find_probe",
89 "prog '%s' not found\n", raw_tp_name))89 "prog '%s' not found\n", raw_tp_name))
90 goto cleanup;90 goto cleanup;
91 fentry_prog = bpf_object__find_program_by_title(obj, fentry_name);91 fentry_prog = bpf_object__find_program_by_name(obj, fentry_name);
92 if (CHECK(!fentry_prog, "find_probe",92 if (CHECK(!fentry_prog, "find_probe",
93 "prog '%s' not found\n", fentry_name))93 "prog '%s' not found\n", fentry_name))
94 goto cleanup;94 goto cleanup;
95 fexit_prog = bpf_object__find_program_by_title(obj, fexit_name);95 fexit_prog = bpf_object__find_program_by_name(obj, fexit_name);
96 if (CHECK(!fexit_prog, "find_probe",96 if (CHECK(!fexit_prog, "find_probe",
97 "prog '%s' not found\n", fexit_name))97 "prog '%s' not found\n", fexit_name))
98 goto cleanup;98 goto cleanup;
tools/testing/selftests/bpf/prog_tests/test_strncmp.c+167−0
@@ -0,0 +1,167 @@
1// SPDX-License-Identifier: GPL-2.0
2/* Copyright (C) 2021. Huawei Technologies Co., Ltd */
3#include <test_progs.h>
4#include "strncmp_test.skel.h"
5
6static int trigger_strncmp(const struct strncmp_test *skel)
7{
8 int cmp;
9
10 usleep(1);
11
12 cmp = skel->bss->cmp_ret;
13 if (cmp > 0)
14 return 1;
15 if (cmp < 0)
16 return -1;
17 return 0;
18}
19
20/*
21 * Compare str and target after making str[i] != target[i].
22 * When exp is -1, make str[i] < target[i] and delta = -1.
23 */
24static void strncmp_full_str_cmp(struct strncmp_test *skel, const char *name,
25 int exp)
26{
27 size_t nr = sizeof(skel->bss->str);
28 char *str = skel->bss->str;
29 int delta = exp;
30 int got;
31 size_t i;
32
33 memcpy(str, skel->rodata->target, nr);
34 for (i = 0; i < nr - 1; i++) {
35 str[i] += delta;
36
37 got = trigger_strncmp(skel);
38 ASSERT_EQ(got, exp, name);
39
40 str[i] -= delta;
41 }
42}
43
44static void test_strncmp_ret(void)
45{
46 struct strncmp_test *skel;
47 struct bpf_program *prog;
48 int err, got;
49
50 skel = strncmp_test__open();
51 if (!ASSERT_OK_PTR(skel, "strncmp_test open"))
52 return;
53
54 bpf_object__for_each_program(prog, skel->obj)
55 bpf_program__set_autoload(prog, false);
56
57 bpf_program__set_autoload(skel->progs.do_strncmp, true);
58
59 err = strncmp_test__load(skel);
60 if (!ASSERT_EQ(err, 0, "strncmp_test load"))
61 goto out;
62
63 err = strncmp_test__attach(skel);
64 if (!ASSERT_EQ(err, 0, "strncmp_test attach"))
65 goto out;
66
67 skel->bss->target_pid = getpid();
68
69 /* Empty str */
70 skel->bss->str[0] = '\0';
71 got = trigger_strncmp(skel);
72 ASSERT_EQ(got, -1, "strncmp: empty str");
73
74 /* Same string */
75 memcpy(skel->bss->str, skel->rodata->target, sizeof(skel->bss->str));
76 got = trigger_strncmp(skel);
77 ASSERT_EQ(got, 0, "strncmp: same str");
78
79 /* Not-null-termainted string */
80 memcpy(skel->bss->str, skel->rodata->target, sizeof(skel->bss->str));
81 skel->bss->str[sizeof(skel->bss->str) - 1] = 'A';
82 got = trigger_strncmp(skel);
83 ASSERT_EQ(got, 1, "strncmp: not-null-term str");
84
85 strncmp_full_str_cmp(skel, "strncmp: less than", -1);
86 strncmp_full_str_cmp(skel, "strncmp: greater than", 1);
87out:
88 strncmp_test__destroy(skel);
89}
90
91static void test_strncmp_bad_not_const_str_size(void)
92{
93 struct strncmp_test *skel;
94 struct bpf_program *prog;
95 int err;
96
97 skel = strncmp_test__open();
98 if (!ASSERT_OK_PTR(skel, "strncmp_test open"))
99 return;
100
101 bpf_object__for_each_program(prog, skel->obj)
102 bpf_program__set_autoload(prog, false);
103
104 bpf_program__set_autoload(skel->progs.strncmp_bad_not_const_str_size,
105 true);
106
107 err = strncmp_test__load(skel);
108 ASSERT_ERR(err, "strncmp_test load bad_not_const_str_size");
109
110 strncmp_test__destroy(skel);
111}
112
113static void test_strncmp_bad_writable_target(void)
114{
115 struct strncmp_test *skel;
116 struct bpf_program *prog;
117 int err;
118
119 skel = strncmp_test__open();
120 if (!ASSERT_OK_PTR(skel, "strncmp_test open"))
121 return;
122
123 bpf_object__for_each_program(prog, skel->obj)
124 bpf_program__set_autoload(prog, false);
125
126 bpf_program__set_autoload(skel->progs.strncmp_bad_writable_target,
127 true);
128
129 err = strncmp_test__load(skel);
130 ASSERT_ERR(err, "strncmp_test load bad_writable_target");
131
132 strncmp_test__destroy(skel);
133}
134
135static void test_strncmp_bad_not_null_term_target(void)
136{
137 struct strncmp_test *skel;
138 struct bpf_program *prog;
139 int err;
140
141 skel = strncmp_test__open();
142 if (!ASSERT_OK_PTR(skel, "strncmp_test open"))
143 return;
144
145 bpf_object__for_each_program(prog, skel->obj)
146 bpf_program__set_autoload(prog, false);
147
148 bpf_program__set_autoload(skel->progs.strncmp_bad_not_null_term_target,
149 true);
150
151 err = strncmp_test__load(skel);
152 ASSERT_ERR(err, "strncmp_test load bad_not_null_term_target");
153
154 strncmp_test__destroy(skel);
155}
156
157void test_test_strncmp(void)
158{
159 if (test__start_subtest("strncmp_ret"))
160 test_strncmp_ret();
161 if (test__start_subtest("strncmp_bad_not_const_str_size"))
162 test_strncmp_bad_not_const_str_size();
163 if (test__start_subtest("strncmp_bad_writable_target"))
164 test_strncmp_bad_writable_target();
165 if (test__start_subtest("strncmp_bad_not_null_term_target"))
166 test_strncmp_bad_not_null_term_target();
167}
tools/testing/selftests/bpf/prog_tests/trampoline_count.c+3−3
@@ -35,7 +35,7 @@ static struct bpf_link *load(struct bpf_object *obj, const char *name) · 34 unmodified lines
35 struct bpf_program *prog;35 struct bpf_program *prog;
36 int duration = 0;36 int duration = 0;
37 37
38 prog = bpf_object__find_program_by_title(obj, name);38 prog = bpf_object__find_program_by_name(obj, name);
39 if (CHECK(!prog, "find_probe", "prog '%s' not found\n", name))39 if (CHECK(!prog, "find_probe", "prog '%s' not found\n", name))
40 return ERR_PTR(-EINVAL);40 return ERR_PTR(-EINVAL);
41 return bpf_program__attach_trace(prog);41 return bpf_program__attach_trace(prog);
@@ -44,8 +44,8 @@ static struct bpf_link *load(struct bpf_object *obj, const char *name) · 2 unmodified lines
44/* TODO: use different target function to run in concurrent mode */44/* TODO: use different target function to run in concurrent mode */
45void serial_test_trampoline_count(void)45void serial_test_trampoline_count(void)
46{46{
47 const char *fentry_name = "fentry/__set_task_comm";47 const char *fentry_name = "prog1";
48 const char *fexit_name = "fexit/__set_task_comm";48 const char *fexit_name = "prog2";
49 const char *object = "test_trampoline_count.o";49 const char *object = "test_trampoline_count.o";
50 struct inst inst[MAX_TRAMP_PROGS] = {};50 struct inst inst[MAX_TRAMP_PROGS] = {};
51 int err, i = 0, duration = 0;51 int err, i = 0, duration = 0;
tools/testing/selftests/bpf/progs/get_func_args_test.c+123−0
@@ -0,0 +1,123 @@
1// SPDX-License-Identifier: GPL-2.0
2#include <linux/bpf.h>
3#include <bpf/bpf_helpers.h>
4#include <bpf/bpf_tracing.h>
5#include <errno.h>
6
7char _license[] SEC("license") = "GPL";
8
9__u64 test1_result = 0;
10SEC("fentry/bpf_fentry_test1")
11int BPF_PROG(test1)
12{
13 __u64 cnt = bpf_get_func_arg_cnt(ctx);
14 __u64 a = 0, z = 0, ret = 0;
15 __s64 err;
16
17 test1_result = cnt == 1;
18
19 /* valid arguments */
20 err = bpf_get_func_arg(ctx, 0, &a);
21
22 /* We need to cast access to traced function argument values with
23 * proper type cast, because trampoline uses type specific instruction
24 * to save it, like for 'int a' with 32-bit mov like:
25 *
26 * mov %edi,-0x8(%rbp)
27 *
28 * so the upper 4 bytes are not zeroed.
29 */
30 test1_result &= err == 0 && ((int) a == 1);
31
32 /* not valid argument */
33 err = bpf_get_func_arg(ctx, 1, &z);
34 test1_result &= err == -EINVAL;
35
36 /* return value fails in fentry */
37 err = bpf_get_func_ret(ctx, &ret);
38 test1_result &= err == -EOPNOTSUPP;
39 return 0;
40}
41
42__u64 test2_result = 0;
43SEC("fexit/bpf_fentry_test2")
44int BPF_PROG(test2)
45{
46 __u64 cnt = bpf_get_func_arg_cnt(ctx);
47 __u64 a = 0, b = 0, z = 0, ret = 0;
48 __s64 err;
49
50 test2_result = cnt == 2;
51
52 /* valid arguments */
53 err = bpf_get_func_arg(ctx, 0, &a);
54 test2_result &= err == 0 && (int) a == 2;
55
56 err = bpf_get_func_arg(ctx, 1, &b);
57 test2_result &= err == 0 && b == 3;
58
59 /* not valid argument */
60 err = bpf_get_func_arg(ctx, 2, &z);
61 test2_result &= err == -EINVAL;
62
63 /* return value */
64 err = bpf_get_func_ret(ctx, &ret);
65 test2_result &= err == 0 && ret == 5;
66 return 0;
67}
68
69__u64 test3_result = 0;
70SEC("fmod_ret/bpf_modify_return_test")
71int BPF_PROG(fmod_ret_test, int _a, int *_b, int _ret)
72{
73 __u64 cnt = bpf_get_func_arg_cnt(ctx);
74 __u64 a = 0, b = 0, z = 0, ret = 0;
75 __s64 err;
76
77 test3_result = cnt == 2;
78
79 /* valid arguments */
80 err = bpf_get_func_arg(ctx, 0, &a);
81 test3_result &= err == 0 && ((int) a == 1);
82
83 err = bpf_get_func_arg(ctx, 1, &b);
84 test3_result &= err == 0 && ((int *) b == _b);
85
86 /* not valid argument */
87 err = bpf_get_func_arg(ctx, 2, &z);
88 test3_result &= err == -EINVAL;
89
90 /* return value */
91 err = bpf_get_func_ret(ctx, &ret);
92 test3_result &= err == 0 && ret == 0;
93
94 /* change return value, it's checked in fexit_test program */
95 return 1234;
96}
97
98__u64 test4_result = 0;
99SEC("fexit/bpf_modify_return_test")
100int BPF_PROG(fexit_test, int _a, int *_b, int _ret)
101{
102 __u64 cnt = bpf_get_func_arg_cnt(ctx);
103 __u64 a = 0, b = 0, z = 0, ret = 0;
104 __s64 err;
105
106 test4_result = cnt == 2;
107
108 /* valid arguments */
109 err = bpf_get_func_arg(ctx, 0, &a);
110 test4_result &= err == 0 && ((int) a == 1);
111
112 err = bpf_get_func_arg(ctx, 1, &b);
113 test4_result &= err == 0 && ((int *) b == _b);
114
115 /* not valid argument */
116 err = bpf_get_func_arg(ctx, 2, &z);
117 test4_result &= err == -EINVAL;
118
119 /* return value */
120 err = bpf_get_func_ret(ctx, &ret);
121 test4_result &= err == 0 && ret == 1234;
122 return 0;
123}
tools/testing/selftests/bpf/progs/local_storage.c+5−19
@@ -20,7 +20,6 @@ int sk_storage_result = -1; · 19 unmodified lines
20struct local_storage {20struct local_storage {
21 struct inode *exec_inode;21 struct inode *exec_inode;
22 __u32 value;22 __u32 value;
23 struct bpf_spin_lock lock;
24};23};
25 24
26struct {25struct {
@@ -58,9 +57,7 @@ int BPF_PROG(unlink_hook, struct inode *dir, struct dentry *victim) · 31 unmodified lines
58 bpf_get_current_task_btf(), 0, 0);57 bpf_get_current_task_btf(), 0, 0);
59 if (storage) {58 if (storage) {
60 /* Don't let an executable delete itself */59 /* Don't let an executable delete itself */
61 bpf_spin_lock(&storage->lock);
62 is_self_unlink = storage->exec_inode == victim->d_inode;60 is_self_unlink = storage->exec_inode == victim->d_inode;
63 bpf_spin_unlock(&storage->lock);
64 if (is_self_unlink)61 if (is_self_unlink)
65 return -EPERM;62 return -EPERM;
66 }63 }
@@ -68,7 +65,7 @@ int BPF_PROG(unlink_hook, struct inode *dir, struct dentry *victim) · 1 unmodified line
68 return 0;65 return 0;
69}66}
70 67
71SEC("lsm/inode_rename")68SEC("lsm.s/inode_rename")
72int BPF_PROG(inode_rename, struct inode *old_dir, struct dentry *old_dentry,69int BPF_PROG(inode_rename, struct inode *old_dir, struct dentry *old_dentry,
73 struct inode *new_dir, struct dentry *new_dentry,70 struct inode *new_dir, struct dentry *new_dentry,
74 unsigned int flags)71 unsigned int flags)
@@ -89,10 +86,8 @@ int BPF_PROG(inode_rename, struct inode *old_dir, struct dentry *old_dentry, · 14 unmodified lines
89 if (!storage)86 if (!storage)
90 return 0;87 return 0;
91 88
92 bpf_spin_lock(&storage->lock);
93 if (storage->value != DUMMY_STORAGE_VALUE)89 if (storage->value != DUMMY_STORAGE_VALUE)
94 inode_storage_result = -1;90 inode_storage_result = -1;
95 bpf_spin_unlock(&storage->lock);
96 91
97 err = bpf_inode_storage_delete(&inode_storage_map, old_dentry->d_inode);92 err = bpf_inode_storage_delete(&inode_storage_map, old_dentry->d_inode);
98 if (!err)93 if (!err)
@@ -101,7 +96,7 @@ int BPF_PROG(inode_rename, struct inode *old_dir, struct dentry *old_dentry, · 2 unmodified lines
101 return 0;96 return 0;
102}97}
103 98
104SEC("lsm/socket_bind")99SEC("lsm.s/socket_bind")
105int BPF_PROG(socket_bind, struct socket *sock, struct sockaddr *address,100int BPF_PROG(socket_bind, struct socket *sock, struct sockaddr *address,
106 int addrlen)101 int addrlen)
107{102{
@@ -117,10 +112,8 @@ int BPF_PROG(socket_bind, struct socket *sock, struct sockaddr *address, · 9 unmodified lines
117 if (!storage)112 if (!storage)
118 return 0;113 return 0;
119 114
120 bpf_spin_lock(&storage->lock);
121 if (storage->value != DUMMY_STORAGE_VALUE)115 if (storage->value != DUMMY_STORAGE_VALUE)
122 sk_storage_result = -1;116 sk_storage_result = -1;
123 bpf_spin_unlock(&storage->lock);
124 117
125 err = bpf_sk_storage_delete(&sk_storage_map, sock->sk);118 err = bpf_sk_storage_delete(&sk_storage_map, sock->sk);
126 if (!err)119 if (!err)
@@ -129,7 +122,7 @@ int BPF_PROG(socket_bind, struct socket *sock, struct sockaddr *address, · 2 unmodified lines
129 return 0;122 return 0;
130}123}
131 124
132SEC("lsm/socket_post_create")125SEC("lsm.s/socket_post_create")
133int BPF_PROG(socket_post_create, struct socket *sock, int family, int type,126int BPF_PROG(socket_post_create, struct socket *sock, int family, int type,
134 int protocol, int kern)127 int protocol, int kern)
135{128{
@@ -144,9 +137,7 @@ int BPF_PROG(socket_post_create, struct socket *sock, int family, int type, · 8 unmodified lines
144 if (!storage)137 if (!storage)
145 return 0;138 return 0;
146 139
147 bpf_spin_lock(&storage->lock);
148 storage->value = DUMMY_STORAGE_VALUE;140 storage->value = DUMMY_STORAGE_VALUE;
149 bpf_spin_unlock(&storage->lock);
150 141
151 return 0;142 return 0;
152}143}
@@ -154,7 +145,7 @@ int BPF_PROG(socket_post_create, struct socket *sock, int family, int type, · 1 unmodified line
154/* This uses the local storage to remember the inode of the binary that a145/* This uses the local storage to remember the inode of the binary that a
155 * process was originally executing.146 * process was originally executing.
156 */147 */
157SEC("lsm/bprm_committed_creds")148SEC("lsm.s/bprm_committed_creds")
158void BPF_PROG(exec, struct linux_binprm *bprm)149void BPF_PROG(exec, struct linux_binprm *bprm)
159{150{
160 __u32 pid = bpf_get_current_pid_tgid() >> 32;151 __u32 pid = bpf_get_current_pid_tgid() >> 32;
@@ -166,18 +157,13 @@ void BPF_PROG(exec, struct linux_binprm *bprm) · 5 unmodified lines
166 storage = bpf_task_storage_get(&task_storage_map,157 storage = bpf_task_storage_get(&task_storage_map,
167 bpf_get_current_task_btf(), 0,158 bpf_get_current_task_btf(), 0,
168 BPF_LOCAL_STORAGE_GET_F_CREATE);159 BPF_LOCAL_STORAGE_GET_F_CREATE);
169 if (storage) {160 if (storage)
170 bpf_spin_lock(&storage->lock);
171 storage->exec_inode = bprm->file->f_inode;161 storage->exec_inode = bprm->file->f_inode;
172 bpf_spin_unlock(&storage->lock);
173 }
174 162
175 storage = bpf_inode_storage_get(&inode_storage_map, bprm->file->f_inode,163 storage = bpf_inode_storage_get(&inode_storage_map, bprm->file->f_inode,
176 0, BPF_LOCAL_STORAGE_GET_F_CREATE);164 0, BPF_LOCAL_STORAGE_GET_F_CREATE);
177 if (!storage)165 if (!storage)
178 return;166 return;
179 167
180 bpf_spin_lock(&storage->lock);
181 storage->value = DUMMY_STORAGE_VALUE;168 storage->value = DUMMY_STORAGE_VALUE;
182 bpf_spin_unlock(&storage->lock);
183}169}
tools/testing/selftests/bpf/progs/strncmp_bench.c+50−0
@@ -0,0 +1,50 @@
1// SPDX-License-Identifier: GPL-2.0
2/* Copyright (C) 2021. Huawei Technologies Co., Ltd */
3#include <linux/types.h>
4#include <linux/bpf.h>
5#include <bpf/bpf_helpers.h>
6#include <bpf/bpf_tracing.h>
7
8#define STRNCMP_STR_SZ 4096
9
10/* Will be updated by benchmark before program loading */
11const volatile unsigned int cmp_str_len = 1;
12const char target[STRNCMP_STR_SZ];
13
14long hits = 0;
15char str[STRNCMP_STR_SZ];
16
17char _license[] SEC("license") = "GPL";
18
19static __always_inline int local_strncmp(const char *s1, unsigned int sz,
20 const char *s2)
21{
22 int ret = 0;
23 unsigned int i;
24
25 for (i = 0; i < sz; i++) {
26 /* E.g. 0xff > 0x31 */
27 ret = (unsigned char)s1[i] - (unsigned char)s2[i];
28 if (ret || !s1[i])
29 break;
30 }
31
32 return ret;
33}
34
35SEC("tp/syscalls/sys_enter_getpgid")
36int strncmp_no_helper(void *ctx)
37{
38 if (local_strncmp(str, cmp_str_len + 1, target) < 0)
39 __sync_add_and_fetch(&hits, 1);
40 return 0;
41}
42
43SEC("tp/syscalls/sys_enter_getpgid")
44int strncmp_helper(void *ctx)
45{
46 if (bpf_strncmp(str, cmp_str_len + 1, target) < 0)
47 __sync_add_and_fetch(&hits, 1);
48 return 0;
49}
50
tools/testing/selftests/bpf/progs/strncmp_test.c+54−0
@@ -0,0 +1,54 @@
1// SPDX-License-Identifier: GPL-2.0
2/* Copyright (C) 2021. Huawei Technologies Co., Ltd */
3#include <stdbool.h>
4#include <linux/types.h>
5#include <linux/bpf.h>
6#include <bpf/bpf_helpers.h>
7#include <bpf/bpf_tracing.h>
8
9#define STRNCMP_STR_SZ 8
10
11const char target[STRNCMP_STR_SZ] = "EEEEEEE";
12char str[STRNCMP_STR_SZ];
13int cmp_ret = 0;
14int target_pid = 0;
15
16const char no_str_target[STRNCMP_STR_SZ] = "12345678";
17char writable_target[STRNCMP_STR_SZ];
18unsigned int no_const_str_size = STRNCMP_STR_SZ;
19
20char _license[] SEC("license") = "GPL";
21
22SEC("tp/syscalls/sys_enter_nanosleep")
23int do_strncmp(void *ctx)
24{
25 if ((bpf_get_current_pid_tgid() >> 32) != target_pid)
26 return 0;
27
28 cmp_ret = bpf_strncmp(str, STRNCMP_STR_SZ, target);
29 return 0;
30}
31
32SEC("tp/syscalls/sys_enter_nanosleep")
33int strncmp_bad_not_const_str_size(void *ctx)
34{
35 /* The value of string size is not const, so will fail */
36 cmp_ret = bpf_strncmp(str, no_const_str_size, target);
37 return 0;
38}
39
40SEC("tp/syscalls/sys_enter_nanosleep")
41int strncmp_bad_writable_target(void *ctx)
42{
43 /* Compared target is not read-only, so will fail */
44 cmp_ret = bpf_strncmp(str, STRNCMP_STR_SZ, writable_target);
45 return 0;
46}
47
48SEC("tp/syscalls/sys_enter_nanosleep")
49int strncmp_bad_not_null_term_target(void *ctx)
50{
51 /* Compared target is not null-terminated, so will fail */
52 cmp_ret = bpf_strncmp(str, STRNCMP_STR_SZ, no_str_target);
53 return 0;
54}
tools/testing/selftests/bpf/progs/test_ksyms_btf_write_check.c+29−0
@@ -0,0 +1,29 @@
1// SPDX-License-Identifier: GPL-2.0
2/* Copyright (c) 2021 Google */
3
4#include "vmlinux.h"
5
6#include <bpf/bpf_helpers.h>
7
8extern const int bpf_prog_active __ksym; /* int type global var. */
9
10SEC("raw_tp/sys_enter")
11int handler(const void *ctx)
12{
13 int *active;
14 __u32 cpu;
15
16 cpu = bpf_get_smp_processor_id();
17 active = (int *)bpf_per_cpu_ptr(&bpf_prog_active, cpu);
18 if (active) {
19 /* Kernel memory obtained from bpf_{per,this}_cpu_ptr
20 * is read-only, should _not_ pass verification.
21 */
22 /* WRITE_ONCE */
23 *(volatile int *)active = -1;
24 }
25
26 return 0;
27}
28
29char _license[] SEC("license") = "GPL";
tools/testing/selftests/bpf/test_cpp.cpp+8−1
@@ -7,9 +7,15 @@ · 6 unmodified lines
7 7
8/* do nothing, just make sure we can link successfully */8/* do nothing, just make sure we can link successfully */
9 9
10static void dump_printf(void *ctx, const char *fmt, va_list args)
11{
12}
13
10int main(int argc, char *argv[])14int main(int argc, char *argv[])
11{15{
16 struct btf_dump_opts opts = { };
12 struct test_core_extern *skel;17 struct test_core_extern *skel;
18 struct btf *btf;
13 19
14 /* libbpf.h */20 /* libbpf.h */
15 libbpf_set_print(NULL);21 libbpf_set_print(NULL);
@@ -18,7 +24,8 @@ int main(int argc, char *argv[]) · 2 unmodified lines
18 bpf_prog_get_fd_by_id(0);24 bpf_prog_get_fd_by_id(0);
19 25
20 /* btf.h */26 /* btf.h */
21 btf__new(NULL, 0);27 btf = btf__new(NULL, 0);
28 btf_dump__new(btf, dump_printf, nullptr, &opts);
22 29
23 /* BPF skeleton */30 /* BPF skeleton */
24 skel = test_core_extern__open_and_load();31 skel = test_core_extern__open_and_load();
tools/testing/selftests/bpf/test_maps.c+0−1
@@ -23,7 +23,6 @@ · 22 unmodified lines
23#include <bpf/libbpf.h>23#include <bpf/libbpf.h>
24 24
25#include "bpf_util.h"25#include "bpf_util.h"
26#include "bpf_rlimit.h"
27#include "test_maps.h"26#include "test_maps.h"
28#include "testing_helpers.h"27#include "testing_helpers.h"
29 28
tools/testing/selftests/bpf/test_progs.c+0−2
@@ -4,7 +4,6 @@ · 3 unmodified lines
4#define _GNU_SOURCE4#define _GNU_SOURCE
5#include "test_progs.h"5#include "test_progs.h"
6#include "cgroup_helpers.h"6#include "cgroup_helpers.h"
7#include "bpf_rlimit.h"
8#include <argp.h>7#include <argp.h>
9#include <pthread.h>8#include <pthread.h>
10#include <sched.h>9#include <sched.h>
@@ -1342,7 +1341,6 @@ int main(int argc, char **argv) · 1331 unmodified lines
1342 1341
1343 /* Use libbpf 1.0 API mode */1342 /* Use libbpf 1.0 API mode */
1344 libbpf_set_strict_mode(LIBBPF_STRICT_ALL);1343 libbpf_set_strict_mode(LIBBPF_STRICT_ALL);
1345
1346 libbpf_set_print(libbpf_print_fn);1344 libbpf_set_print(libbpf_print_fn);
1347 1345
1348 srand(time(NULL));1346 srand(time(NULL));
tools/testing/selftests/bpf/test_verifier.c+8−10
@@ -41,7 +41,6 @@ · 40 unmodified lines
41# define CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS 141# define CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS 1
42# endif42# endif
43#endif43#endif
44#include "bpf_rlimit.h"
45#include "bpf_rand.h"44#include "bpf_rand.h"
46#include "bpf_util.h"45#include "bpf_util.h"
47#include "test_btf.h"46#include "test_btf.h"
@@ -701,22 +700,18 @@ static int create_sk_storage_map(void) · 653 unmodified lines
701 700
702static int create_map_timer(void)701static int create_map_timer(void)
703{702{
704 struct bpf_create_map_attr attr = {703 LIBBPF_OPTS(bpf_map_create_opts, opts,
705 .name = "test_map",
706 .map_type = BPF_MAP_TYPE_ARRAY,
707 .key_size = 4,
708 .value_size = 16,
709 .max_entries = 1,
710 .btf_key_type_id = 1,704 .btf_key_type_id = 1,
711 .btf_value_type_id = 5,705 .btf_value_type_id = 5,
712 };706 );
713 int fd, btf_fd;707 int fd, btf_fd;
714 708
715 btf_fd = load_btf();709 btf_fd = load_btf();
716 if (btf_fd < 0)710 if (btf_fd < 0)
717 return -1;711 return -1;
718 attr.btf_fd = btf_fd;712
719 fd = bpf_create_map_xattr(&attr);713 opts.btf_fd = btf_fd;
714 fd = bpf_map_create(BPF_MAP_TYPE_ARRAY, "test_map", 4, 16, 1, &opts);
720 if (fd < 0)715 if (fd < 0)
721 printf("Failed to create map with timer\n");716 printf("Failed to create map with timer\n");
722 return fd;717 return fd;
@@ -1399,6 +1394,9 @@ int main(int argc, char **argv) · 676 unmodified lines
1399 return EXIT_FAILURE;1394 return EXIT_FAILURE;
1400 }1395 }
1401 1396
1397 /* Use libbpf 1.0 API mode */
1398 libbpf_set_strict_mode(LIBBPF_STRICT_ALL);
1399
1402 bpf_semi_rand_init();1400 bpf_semi_rand_init();
1403 return do_test(unpriv, from, to);1401 return do_test(unpriv, from, to);
1404}1402}
tools/testing/selftests/bpf/verifier/btf_ctx_access.c+12−0
@@ -0,0 +1,12 @@
1{
2 "btf_ctx_access accept",
3 .insns = {
4 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 8), /* load 2nd argument value (int pointer) */
5 BPF_MOV64_IMM(BPF_REG_0, 0),
6 BPF_EXIT_INSN(),
7 },
8 .result = ACCEPT,
9 .prog_type = BPF_PROG_TYPE_TRACING,
10 .expected_attach_type = BPF_TRACE_FENTRY,
11 .kfunc = "bpf_modify_return_test",
12},
tools/testing/selftests/bpf/vmtest.sh+1−1
@@ -32,7 +32,7 @@ ROOTFS_IMAGE="root.img" · 31 unmodified lines
32OUTPUT_DIR="$HOME/.bpf_selftests"32OUTPUT_DIR="$HOME/.bpf_selftests"
33KCONFIG_URL="https://raw.githubusercontent.com/libbpf/libbpf/master/travis-ci/vmtest/configs/config-latest.${ARCH}"33KCONFIG_URL="https://raw.githubusercontent.com/libbpf/libbpf/master/travis-ci/vmtest/configs/config-latest.${ARCH}"
34KCONFIG_API_URL="https://api.github.com/repos/libbpf/libbpf/contents/travis-ci/vmtest/configs/config-latest.${ARCH}"34KCONFIG_API_URL="https://api.github.com/repos/libbpf/libbpf/contents/travis-ci/vmtest/configs/config-latest.${ARCH}"
35INDEX_URL="https://raw.githubusercontent.com/libbpf/libbpf/master/travis-ci/vmtest/configs/INDEX"35INDEX_URL="https://raw.githubusercontent.com/libbpf/ci/master/INDEX"
36NUM_COMPILE_JOBS="$(nproc)"36NUM_COMPILE_JOBS="$(nproc)"
37LOG_FILE_BASE="$(date +"bpf_selftests.%Y-%m-%d_%H-%M-%S")"37LOG_FILE_BASE="$(date +"bpf_selftests.%Y-%m-%d_%H-%M-%S")"
38LOG_FILE="${LOG_FILE_BASE}.log"38LOG_FILE="${LOG_FILE_BASE}.log"