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
170170
171171 $(OUTPUT)/urandom_read: urandom_read.c
172172 $(call msg,BINARY,,$@)
173− $(Q)$(CC) $(LDFLAGS) $< $(LDLIBS) -Wl,--build-id=sha1 -o $@
173+ $(Q)$(CC) $(CFLAGS) $(LDFLAGS) $< $(LDLIBS) -Wl,--build-id=sha1 -o $@
174174
175175 $(OUTPUT)/bpf_testmod.ko: $(VMLINUX_BTF) $(wildcard bpf_testmod/Makefile bpf_testmod/*.[ch])
176176 $(call msg,MOD,,$@)
@@ -217,7 +217,7 @@ BPFTOOL ?= $(DEFAULT_BPFTOOL) · 40 unmodified lines
217217 $(DEFAULT_BPFTOOL): $(wildcard $(BPFTOOLDIR)/*.[ch] $(BPFTOOLDIR)/Makefile) \
218218 $(HOST_BPFOBJ) | $(HOST_BUILD_DIR)/bpftool
219219 $(Q)$(MAKE) $(submake_extras) -C $(BPFTOOLDIR) \
220− CC=$(HOSTCC) LD=$(HOSTLD) \
220+ ARCH= CROSS_COMPILE= CC=$(HOSTCC) LD=$(HOSTLD) \
221221 EXTRA_CFLAGS='-g -O0' \
222222 OUTPUT=$(HOST_BUILD_DIR)/bpftool/ \
223223 LIBBPF_OUTPUT=$(HOST_BUILD_DIR)/libbpf/ \
@@ -248,7 +248,7 @@ $(HOST_BPFOBJ): $(wildcard $(BPFDIR)/*.[ch] $(BPFDIR)/Makefile) \ · 24 unmodified lines
248248 $(APIDIR)/linux/bpf.h \
249249 | $(HOST_BUILD_DIR)/libbpf
250250 $(Q)$(MAKE) $(submake_extras) -C $(BPFDIR) \
251− EXTRA_CFLAGS='-g -O0' \
251+ EXTRA_CFLAGS='-g -O0' ARCH= CROSS_COMPILE= \
252252 OUTPUT=$(HOST_BUILD_DIR)/libbpf/ CC=$(HOSTCC) LD=$(HOSTLD) \
253253 DESTDIR=$(HOST_SCRATCH_DIR)/ prefix= all install_headers
254254 endif
@@ -537,6 +537,7 @@ $(OUTPUT)/bench_ringbufs.o: $(OUTPUT)/ringbuf_bench.skel.h \ · 282 unmodified lines
537537 $(OUTPUT)/perfbuf_bench.skel.h
538538 $(OUTPUT)/bench_bloom_filter_map.o: $(OUTPUT)/bloom_filter_bench.skel.h
539539 $(OUTPUT)/bench_bpf_loop.o: $(OUTPUT)/bpf_loop_bench.skel.h
540+$(OUTPUT)/bench_strncmp.o: $(OUTPUT)/strncmp_bench.skel.h
540541 $(OUTPUT)/bench.o: bench.h testing_helpers.h $(BPFOBJ)
541542 $(OUTPUT)/bench: LDLIBS += -lm
542543 $(OUTPUT)/bench: $(OUTPUT)/bench.o \
@@ -547,9 +548,10 @@ $(OUTPUT)/bench: $(OUTPUT)/bench.o \ · 4 unmodified lines
547548 $(OUTPUT)/bench_trigger.o \
548549 $(OUTPUT)/bench_ringbufs.o \
549550 $(OUTPUT)/bench_bloom_filter_map.o \
550− $(OUTPUT)/bench_bpf_loop.o
551+ $(OUTPUT)/bench_bpf_loop.o \
552+ $(OUTPUT)/bench_strncmp.o
551553 $(call msg,BINARY,,$@)
552− $(Q)$(CC) $(LDFLAGS) $(filter %.a %.o,$^) $(LDLIBS) -o $@
554+ $(Q)$(CC) $(CFLAGS) $(LDFLAGS) $(filter %.a %.o,$^) $(LDLIBS) -o $@
553555
554556 EXTRA_CLEAN := $(TEST_CUSTOM_PROGS) $(SCRATCH_DIR) $(HOST_SCRATCH_DIR) \
555557 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
2929 return vfprintf(stderr, format, args);
3030 }
3131
32−static int bump_memlock_rlimit(void)
32+void setup_libbpf(void)
3333 {
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−
42−void setup_libbpf()
43−{
44− int err;
45−
4634 libbpf_set_strict_mode(LIBBPF_STRICT_ALL);
4735 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);
5236 }
5337
5438 void 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
205189 extern struct argp bench_ringbufs_argp;
206190 extern struct argp bench_bloom_map_argp;
207191 extern struct argp bench_bpf_loop_argp;
192+extern struct argp bench_strncmp_argp;
208193
209194 static const struct argp_child bench_parsers[] = {
210195 { &bench_ringbufs_argp, 0, "Ring buffers benchmark", 0 },
211196 { &bench_bloom_map_argp, 0, "Bloom filter map benchmark", 0 },
212197 { &bench_bpf_loop_argp, 0, "bpf_loop helper benchmark", 0 },
198+ { &bench_strncmp_argp, 0, "bpf_strncmp helper benchmark", 0 },
213199 {},
214200 };
215201
@@ -409,6 +395,8 @@ extern const struct bench bench_bloom_false_positive; · 193 unmodified lines
409395 extern const struct bench bench_hashmap_without_bloom;
410396 extern const struct bench bench_hashmap_with_bloom;
411397 extern const struct bench bench_bpf_loop;
398+extern const struct bench bench_strncmp_no_helper;
399+extern const struct bench bench_strncmp_helper;
412400
413401 static const struct bench *benchs[] = {
414402 &bench_count_global,
@@ -441,6 +429,8 @@ static const struct bench *benchs[] = { · 26 unmodified lines
441429 &bench_hashmap_without_bloom,
442430 &bench_hashmap_with_bloom,
443431 &bench_bpf_loop,
432+ &bench_strncmp_no_helper,
433+ &bench_strncmp_helper,
444434 };
445435
446436 static void setup_benchmark()
tools/testing/selftests/bpf/bench.h+5−4
@@ -38,8 +38,8 @@ struct bench_res { · 37 unmodified lines
3838
3939 struct bench {
4040 const char *name;
41− void (*validate)();
42− void (*setup)();
41+ void (*validate)(void);
42+ void (*setup)(void);
4343 void *(*producer_thread)(void *ctx);
4444 void *(*consumer_thread)(void *ctx);
4545 void (*measure)(struct bench_res* res);
@@ -54,7 +54,7 @@ struct counter { · 8 unmodified lines
5454 extern struct env env;
5555 extern const struct bench *bench;
5656
57−void setup_libbpf();
57+void setup_libbpf(void);
5858 void hits_drops_report_progress(int iter, struct bench_res *res, long delta_ns);
5959 void hits_drops_report_final(struct bench_res res[], int res_cnt);
6060 void 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
6262 void ops_report_progress(int iter, struct bench_res *res, long delta_ns);
6363 void ops_report_final(struct bench_res res[], int res_cnt);
6464
65−static inline __u64 get_time_ns() {
65+static inline __u64 get_time_ns(void)
66+{
6667 struct timespec t;
6768
6869 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
3636 struct counter *hits;
3737 } count_local_ctx;
3838
39−static void count_local_setup()
39+static void count_local_setup(void)
4040 {
4141 struct count_local_ctx *ctx = &count_local_ctx;
4242
tools/testing/selftests/bpf/benchs/bench_rename.c+8−8
@@ -11,7 +11,7 @@ static struct ctx { · 10 unmodified lines
1111 int fd;
1212 } ctx;
1313
14−static void validate()
14+static void validate(void)
1515 {
1616 if (env.producer_cnt != 1) {
1717 fprintf(stderr, "benchmark doesn't support multi-producer!\n");
@@ -43,7 +43,7 @@ static void measure(struct bench_res *res) · 25 unmodified lines
4343 res->hits = atomic_swap(&ctx.hits.value, 0);
4444 }
4545
46−static void setup_ctx()
46+static void setup_ctx(void)
4747 {
4848 setup_libbpf();
4949
@@ -71,36 +71,36 @@ static void attach_bpf(struct bpf_program *prog) · 21 unmodified lines
7171 }
7272 }
7373
74−static void setup_base()
74+static void setup_base(void)
7575 {
7676 setup_ctx();
7777 }
7878
79−static void setup_kprobe()
79+static void setup_kprobe(void)
8080 {
8181 setup_ctx();
8282 attach_bpf(ctx.skel->progs.prog1);
8383 }
8484
85−static void setup_kretprobe()
85+static void setup_kretprobe(void)
8686 {
8787 setup_ctx();
8888 attach_bpf(ctx.skel->progs.prog2);
8989 }
9090
91−static void setup_rawtp()
91+static void setup_rawtp(void)
9292 {
9393 setup_ctx();
9494 attach_bpf(ctx.skel->progs.prog3);
9595 }
9696
97−static void setup_fentry()
97+static void setup_fentry(void)
9898 {
9999 setup_ctx();
100100 attach_bpf(ctx.skel->progs.prog4);
101101 }
102102
103−static void setup_fexit()
103+static void setup_fexit(void)
104104 {
105105 setup_ctx();
106106 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
8888
8989 static struct counter buf_hits;
9090
91−static inline void bufs_trigger_batch()
91+static inline void bufs_trigger_batch(void)
9292 {
9393 (void)syscall(__NR_getpgid);
9494 }
9595
96−static void bufs_validate()
96+static void bufs_validate(void)
9797 {
9898 if (env.consumer_cnt != 1) {
9999 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
132132 res->drops = atomic_swap(&ctx->skel->bss->dropped, 0);
133133 }
134134
135−static struct ringbuf_bench *ringbuf_setup_skeleton()
135+static struct ringbuf_bench *ringbuf_setup_skeleton(void)
136136 {
137137 struct ringbuf_bench *skel;
138138
@@ -167,7 +167,7 @@ static int buf_process_sample(void *ctx, void *data, size_t len) · 28 unmodified lines
167167 return 0;
168168 }
169169
170−static void ringbuf_libbpf_setup()
170+static void ringbuf_libbpf_setup(void)
171171 {
172172 struct ringbuf_libbpf_ctx *ctx = &ringbuf_libbpf_ctx;
173173 struct bpf_link *link;
@@ -223,7 +223,7 @@ static void ringbuf_custom_measure(struct bench_res *res) · 49 unmodified lines
223223 res->drops = atomic_swap(&ctx->skel->bss->dropped, 0);
224224 }
225225
226−static void ringbuf_custom_setup()
226+static void ringbuf_custom_setup(void)
227227 {
228228 struct ringbuf_custom_ctx *ctx = &ringbuf_custom_ctx;
229229 const size_t page_size = getpagesize();
@@ -352,7 +352,7 @@ static void perfbuf_measure(struct bench_res *res) · 122 unmodified lines
352352 res->drops = atomic_swap(&ctx->skel->bss->dropped, 0);
353353 }
354354
355−static struct perfbuf_bench *perfbuf_setup_skeleton()
355+static struct perfbuf_bench *perfbuf_setup_skeleton(void)
356356 {
357357 struct perfbuf_bench *skel;
358358
@@ -390,7 +390,7 @@ perfbuf_process_sample_raw(void *input_ctx, int cpu, · 31 unmodified lines
390390 return LIBBPF_PERF_EVENT_CONT;
391391 }
392392
393−static void perfbuf_libbpf_setup()
393+static void perfbuf_libbpf_setup(void)
394394 {
395395 struct perfbuf_libbpf_ctx *ctx = &perfbuf_libbpf_ctx;
396396 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+
7+static struct strncmp_ctx {
8+ struct strncmp_bench *skel;
9+} ctx;
10+
11+static struct strncmp_args {
12+ u32 cmp_str_len;
13+} args = {
14+ .cmp_str_len = 32,
15+};
16+
17+enum {
18+ ARG_CMP_STR_LEN = 5000,
19+};
20+
21+static 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+
27+static 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+
46+const struct argp bench_strncmp_argp = {
47+ .options = opts,
48+ .parser = strncmp_parse_arg,
49+};
50+
51+static 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+
59+static 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+
101+static 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+
112+static void strncmp_no_helper_setup(void)
113+{
114+ strncmp_setup();
115+ strncmp_attach_prog(ctx.skel->progs.strncmp_no_helper);
116+}
117+
118+static void strncmp_helper_setup(void)
119+{
120+ strncmp_setup();
121+ strncmp_attach_prog(ctx.skel->progs.strncmp_helper);
122+}
123+
124+static void *strncmp_producer(void *ctx)
125+{
126+ while (true)
127+ (void)syscall(__NR_getpgid);
128+ return NULL;
129+}
130+
131+static void *strncmp_consumer(void *ctx)
132+{
133+ return NULL;
134+}
135+
136+static void strncmp_measure(struct bench_res *res)
137+{
138+ res->hits = atomic_swap(&ctx.skel->bss->hits, 0);
139+}
140+
141+const 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+
152+const 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
1111
1212 static struct counter base_hits;
1313
14−static void trigger_validate()
14+static void trigger_validate(void)
1515 {
1616 if (env.consumer_cnt != 1) {
1717 fprintf(stderr, "benchmark doesn't support multi-consumer!\n");
@@ -45,7 +45,7 @@ static void trigger_measure(struct bench_res *res) · 27 unmodified lines
4545 res->hits = atomic_swap(&ctx.skel->bss->hits, 0);
4646 }
4747
48−static void setup_ctx()
48+static void setup_ctx(void)
4949 {
5050 setup_libbpf();
5151
@@ -67,37 +67,37 @@ static void attach_bpf(struct bpf_program *prog) · 15 unmodified lines
6767 }
6868 }
6969
70−static void trigger_tp_setup()
70+static void trigger_tp_setup(void)
7171 {
7272 setup_ctx();
7373 attach_bpf(ctx.skel->progs.bench_trigger_tp);
7474 }
7575
76−static void trigger_rawtp_setup()
76+static void trigger_rawtp_setup(void)
7777 {
7878 setup_ctx();
7979 attach_bpf(ctx.skel->progs.bench_trigger_raw_tp);
8080 }
8181
82−static void trigger_kprobe_setup()
82+static void trigger_kprobe_setup(void)
8383 {
8484 setup_ctx();
8585 attach_bpf(ctx.skel->progs.bench_trigger_kprobe);
8686 }
8787
88−static void trigger_fentry_setup()
88+static void trigger_fentry_setup(void)
8989 {
9090 setup_ctx();
9191 attach_bpf(ctx.skel->progs.bench_trigger_fentry);
9292 }
9393
94−static void trigger_fentry_sleep_setup()
94+static void trigger_fentry_sleep_setup(void)
9595 {
9696 setup_ctx();
9797 attach_bpf(ctx.skel->progs.bench_trigger_fentry_sleep);
9898 }
9999
100−static void trigger_fmodret_setup()
100+static void trigger_fmodret_setup(void)
101101 {
102102 setup_ctx();
103103 attach_bpf(ctx.skel->progs.bench_trigger_fmodret);
@@ -183,22 +183,22 @@ static void usetup(bool use_retprobe, bool use_nop) · 79 unmodified lines
183183 ctx.skel->links.bench_trigger_uprobe = link;
184184 }
185185
186−static void uprobe_setup_with_nop()
186+static void uprobe_setup_with_nop(void)
187187 {
188188 usetup(false, true);
189189 }
190190
191−static void uretprobe_setup_with_nop()
191+static void uretprobe_setup_with_nop(void)
192192 {
193193 usetup(true, true);
194194 }
195195
196−static void uprobe_setup_without_nop()
196+static void uprobe_setup_without_nop(void)
197197 {
198198 usetup(false, false);
199199 }
200200
201−static void uretprobe_setup_without_nop()
201+static void uretprobe_setup_without_nop(void)
202202 {
203203 usetup(true, false);
204204 }
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+
4+source ./benchs/run_common.sh
5+
6+set -eufo pipefail
7+
8+for 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
12+done
tools/testing/selftests/bpf/config+2−0
@@ -38,7 +38,9 @@ CONFIG_IPV6_SIT=m · 37 unmodified lines
3838 CONFIG_BPF_JIT=y
3939 CONFIG_BPF_LSM=y
4040 CONFIG_SECURITY=y
41+CONFIG_RC_CORE=y
4142 CONFIG_LIRC=y
43+CONFIG_BPF_LIRC_MODE2=y
4244 CONFIG_IMA=y
4345 CONFIG_SECURITYFS=y
4446 CONFIG_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
3939 },
4040 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
4141 .matches = {
42− {1, "R1=ctx(id=0,off=0,imm=0)"},
43− {1, "R10=fp0"},
44− {1, "R3_w=inv2"},
45− {2, "R3_w=inv4"},
46− {3, "R3_w=inv8"},
47− {4, "R3_w=inv16"},
48− {5, "R3_w=inv32"},
42+ {0, "R1=ctx(id=0,off=0,imm=0)"},
43+ {0, "R10=fp0"},
44+ {0, "R3_w=inv2"},
45+ {1, "R3_w=inv4"},
46+ {2, "R3_w=inv8"},
47+ {3, "R3_w=inv16"},
48+ {4, "R3_w=inv32"},
4949 },
5050 },
5151 {
@@ -67,19 +67,19 @@ static struct bpf_align_test tests[] = { · 15 unmodified lines
6767 },
6868 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
6969 .matches = {
70− {1, "R1=ctx(id=0,off=0,imm=0)"},
71− {1, "R10=fp0"},
72− {1, "R3_w=inv1"},
73− {2, "R3_w=inv2"},
74− {3, "R3_w=inv4"},
75− {4, "R3_w=inv8"},
76− {5, "R3_w=inv16"},
77− {6, "R3_w=inv1"},
78− {7, "R4_w=inv32"},
79− {8, "R4_w=inv16"},
80− {9, "R4_w=inv8"},
81− {10, "R4_w=inv4"},
82− {11, "R4_w=inv2"},
70+ {0, "R1=ctx(id=0,off=0,imm=0)"},
71+ {0, "R10=fp0"},
72+ {0, "R3_w=inv1"},
73+ {1, "R3_w=inv2"},
74+ {2, "R3_w=inv4"},
75+ {3, "R3_w=inv8"},
76+ {4, "R3_w=inv16"},
77+ {5, "R3_w=inv1"},
78+ {6, "R4_w=inv32"},
79+ {7, "R4_w=inv16"},
80+ {8, "R4_w=inv8"},
81+ {9, "R4_w=inv4"},
82+ {10, "R4_w=inv2"},
8383 },
8484 },
8585 {
@@ -96,14 +96,14 @@ static struct bpf_align_test tests[] = { · 10 unmodified lines
9696 },
9797 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
9898 .matches = {
99− {1, "R1=ctx(id=0,off=0,imm=0)"},
100− {1, "R10=fp0"},
101− {1, "R3_w=inv4"},
102− {2, "R3_w=inv8"},
103− {3, "R3_w=inv10"},
104− {4, "R4_w=inv8"},
105− {5, "R4_w=inv12"},
106− {6, "R4_w=inv14"},
99+ {0, "R1=ctx(id=0,off=0,imm=0)"},
100+ {0, "R10=fp0"},
101+ {0, "R3_w=inv4"},
102+ {1, "R3_w=inv8"},
103+ {2, "R3_w=inv10"},
104+ {3, "R4_w=inv8"},
105+ {4, "R4_w=inv12"},
106+ {5, "R4_w=inv14"},
107107 },
108108 },
109109 {
@@ -118,12 +118,12 @@ static struct bpf_align_test tests[] = { · 8 unmodified lines
118118 },
119119 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
120120 .matches = {
121− {1, "R1=ctx(id=0,off=0,imm=0)"},
122− {1, "R10=fp0"},
121+ {0, "R1=ctx(id=0,off=0,imm=0)"},
122+ {0, "R10=fp0"},
123+ {0, "R3_w=inv7"},
123124 {1, "R3_w=inv7"},
124− {2, "R3_w=inv7"},
125− {3, "R3_w=inv14"},
126− {4, "R3_w=inv56"},
125+ {2, "R3_w=inv14"},
126+ {3, "R3_w=inv56"},
127127 },
128128 },
129129
@@ -161,19 +161,19 @@ static struct bpf_align_test tests[] = { · 31 unmodified lines
161161 },
162162 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
163163 .matches = {
164− {7, "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))"},
166− {8, "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))"},
168− {10, "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))"},
170− {18, "R3=pkt_end(id=0,off=0,imm=0)"},
171− {18, "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))"},
173− {20, "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))"},
175− {22, "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))"},
164+ {6, "R0_w=pkt(id=0,off=8,r=8,imm=0)"},
165+ {6, "R3_w=inv(id=0,umax_value=255,var_off=(0x0; 0xff))"},
166+ {7, "R3_w=inv(id=0,umax_value=510,var_off=(0x0; 0x1fe))"},
167+ {8, "R3_w=inv(id=0,umax_value=1020,var_off=(0x0; 0x3fc))"},
168+ {9, "R3_w=inv(id=0,umax_value=2040,var_off=(0x0; 0x7f8))"},
169+ {10, "R3_w=inv(id=0,umax_value=4080,var_off=(0x0; 0xff0))"},
170+ {12, "R3_w=pkt_end(id=0,off=0,imm=0)"},
171+ {17, "R4_w=inv(id=0,umax_value=255,var_off=(0x0; 0xff))"},
172+ {18, "R4_w=inv(id=0,umax_value=8160,var_off=(0x0; 0x1fe0))"},
173+ {19, "R4_w=inv(id=0,umax_value=4080,var_off=(0x0; 0xff0))"},
174+ {20, "R4_w=inv(id=0,umax_value=2040,var_off=(0x0; 0x7f8))"},
175+ {21, "R4_w=inv(id=0,umax_value=1020,var_off=(0x0; 0x3fc))"},
176+ {22, "R4_w=inv(id=0,umax_value=510,var_off=(0x0; 0x1fe))"},
177177 },
178178 },
179179 {
@@ -194,16 +194,16 @@ static struct bpf_align_test tests[] = { · 14 unmodified lines
194194 },
195195 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
196196 .matches = {
197− {7, "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))"},
199− {9, "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))"},
201− {11, "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))"},
203− {13, "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))"},
205− {15, "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))"},
197+ {6, "R3_w=inv(id=0,umax_value=255,var_off=(0x0; 0xff))"},
198+ {7, "R4_w=inv(id=1,umax_value=255,var_off=(0x0; 0xff))"},
199+ {8, "R4_w=inv(id=0,umax_value=255,var_off=(0x0; 0xff))"},
200+ {9, "R4_w=inv(id=1,umax_value=255,var_off=(0x0; 0xff))"},
201+ {10, "R4_w=inv(id=0,umax_value=510,var_off=(0x0; 0x1fe))"},
202+ {11, "R4_w=inv(id=1,umax_value=255,var_off=(0x0; 0xff))"},
203+ {12, "R4_w=inv(id=0,umax_value=1020,var_off=(0x0; 0x3fc))"},
204+ {13, "R4_w=inv(id=1,umax_value=255,var_off=(0x0; 0xff))"},
205+ {14, "R4_w=inv(id=0,umax_value=2040,var_off=(0x0; 0x7f8))"},
206+ {15, "R4_w=inv(id=0,umax_value=4080,var_off=(0x0; 0xff0))"},
207207 },
208208 },
209209 {
@@ -234,14 +234,14 @@ static struct bpf_align_test tests[] = { · 24 unmodified lines
234234 },
235235 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
236236 .matches = {
237− {4, "R5_w=pkt(id=0,off=0,r=0,imm=0)"},
238− {5, "R5_w=pkt(id=0,off=14,r=0,imm=0)"},
239− {6, "R4_w=pkt(id=0,off=14,r=0,imm=0)"},
240− {10, "R2=pkt(id=0,off=0,r=18,imm=0)"},
237+ {2, "R5_w=pkt(id=0,off=0,r=0,imm=0)"},
238+ {4, "R5_w=pkt(id=0,off=14,r=0,imm=0)"},
239+ {5, "R4_w=pkt(id=0,off=14,r=0,imm=0)"},
240+ {9, "R2=pkt(id=0,off=0,r=18,imm=0)"},
241241 {10, "R5=pkt(id=0,off=14,r=18,imm=0)"},
242242 {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))"},
243244 {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))"},
245245 },
246246 },
247247 {
@@ -296,8 +296,8 @@ static struct bpf_align_test tests[] = { · 48 unmodified lines
296296 /* Calculated offset in R6 has unknown value, but known
297297 * alignment of 4.
298298 */
299− {8, "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))"},
299+ {6, "R2_w=pkt(id=0,off=0,r=8,imm=0)"},
300+ {7, "R6_w=inv(id=0,umax_value=1020,var_off=(0x0; 0x3fc))"},
301301 /* Offset is added to packet pointer R5, resulting in
302302 * known fixed offset, and variable offset from R6.
303303 */
@@ -313,11 +313,11 @@ static struct bpf_align_test tests[] = { · 9 unmodified lines
313313 /* Variable offset is added to R5 packet pointer,
314314 * resulting in auxiliary alignment of 4.
315315 */
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))"},
317317 /* Constant offset is added to R5, resulting in
318318 * reg->off of 14.
319319 */
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))"},
321321 /* At the time the word size load is performed from R5,
322322 * its total fixed offset is NET_IP_ALIGN + reg->off
323323 * (14) which is 16. Then the variable offset is 4-byte
@@ -329,18 +329,18 @@ static struct bpf_align_test tests[] = { · 5 unmodified lines
329329 /* Constant offset is added to R5 packet pointer,
330330 * resulting in reg->off value of 14.
331331 */
332− {26, "R5_w=pkt(id=0,off=14,r=8"},
332+ {25, "R5_w=pkt(id=0,off=14,r=8"},
333333 /* Variable offset is added to R5, resulting in a
334334 * variable offset of (4n).
335335 */
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))"},
337337 /* 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))"},
339339 /* And once more we add a variable; resulting var_off
340340 * is still (4n), fixed offset is not changed.
341341 * Also, we create a new reg->id.
342342 */
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)"},
344344 /* At the time the word size load is performed from R5,
345345 * its total fixed offset is NET_IP_ALIGN + reg->off (18)
346346 * which is 20. Then the variable offset is (4n), so
@@ -386,13 +386,13 @@ static struct bpf_align_test tests[] = { · 39 unmodified lines
386386 /* Calculated offset in R6 has unknown value, but known
387387 * alignment of 4.
388388 */
389− {8, "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))"},
389+ {6, "R2_w=pkt(id=0,off=0,r=8,imm=0)"},
390+ {7, "R6_w=inv(id=0,umax_value=1020,var_off=(0x0; 0x3fc))"},
391391 /* 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))"},
393393 /* Packet pointer has (4n+2) offset */
394394 {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)"},
396396 /* At the time the word size load is performed from R5,
397397 * its total fixed offset is NET_IP_ALIGN + reg->off (0)
398398 * which is 2. Then the variable offset is (4n+2), so
@@ -403,12 +403,12 @@ static struct bpf_align_test tests[] = { · 4 unmodified lines
403403 /* Newly read value in R6 was shifted left by 2, so has
404404 * known alignment of 4.
405405 */
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))"},
407407 /* Added (4n) to packet pointer's (4n+2) var_off, giving
408408 * another (4n+2).
409409 */
410410 {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)"},
412412 /* At the time the word size load is performed from R5,
413413 * its total fixed offset is NET_IP_ALIGN + reg->off (0)
414414 * which is 2. Then the variable offset is (4n+2), so
@@ -448,18 +448,18 @@ static struct bpf_align_test tests[] = { · 33 unmodified lines
448448 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
449449 .result = REJECT,
450450 .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)"},
452452 /* (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)"},
454454 /* (4n) + 14 == (4n+2). We blow our bounds, because
455455 * the add could overflow.
456456 */
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)"},
458458 /* Checked s>=0 */
459459 {9, "R5=inv(id=0,umin_value=2,umax_value=9223372036854775806,var_off=(0x2; 0x7ffffffffffffffc)"},
460460 /* packet pointer + nonnegative (4n+2) */
461461 {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)"},
463463 /* NET_IP_ALIGN + (4n+2) == (4n), alignment is fine.
464464 * We checked the bounds, but it might have been able
465465 * to overflow if the packet pointer started in the
@@ -502,14 +502,14 @@ static struct bpf_align_test tests[] = { · 36 unmodified lines
502502 /* Calculated offset in R6 has unknown value, but known
503503 * alignment of 4.
504504 */
505− {7, "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))"},
505+ {6, "R2_w=pkt(id=0,off=0,r=8,imm=0)"},
506+ {8, "R6_w=inv(id=0,umax_value=1020,var_off=(0x0; 0x3fc))"},
507507 /* 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))"},
509509 /* 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))"},
511511 /* 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)"},
513513 /* Checked s>= 0 */
514514 {14, "R6=inv(id=0,umin_value=2,umax_value=1034,var_off=(0x2; 0x7fc))"},
515515 /* At the time the word size load is performed from R5,
@@ -556,14 +556,14 @@ static struct bpf_align_test tests[] = { · 40 unmodified lines
556556 /* Calculated offset in R6 has unknown value, but known
557557 * alignment of 4.
558558 */
559− {7, "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))"},
559+ {6, "R2_w=pkt(id=0,off=0,r=8,imm=0)"},
560+ {9, "R6_w=inv(id=0,umax_value=60,var_off=(0x0; 0x3c))"},
561561 /* 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))"},
563563 /* Subtracting from packet pointer overflows ubounds */
564564 {13, "R5_w=pkt(id=2,off=0,r=8,umin_value=18446744073709551542,umax_value=18446744073709551602,var_off=(0xffffffffffffff82; 0x7c)"},
565565 /* 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))"},
567567 /* Adding it to packet pointer gives nice bounds again */
568568 {16, "R5_w=pkt(id=3,off=0,r=0,umin_value=2,umax_value=1082,var_off=(0x2; 0xfffffffc)"},
569569 /* 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
625625 line_ptr = strtok(bpf_vlog_copy, "\n");
626626 for (i = 0; i < MAX_MATCHES; i++) {
627627 struct bpf_reg_match m = test->matches[i];
628+ int tmp;
628629
629630 if (!m.match)
630631 break;
631632 while (line_ptr) {
632633 cur_line = -1;
633634 sscanf(line_ptr, "%u: ", &cur_line);
635+ if (cur_line == -1)
636+ sscanf(line_ptr, "from %u to %u: ", &tmp, &cur_line);
634637 if (cur_line == m.line)
635638 break;
636639 line_ptr = strtok(NULL, "\n");
@@ -642,7 +645,19 @@ static int do_test_single(struct bpf_align_test *test) · 5 unmodified lines
642645 printf("%s", bpf_vlog);
643646 break;
644647 }
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+ */
645654 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)) {
646661 printf("Failed to find match %u: %s\n",
647662 m.line, m.match);
648663 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
6565 if (CHECK_FAIL(err))
6666 goto done;
6767
68− prog = bpf_object__find_program_by_title(objs[i],
69− "raw_tp/sys_enter");
68+ prog = bpf_object__find_program_by_name(objs[i],
69+ "test_obj_id");
7070 if (CHECK_FAIL(!prog))
7171 goto done;
7272 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
217217 static int libbpf_debug_print(enum libbpf_print_level level,
218218 const char *format, va_list args)
219219 {
220− const char *log_buf;
220+ const char *prog_name, *log_buf;
221221
222222 if (level != LIBBPF_WARN ||
223223 !strstr(format, "-- BEGIN PROG LOAD LOG --")) {
@@ -225,15 +225,14 @@ static int libbpf_debug_print(enum libbpf_print_level level, · 1 unmodified line
225225 return 0;
226226 }
227227
228− /* skip prog_name */
229− va_arg(args, char *);
228+ prog_name = va_arg(args, char *);
230229 log_buf = va_arg(args, char *);
231230 if (!log_buf)
232231 goto out;
233232 if (err_str && strstr(log_buf, err_str) != NULL)
234233 found = true;
235234 out:
236− printf(format, log_buf);
235+ printf(format, prog_name, log_buf);
237236 return 0;
238237 }
239238
tools/testing/selftests/bpf/prog_tests/btf.c+0−1
@@ -22,7 +22,6 @@ · 21 unmodified lines
2222 #include <bpf/libbpf.h>
2323 #include <bpf/btf.h>
2424
25−#include "bpf_rlimit.h"
2625 #include "bpf_util.h"
2726 #include "../test_btf.h"
2827 #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
6767 goto close_bpf_object;
6868 }
6969
70− prog = bpf_object__find_program_by_title(obj, v4 ?
71− "cgroup/connect4" :
72− "cgroup/connect6");
70+ prog = bpf_object__find_program_by_name(obj, v4 ?
71+ "connect4" :
72+ "connect6");
7373 if (CHECK(!prog, "find_prog", "connect prog not found\n")) {
7474 err = -EIO;
7575 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
8383 goto close_bpf_object;
8484 }
8585
86− prog = bpf_object__find_program_by_title(obj, v4 ?
87− "cgroup/getpeername4" :
88− "cgroup/getpeername6");
86+ prog = bpf_object__find_program_by_name(obj, v4 ?
87+ "getpeername4" :
88+ "getpeername6");
8989 if (CHECK(!prog, "find_prog", "getpeername prog not found\n")) {
9090 err = -EIO;
9191 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
9999 goto close_bpf_object;
100100 }
101101
102− prog = bpf_object__find_program_by_title(obj, v4 ?
103− "cgroup/getsockname4" :
104− "cgroup/getsockname6");
102+ prog = bpf_object__find_program_by_name(obj, v4 ?
103+ "getsockname4" :
104+ "getsockname6");
105105 if (CHECK(!prog, "find_prog", "getsockname prog not found\n")) {
106106 err = -EIO;
107107 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
1010
1111 #define STRUCT_TO_CHAR_PTR(struct_name) (const char *)&(struct struct_name)
1212
13−#define MODULES_CASE(name, sec_name, tp_name) { \
13+#define MODULES_CASE(name, pg_name, tp_name) { \
1414 .case_name = name, \
1515 .bpf_obj_file = "test_core_reloc_module.o", \
1616 .btf_src_file = NULL, /* find in kernel module BTFs */ \
@@ -28,7 +28,7 @@ static int duration = 0; · 11 unmodified lines
2828 .comm_len = sizeof("test_progs"), \
2929 }, \
3030 .output_len = sizeof(struct core_reloc_module_output), \
31− .prog_sec_name = sec_name, \
31+ .prog_name = pg_name, \
3232 .raw_tp_name = tp_name, \
3333 .trigger = __trigger_module_test_read, \
3434 .needs_testmod = true, \
@@ -43,7 +43,9 @@ static int duration = 0; · 8 unmodified lines
4343 #define FLAVORS_CASE_COMMON(name) \
4444 .case_name = #name, \
4545 .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" \
4749
4850 #define FLAVORS_CASE(name) { \
4951 FLAVORS_CASE_COMMON(name), \
@@ -66,7 +68,9 @@ static int duration = 0; · 16 unmodified lines
6668 #define NESTING_CASE_COMMON(name) \
6769 .case_name = #name, \
6870 .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" \
7074
7175 #define NESTING_CASE(name) { \
7276 NESTING_CASE_COMMON(name), \
@@ -91,7 +95,9 @@ static int duration = 0; · 18 unmodified lines
9195 #define ARRAYS_CASE_COMMON(name) \
9296 .case_name = #name, \
9397 .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" \
95101
96102 #define ARRAYS_CASE(name) { \
97103 ARRAYS_CASE_COMMON(name), \
@@ -123,7 +129,9 @@ static int duration = 0; · 25 unmodified lines
123129 #define PRIMITIVES_CASE_COMMON(name) \
124130 .case_name = #name, \
125131 .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" \
127135
128136 #define PRIMITIVES_CASE(name) { \
129137 PRIMITIVES_CASE_COMMON(name), \
@@ -158,6 +166,8 @@ static int duration = 0; · 28 unmodified lines
158166 .e = 5, .f = 6, .g = 7, .h = 8, \
159167 }, \
160168 .output_len = sizeof(struct core_reloc_mods_output), \
169+ .raw_tp_name = "sys_enter", \
170+ .prog_name = "test_core_mods", \
161171 }
162172
163173 #define PTR_AS_ARR_CASE(name) { \
@@ -174,6 +184,8 @@ static int duration = 0; · 10 unmodified lines
174184 .a = 3, \
175185 }, \
176186 .output_len = sizeof(struct core_reloc_ptr_as_arr), \
187+ .raw_tp_name = "sys_enter", \
188+ .prog_name = "test_core_ptr_as_arr", \
177189 }
178190
179191 #define INTS_DATA(struct_name) STRUCT_TO_CHAR_PTR(struct_name) { \
@@ -190,7 +202,9 @@ static int duration = 0; · 10 unmodified lines
190202 #define INTS_CASE_COMMON(name) \
191203 .case_name = #name, \
192204 .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"
194208
195209 #define INTS_CASE(name) { \
196210 INTS_CASE_COMMON(name), \
@@ -208,7 +222,9 @@ static int duration = 0; · 11 unmodified lines
208222 #define FIELD_EXISTS_CASE_COMMON(name) \
209223 .case_name = #name, \
210224 .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"
212228
213229 #define BITFIELDS_CASE_COMMON(objfile, test_name_prefix, name) \
214230 .case_name = test_name_prefix#name, \
@@ -223,6 +239,8 @@ static int duration = 0; · 8 unmodified lines
223239 .output = STRUCT_TO_CHAR_PTR(core_reloc_bitfields_output) \
224240 __VA_ARGS__, \
225241 .output_len = sizeof(struct core_reloc_bitfields_output), \
242+ .raw_tp_name = "sys_enter", \
243+ .prog_name = "test_core_bitfields", \
226244 }, { \
227245 BITFIELDS_CASE_COMMON("test_core_reloc_bitfields_direct.o", \
228246 "direct:", name), \
@@ -231,7 +249,7 @@ static int duration = 0; · 2 unmodified lines
231249 .output = STRUCT_TO_CHAR_PTR(core_reloc_bitfields_output) \
232250 __VA_ARGS__, \
233251 .output_len = sizeof(struct core_reloc_bitfields_output), \
234− .prog_sec_name = "tp_btf/sys_enter", \
252+ .prog_name = "test_core_bitfields_direct", \
235253 }
236254
237255
@@ -239,17 +257,21 @@ static int duration = 0; · 1 unmodified line
239257 BITFIELDS_CASE_COMMON("test_core_reloc_bitfields_probed.o", \
240258 "probed:", name), \
241259 .fails = true, \
260+ .raw_tp_name = "sys_enter", \
261+ .prog_name = "test_core_bitfields", \
242262 }, { \
243263 BITFIELDS_CASE_COMMON("test_core_reloc_bitfields_direct.o", \
244264 "direct:", name), \
245− .prog_sec_name = "tp_btf/sys_enter", \
246265 .fails = true, \
266+ .prog_name = "test_core_bitfields_direct", \
247267 }
248268
249269 #define SIZE_CASE_COMMON(name) \
250270 .case_name = #name, \
251271 .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"
253275
254276 #define SIZE_OUTPUT_DATA(type) \
255277 STRUCT_TO_CHAR_PTR(core_reloc_size_output) { \
@@ -277,8 +299,10 @@ static int duration = 0; · 21 unmodified lines
277299
278300 #define TYPE_BASED_CASE_COMMON(name) \
279301 .case_name = #name, \
280− .bpf_obj_file = "test_core_reloc_type_based.o", \
281− .btf_src_file = "btf__core_reloc_" #name ".o" \
302+ .bpf_obj_file = "test_core_reloc_type_based.o", \
303+ .btf_src_file = "btf__core_reloc_" #name ".o", \
304+ .raw_tp_name = "sys_enter", \
305+ .prog_name = "test_core_type_based"
282306
283307 #define TYPE_BASED_CASE(name, ...) { \
284308 TYPE_BASED_CASE_COMMON(name), \
@@ -295,7 +319,9 @@ static int duration = 0; · 10 unmodified lines
295319 #define TYPE_ID_CASE_COMMON(name) \
296320 .case_name = #name, \
297321 .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"
299325
300326 #define TYPE_ID_CASE(name, setup_fn) { \
301327 TYPE_ID_CASE_COMMON(name), \
@@ -312,7 +338,9 @@ static int duration = 0; · 10 unmodified lines
312338 #define ENUMVAL_CASE_COMMON(name) \
313339 .case_name = #name, \
314340 .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"
316344
317345 #define ENUMVAL_CASE(name, ...) { \
318346 ENUMVAL_CASE_COMMON(name), \
@@ -342,7 +370,7 @@ struct core_reloc_test_case { · 23 unmodified lines
342370 bool fails;
343371 bool needs_testmod;
344372 bool relaxed_core_relocs;
345− const char *prog_sec_name;
373+ const char *prog_name;
346374 const char *raw_tp_name;
347375 setup_test_fn setup;
348376 trigger_test_fn trigger;
@@ -497,11 +525,13 @@ static struct core_reloc_test_case test_cases[] = { · 148 unmodified lines
497525 .comm_len = sizeof("test_progs"),
498526 },
499527 .output_len = sizeof(struct core_reloc_kernel_output),
528+ .raw_tp_name = "sys_enter",
529+ .prog_name = "test_core_kernel",
500530 },
501531
502532 /* 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"),
504− MODULES_CASE("module_direct", "tp_btf/bpf_testmod_test_read", NULL),
533+ MODULES_CASE("module_probed", "test_core_module_probed", "bpf_testmod_test_read"),
534+ MODULES_CASE("module_direct", "test_core_module_direct", NULL),
505535
506536 /* validate BPF program can use multiple flavors to match against
507537 * single target BTF type
@@ -580,6 +610,8 @@ static struct core_reloc_test_case test_cases[] = { · 72 unmodified lines
580610 .c = 0, /* BUG in clang, should be 3 */
581611 },
582612 .output_len = sizeof(struct core_reloc_misc_output),
613+ .raw_tp_name = "sys_enter",
614+ .prog_name = "test_core_misc",
583615 },
584616
585617 /* validate field existence checks */
@@ -848,14 +880,9 @@ void test_core_reloc(void) · 262 unmodified lines
848880 if (!ASSERT_OK_PTR(obj, "obj_open"))
849881 goto cleanup;
850882
851− probe_name = "raw_tracepoint/sys_enter";
852− tp_name = "sys_enter";
853− if (test_case->prog_sec_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);
883+ probe_name = test_case->prog_name;
884+ tp_name = test_case->raw_tp_name; /* NULL for tp_btf */
885+ prog = bpf_object__find_program_by_name(obj, probe_name);
859886 if (CHECK(!prog, "find_probe",
860887 "prog '%s' not found\n", probe_name))
861888 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
101101
102102 for (i = 0; i < prog_cnt; i++) {
103103 struct bpf_link_info link_info;
104+ struct bpf_program *pos;
105+ const char *pos_sec_name;
104106 char *tgt_name;
105107 __s32 btf_id;
106108
@@ -109,7 +111,14 @@ static void test_fexit_bpf2bpf_common(const char *obj_file, · 2 unmodified lines
109111 goto close_prog;
110112 btf_id = btf__find_by_name_kind(btf, tgt_name + 1, BTF_KIND_FUNC);
111113
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+ }
113122 if (!ASSERT_OK_PTR(prog[i], prog_name[i]))
114123 goto close_prog;
115124
@@ -211,8 +220,8 @@ static void test_func_replace_verify(void) · 95 unmodified lines
211220
212221 static int test_second_attach(struct bpf_object *obj)
213222 {
214− const char *prog_name = "freplace/get_constant";
215− const char *tgt_name = prog_name + 9; /* cut off freplace/ */
223+ const char *prog_name = "security_new_get_constant";
224+ const char *tgt_name = "get_constant";
216225 const char *tgt_obj_file = "./test_pkt_access.o";
217226 struct bpf_program *prog = NULL;
218227 struct bpf_object *tgt_obj;
@@ -220,7 +229,7 @@ static int test_second_attach(struct bpf_object *obj) · 1 unmodified line
220229 struct bpf_link *link;
221230 int err = 0, tgt_fd;
222231
223− prog = bpf_object__find_program_by_title(obj, prog_name);
232+ prog = bpf_object__find_program_by_name(obj, prog_name);
224233 if (CHECK(!prog, "find_prog", "prog %s not found\n", prog_name))
225234 return -ENOENT;
226235
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+
5+void 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+
42+cleanup:
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
8989 {
9090 const char *file = "./test_get_stack_rawtp.o";
9191 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";
9393 int i, err, prog_fd, exp_cnt = MAX_CNT_RAWTP;
9494 struct perf_buffer *pb = NULL;
9595 struct bpf_link *link = NULL;
@@ -107,7 +107,7 @@ void test_get_stack_raw_tp(void) · 11 unmodified lines
107107 if (CHECK(err, "prog_load raw tp", "err %d errno %d\n", err, errno))
108108 return;
109109
110− prog = bpf_object__find_program_by_title(obj, prog_name);
110+ prog = bpf_object__find_program_by_name(obj, prog_name);
111111 if (CHECK(!prog, "find_probe", "prog '%s' not found\n", prog_name))
112112 goto close_prog;
113113
tools/testing/selftests/bpf/prog_tests/ksyms_btf.c+14−0
@@ -8,6 +8,7 @@ · 7 unmodified lines
88 #include "test_ksyms_btf_null_check.skel.h"
99 #include "test_ksyms_weak.skel.h"
1010 #include "test_ksyms_weak.lskel.h"
11+#include "test_ksyms_btf_write_check.skel.h"
1112
1213 static int duration;
1314
@@ -137,6 +138,16 @@ cleanup: · 123 unmodified lines
137138 test_ksyms_weak_lskel__destroy(skel);
138139 }
139140
141+static 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+
140151 void test_ksyms_btf(void)
141152 {
142153 int percpu_datasec;
@@ -167,4 +178,7 @@ void test_ksyms_btf(void) · 24 unmodified lines
167178
168179 if (test__start_subtest("weak_ksyms_lskel"))
169180 test_weak_syms_lskel();
181+
182+ if (test__start_subtest("write_check"))
183+ test_write_check();
170184 }
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+
7+void 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+
41+cleanup:
42+ btf__free(btf);
43+}
44+
45+void 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+
79+cleanup:
80+ btf__free(btf);
81+}
82+
83+void 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
1818 #include <netinet/in.h>
1919 #include <bpf/bpf.h>
2020 #include <bpf/libbpf.h>
21−#include "bpf_rlimit.h"
2221 #include "bpf_util.h"
2322
2423 #include "test_progs.h"
tools/testing/selftests/bpf/prog_tests/sk_lookup.c+0−1
@@ -30,7 +30,6 @@ · 29 unmodified lines
3030 #include <bpf/bpf.h>
3131
3232 #include "test_progs.h"
33−#include "bpf_rlimit.h"
3433 #include "bpf_util.h"
3534 #include "cgroup_helpers.h"
3635 #include "network_helpers.h"
tools/testing/selftests/bpf/prog_tests/sock_fields.c+0−1
@@ -15,7 +15,6 @@ · 14 unmodified lines
1515 #include "network_helpers.h"
1616 #include "cgroup_helpers.h"
1717 #include "test_progs.h"
18−#include "bpf_rlimit.h"
1918 #include "test_sock_fields.skel.h"
2019
2120 enum 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
136136 return fd;
137137 }
138138
139−static int prog_attach(struct bpf_object *obj, int cgroup_fd, const char *title)
139+static int prog_attach(struct bpf_object *obj, int cgroup_fd, const char *title,
140+ const char *prog_name)
140141 {
141142 enum bpf_attach_type attach_type;
142143 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
145146
146147 err = libbpf_prog_type_by_name(title, &prog_type, &attach_type);
147148 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);
149150 return -1;
150151 }
151152
152− prog = bpf_object__find_program_by_title(obj, title);
153+ prog = bpf_object__find_program_by_name(obj, prog_name);
153154 if (!prog) {
154− log_err("Failed to find %s BPF program", title);
155+ log_err("Failed to find %s BPF program", prog_name);
155156 return -1;
156157 }
157158
158159 err = bpf_prog_attach(bpf_program__fd(prog), cgroup_fd,
159160 attach_type, 0);
160161 if (err) {
161− log_err("Failed to attach %s BPF program", title);
162+ log_err("Failed to attach %s BPF program", prog_name);
162163 return -1;
163164 }
164165
@@ -181,11 +182,11 @@ static void run_test(int cgroup_fd) · 16 unmodified lines
181182 if (!ASSERT_OK(err, "obj_load"))
182183 goto close_bpf_object;
183184
184− err = prog_attach(obj, cgroup_fd, "cgroup/getsockopt");
185+ err = prog_attach(obj, cgroup_fd, "cgroup/getsockopt", "_getsockopt");
185186 if (CHECK_FAIL(err))
186187 goto close_bpf_object;
187188
188− err = prog_attach(obj, cgroup_fd, "cgroup/setsockopt");
189+ err = prog_attach(obj, cgroup_fd, "cgroup/setsockopt", "_setsockopt");
189190 if (CHECK_FAIL(err))
190191 goto close_bpf_object;
191192
tools/testing/selftests/bpf/prog_tests/stacktrace_map.c+2−2
@@ -4,7 +4,7 @@ · 3 unmodified lines
44 void test_stacktrace_map(void)
55 {
66 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";
88 int err, prog_fd, stack_trace_len;
99 const char *file = "./test_stacktrace_map.o";
1010 __u32 key, val, duration = 0;
@@ -16,7 +16,7 @@ void test_stacktrace_map(void) · 5 unmodified lines
1616 if (CHECK(err, "prog_load", "err %d errno %d\n", err, errno))
1717 return;
1818
19− prog = bpf_object__find_program_by_title(obj, prog_name);
19+ prog = bpf_object__find_program_by_name(obj, prog_name);
2020 if (CHECK(!prog, "find_prog", "prog '%s' not found\n", prog_name))
2121 goto close_prog;
2222
tools/testing/selftests/bpf/prog_tests/stacktrace_map_raw_tp.c+2−2
@@ -3,7 +3,7 @@ · 2 unmodified lines
33
44 void test_stacktrace_map_raw_tp(void)
55 {
6− const char *prog_name = "tracepoint/sched/sched_switch";
6+ const char *prog_name = "oncpu";
77 int control_map_fd, stackid_hmap_fd, stackmap_fd;
88 const char *file = "./test_stacktrace_map.o";
99 __u32 key, val, duration = 0;
@@ -16,7 +16,7 @@ void test_stacktrace_map_raw_tp(void) · 6 unmodified lines
1616 if (CHECK(err, "prog_load raw tp", "err %d errno %d\n", err, errno))
1717 return;
1818
19− prog = bpf_object__find_program_by_title(obj, prog_name);
19+ prog = bpf_object__find_program_by_name(obj, prog_name);
2020 if (CHECK(!prog, "find_prog", "prog '%s' not found\n", prog_name))
2121 goto close_prog;
2222
tools/testing/selftests/bpf/prog_tests/test_local_storage.c+6−14
@@ -28,10 +28,6 @@ static unsigned int duration; · 27 unmodified lines
2828 struct storage {
2929 void *inode;
3030 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;
3531 };
3632
3733 /* 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
6662
6763 static bool check_syscall_operations(int map_fd, int obj_fd)
6864 {
69− struct storage val = { .value = TEST_STORAGE_VALUE, .lock = { 0 } },
70− lookup_val = { .value = 0, .lock = { 0 } };
65+ struct storage val = { .value = TEST_STORAGE_VALUE },
66+ lookup_val = { .value = 0 };
7167 int err;
7268
7369 /* Looking up an existing element should fail initially */
74− err = bpf_map_lookup_elem_flags(map_fd, &obj_fd, &lookup_val,
75− BPF_F_LOCK);
70+ err = bpf_map_lookup_elem_flags(map_fd, &obj_fd, &lookup_val, 0);
7671 if (CHECK(!err || errno != ENOENT, "bpf_map_lookup_elem",
7772 "err:%d errno:%d\n", err, errno))
7873 return false;
7974
8075 /* Create a new element */
81− err = bpf_map_update_elem(map_fd, &obj_fd, &val,
82− BPF_NOEXIST | BPF_F_LOCK);
76+ err = bpf_map_update_elem(map_fd, &obj_fd, &val, BPF_NOEXIST);
8377 if (CHECK(err < 0, "bpf_map_update_elem", "err:%d errno:%d\n", err,
8478 errno))
8579 return false;
8680
8781 /* Lookup the newly created element */
88− err = bpf_map_lookup_elem_flags(map_fd, &obj_fd, &lookup_val,
89− BPF_F_LOCK);
82+ err = bpf_map_lookup_elem_flags(map_fd, &obj_fd, &lookup_val, 0);
9083 if (CHECK(err < 0, "bpf_map_lookup_elem", "err:%d errno:%d", err,
9184 errno))
9285 return false;
@@ -102,8 +95,7 @@ static bool check_syscall_operations(int map_fd, int obj_fd) · 9 unmodified lines
10295 return false;
10396
10497 /* The lookup should fail, now that the element has been deleted */
105− err = bpf_map_lookup_elem_flags(map_fd, &obj_fd, &lookup_val,
106− BPF_F_LOCK);
98+ err = bpf_map_lookup_elem_flags(map_fd, &obj_fd, &lookup_val, 0);
10799 if (CHECK(!err || errno != ENOENT, "bpf_map_lookup_elem",
108100 "err:%d errno:%d\n", err, errno))
109101 return false;
tools/testing/selftests/bpf/prog_tests/test_overhead.c+10−10
@@ -56,11 +56,11 @@ static void setaffinity(void) · 55 unmodified lines
5656
5757 void test_test_overhead(void)
5858 {
59− const char *kprobe_name = "kprobe/__set_task_comm";
60− const char *kretprobe_name = "kretprobe/__set_task_comm";
61− const char *raw_tp_name = "raw_tp/task_rename";
62− const char *fentry_name = "fentry/__set_task_comm";
63− const char *fexit_name = "fexit/__set_task_comm";
59+ const char *kprobe_name = "prog1";
60+ const char *kretprobe_name = "prog2";
61+ const char *raw_tp_name = "prog3";
62+ const char *fentry_name = "prog4";
63+ const char *fexit_name = "prog5";
6464 const char *kprobe_func = "__set_task_comm";
6565 struct bpf_program *kprobe_prog, *kretprobe_prog, *raw_tp_prog;
6666 struct bpf_program *fentry_prog, *fexit_prog;
@@ -76,23 +76,23 @@ void test_test_overhead(void) · 9 unmodified lines
7676 if (!ASSERT_OK_PTR(obj, "obj_open_file"))
7777 return;
7878
79− kprobe_prog = bpf_object__find_program_by_title(obj, kprobe_name);
79+ kprobe_prog = bpf_object__find_program_by_name(obj, kprobe_name);
8080 if (CHECK(!kprobe_prog, "find_probe",
8181 "prog '%s' not found\n", kprobe_name))
8282 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);
8484 if (CHECK(!kretprobe_prog, "find_probe",
8585 "prog '%s' not found\n", kretprobe_name))
8686 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);
8888 if (CHECK(!raw_tp_prog, "find_probe",
8989 "prog '%s' not found\n", raw_tp_name))
9090 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);
9292 if (CHECK(!fentry_prog, "find_probe",
9393 "prog '%s' not found\n", fentry_name))
9494 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);
9696 if (CHECK(!fexit_prog, "find_probe",
9797 "prog '%s' not found\n", fexit_name))
9898 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+
6+static 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+ */
24+static 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+
44+static 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);
87+out:
88+ strncmp_test__destroy(skel);
89+}
90+
91+static 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+
113+static 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+
135+static 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+
157+void 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
3535 struct bpf_program *prog;
3636 int duration = 0;
3737
38− prog = bpf_object__find_program_by_title(obj, name);
38+ prog = bpf_object__find_program_by_name(obj, name);
3939 if (CHECK(!prog, "find_probe", "prog '%s' not found\n", name))
4040 return ERR_PTR(-EINVAL);
4141 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
4444 /* TODO: use different target function to run in concurrent mode */
4545 void serial_test_trampoline_count(void)
4646 {
47− const char *fentry_name = "fentry/__set_task_comm";
48− const char *fexit_name = "fexit/__set_task_comm";
47+ const char *fentry_name = "prog1";
48+ const char *fexit_name = "prog2";
4949 const char *object = "test_trampoline_count.o";
5050 struct inst inst[MAX_TRAMP_PROGS] = {};
5151 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+
7+char _license[] SEC("license") = "GPL";
8+
9+__u64 test1_result = 0;
10+SEC("fentry/bpf_fentry_test1")
11+int 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;
43+SEC("fexit/bpf_fentry_test2")
44+int 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;
70+SEC("fmod_ret/bpf_modify_return_test")
71+int 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;
99+SEC("fexit/bpf_modify_return_test")
100+int 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
2020 struct local_storage {
2121 struct inode *exec_inode;
2222 __u32 value;
23− struct bpf_spin_lock lock;
2423 };
2524
2625 struct {
@@ -58,9 +57,7 @@ int BPF_PROG(unlink_hook, struct inode *dir, struct dentry *victim) · 31 unmodified lines
5857 bpf_get_current_task_btf(), 0, 0);
5958 if (storage) {
6059 /* Don't let an executable delete itself */
61− bpf_spin_lock(&storage->lock);
6260 is_self_unlink = storage->exec_inode == victim->d_inode;
63− bpf_spin_unlock(&storage->lock);
6461 if (is_self_unlink)
6562 return -EPERM;
6663 }
@@ -68,7 +65,7 @@ int BPF_PROG(unlink_hook, struct inode *dir, struct dentry *victim) · 1 unmodified line
6865 return 0;
6966 }
7067
71−SEC("lsm/inode_rename")
68+SEC("lsm.s/inode_rename")
7269 int BPF_PROG(inode_rename, struct inode *old_dir, struct dentry *old_dentry,
7370 struct inode *new_dir, struct dentry *new_dentry,
7471 unsigned int flags)
@@ -89,10 +86,8 @@ int BPF_PROG(inode_rename, struct inode *old_dir, struct dentry *old_dentry, · 14 unmodified lines
8986 if (!storage)
9087 return 0;
9188
92− bpf_spin_lock(&storage->lock);
9389 if (storage->value != DUMMY_STORAGE_VALUE)
9490 inode_storage_result = -1;
95− bpf_spin_unlock(&storage->lock);
9691
9792 err = bpf_inode_storage_delete(&inode_storage_map, old_dentry->d_inode);
9893 if (!err)
@@ -101,7 +96,7 @@ int BPF_PROG(inode_rename, struct inode *old_dir, struct dentry *old_dentry, · 2 unmodified lines
10196 return 0;
10297 }
10398
104−SEC("lsm/socket_bind")
99+SEC("lsm.s/socket_bind")
105100 int BPF_PROG(socket_bind, struct socket *sock, struct sockaddr *address,
106101 int addrlen)
107102 {
@@ -117,10 +112,8 @@ int BPF_PROG(socket_bind, struct socket *sock, struct sockaddr *address, · 9 unmodified lines
117112 if (!storage)
118113 return 0;
119114
120− bpf_spin_lock(&storage->lock);
121115 if (storage->value != DUMMY_STORAGE_VALUE)
122116 sk_storage_result = -1;
123− bpf_spin_unlock(&storage->lock);
124117
125118 err = bpf_sk_storage_delete(&sk_storage_map, sock->sk);
126119 if (!err)
@@ -129,7 +122,7 @@ int BPF_PROG(socket_bind, struct socket *sock, struct sockaddr *address, · 2 unmodified lines
129122 return 0;
130123 }
131124
132−SEC("lsm/socket_post_create")
125+SEC("lsm.s/socket_post_create")
133126 int BPF_PROG(socket_post_create, struct socket *sock, int family, int type,
134127 int protocol, int kern)
135128 {
@@ -144,9 +137,7 @@ int BPF_PROG(socket_post_create, struct socket *sock, int family, int type, · 8 unmodified lines
144137 if (!storage)
145138 return 0;
146139
147− bpf_spin_lock(&storage->lock);
148140 storage->value = DUMMY_STORAGE_VALUE;
149− bpf_spin_unlock(&storage->lock);
150141
151142 return 0;
152143 }
@@ -154,7 +145,7 @@ int BPF_PROG(socket_post_create, struct socket *sock, int family, int type, · 1 unmodified line
154145 /* This uses the local storage to remember the inode of the binary that a
155146 * process was originally executing.
156147 */
157−SEC("lsm/bprm_committed_creds")
148+SEC("lsm.s/bprm_committed_creds")
158149 void BPF_PROG(exec, struct linux_binprm *bprm)
159150 {
160151 __u32 pid = bpf_get_current_pid_tgid() >> 32;
@@ -166,18 +157,13 @@ void BPF_PROG(exec, struct linux_binprm *bprm) · 5 unmodified lines
166157 storage = bpf_task_storage_get(&task_storage_map,
167158 bpf_get_current_task_btf(), 0,
168159 BPF_LOCAL_STORAGE_GET_F_CREATE);
169− if (storage) {
170− bpf_spin_lock(&storage->lock);
160+ if (storage)
171161 storage->exec_inode = bprm->file->f_inode;
172− bpf_spin_unlock(&storage->lock);
173− }
174162
175163 storage = bpf_inode_storage_get(&inode_storage_map, bprm->file->f_inode,
176164 0, BPF_LOCAL_STORAGE_GET_F_CREATE);
177165 if (!storage)
178166 return;
179167
180− bpf_spin_lock(&storage->lock);
181168 storage->value = DUMMY_STORAGE_VALUE;
182− bpf_spin_unlock(&storage->lock);
183169 }
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 */
11+const volatile unsigned int cmp_str_len = 1;
12+const char target[STRNCMP_STR_SZ];
13+
14+long hits = 0;
15+char str[STRNCMP_STR_SZ];
16+
17+char _license[] SEC("license") = "GPL";
18+
19+static __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+
35+SEC("tp/syscalls/sys_enter_getpgid")
36+int 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+
43+SEC("tp/syscalls/sys_enter_getpgid")
44+int 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+
11+const char target[STRNCMP_STR_SZ] = "EEEEEEE";
12+char str[STRNCMP_STR_SZ];
13+int cmp_ret = 0;
14+int target_pid = 0;
15+
16+const char no_str_target[STRNCMP_STR_SZ] = "12345678";
17+char writable_target[STRNCMP_STR_SZ];
18+unsigned int no_const_str_size = STRNCMP_STR_SZ;
19+
20+char _license[] SEC("license") = "GPL";
21+
22+SEC("tp/syscalls/sys_enter_nanosleep")
23+int 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+
32+SEC("tp/syscalls/sys_enter_nanosleep")
33+int 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+
40+SEC("tp/syscalls/sys_enter_nanosleep")
41+int 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+
48+SEC("tp/syscalls/sys_enter_nanosleep")
49+int 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+
8+extern const int bpf_prog_active __ksym; /* int type global var. */
9+
10+SEC("raw_tp/sys_enter")
11+int 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+
29+char _license[] SEC("license") = "GPL";
tools/testing/selftests/bpf/test_cpp.cpp+8−1
@@ -7,9 +7,15 @@ · 6 unmodified lines
77
88 /* do nothing, just make sure we can link successfully */
99
10+static void dump_printf(void *ctx, const char *fmt, va_list args)
11+{
12+}
13+
1014 int main(int argc, char *argv[])
1115 {
16+ struct btf_dump_opts opts = { };
1217 struct test_core_extern *skel;
18+ struct btf *btf;
1319
1420 /* libbpf.h */
1521 libbpf_set_print(NULL);
@@ -18,7 +24,8 @@ int main(int argc, char *argv[]) · 2 unmodified lines
1824 bpf_prog_get_fd_by_id(0);
1925
2026 /* btf.h */
21− btf__new(NULL, 0);
27+ btf = btf__new(NULL, 0);
28+ btf_dump__new(btf, dump_printf, nullptr, &opts);
2229
2330 /* BPF skeleton */
2431 skel = test_core_extern__open_and_load();
tools/testing/selftests/bpf/test_maps.c+0−1
@@ -23,7 +23,6 @@ · 22 unmodified lines
2323 #include <bpf/libbpf.h>
2424
2525 #include "bpf_util.h"
26−#include "bpf_rlimit.h"
2726 #include "test_maps.h"
2827 #include "testing_helpers.h"
2928
tools/testing/selftests/bpf/test_progs.c+0−2
@@ -4,7 +4,6 @@ · 3 unmodified lines
44 #define _GNU_SOURCE
55 #include "test_progs.h"
66 #include "cgroup_helpers.h"
7−#include "bpf_rlimit.h"
87 #include <argp.h>
98 #include <pthread.h>
109 #include <sched.h>
@@ -1342,7 +1341,6 @@ int main(int argc, char **argv) · 1331 unmodified lines
13421341
13431342 /* Use libbpf 1.0 API mode */
13441343 libbpf_set_strict_mode(LIBBPF_STRICT_ALL);
1345−
13461344 libbpf_set_print(libbpf_print_fn);
13471345
13481346 srand(time(NULL));
tools/testing/selftests/bpf/test_verifier.c+8−10
@@ -41,7 +41,6 @@ · 40 unmodified lines
4141 # define CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS 1
4242 # endif
4343 #endif
44−#include "bpf_rlimit.h"
4544 #include "bpf_rand.h"
4645 #include "bpf_util.h"
4746 #include "test_btf.h"
@@ -701,22 +700,18 @@ static int create_sk_storage_map(void) · 653 unmodified lines
701700
702701 static int create_map_timer(void)
703702 {
704− struct bpf_create_map_attr attr = {
705− .name = "test_map",
706− .map_type = BPF_MAP_TYPE_ARRAY,
707− .key_size = 4,
708− .value_size = 16,
709− .max_entries = 1,
703+ LIBBPF_OPTS(bpf_map_create_opts, opts,
710704 .btf_key_type_id = 1,
711705 .btf_value_type_id = 5,
712− };
706+ );
713707 int fd, btf_fd;
714708
715709 btf_fd = load_btf();
716710 if (btf_fd < 0)
717711 return -1;
718− attr.btf_fd = btf_fd;
719− fd = bpf_create_map_xattr(&attr);
712+
713+ opts.btf_fd = btf_fd;
714+ fd = bpf_map_create(BPF_MAP_TYPE_ARRAY, "test_map", 4, 16, 1, &opts);
720715 if (fd < 0)
721716 printf("Failed to create map with timer\n");
722717 return fd;
@@ -1399,6 +1394,9 @@ int main(int argc, char **argv) · 676 unmodified lines
13991394 return EXIT_FAILURE;
14001395 }
14011396
1397+ /* Use libbpf 1.0 API mode */
1398+ libbpf_set_strict_mode(LIBBPF_STRICT_ALL);
1399+
14021400 bpf_semi_rand_init();
14031401 return do_test(unpriv, from, to);
14041402 }
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
3232 OUTPUT_DIR="$HOME/.bpf_selftests"
3333 KCONFIG_URL="https://raw.githubusercontent.com/libbpf/libbpf/master/travis-ci/vmtest/configs/config-latest.${ARCH}"
3434 KCONFIG_API_URL="https://api.github.com/repos/libbpf/libbpf/contents/travis-ci/vmtest/configs/config-latest.${ARCH}"
35−INDEX_URL="https://raw.githubusercontent.com/libbpf/libbpf/master/travis-ci/vmtest/configs/INDEX"
35+INDEX_URL="https://raw.githubusercontent.com/libbpf/ci/master/INDEX"
3636 NUM_COMPILE_JOBS="$(nproc)"
3737 LOG_FILE_BASE="$(date +"bpf_selftests.%Y-%m-%d_%H-%M-%S")"
3838 LOG_FILE="${LOG_FILE_BASE}.log"