History

Merge tag 'for-netdev' of https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next

Daniel Borkmann says: ==================== pull-request: bpf-next 2024-03-25 We've added 38 non-merge commits during the last 13 day(s) which contain a total of 50 files changed, 867 insertions(+), 274 deletions(-). The main changes are: 1) Add the ability to specify and retrieve BPF cookie also for raw tracepoint programs in order to ease migration from classic to raw tracepoints, from Andrii Nakryiko. 2) Allow the use of bpf_get_{ns_,}current_pid_tgid() helper for all program types and add additional BPF selftests, from Yonghong Song. 3) Several improvements to bpftool and its build, for example, enabling libbpf logs when loading pid_iter in debug mode, from Quentin Monnet. 4) Check the return code of all BPF-related set_memory_*() functions during load and bail out in case they fail, from Christophe Leroy. 5) Avoid a goto in regs_refine_cond_op() such that the verifier can be better integrated into Agni tool which doesn't support backedges yet, from Harishankar Vishwanathan. 6) Add a small BPF trie perf improvement by always inlining longest_prefix_match, from Jesper Dangaard Brouer. 7) Small BPF selftest refactor in bpf_tcp_ca.c to utilize start_server() helper instead of open-coding it, from Geliang Tang. 8) Improve test_tc_tunnel.sh BPF selftest to prevent client connect before the server bind, from Alessandro Carminati. 9) Fix BPF selftest benchmark for older glibc and use syscall(SYS_gettid) instead of gettid(), from Alan Maguire. 10) Implement a backward-compatible method for struct_ops types with additional fields which are not present in older kernels, from Kui-Feng Lee. 11) Add a small helper to check if an instruction is addr_space_cast from as(0) to as(1) and utilize it in x86-64 JIT, from Puranjay Mohan. 12) Small cleanup to remove unnecessary error check in bpf_struct_ops_map_update_elem, from Martin KaFai Lau. 13) Improvements to libbpf fd validity checks for BPF map/programs, from Mykyta Yatsenko. * tag 'for-netdev' of https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next: (38 commits) selftests/bpf: Fix flaky test btf_map_in_map/lookup_update bpf: implement insn_is_cast_user() helper for JITs bpf: Avoid get_kernel_nofault() to fetch kprobe entry IP selftests/bpf: Use start_server in bpf_tcp_ca bpf: Sync uapi bpf.h to tools directory libbpf: Add new sec_def "sk_skb/verdict" selftests/bpf: Mark uprobe trigger functions with nocf_check attribute selftests/bpf: Use syscall(SYS_gettid) instead of gettid() wrapper in bench bpf-next: Avoid goto in regs_refine_cond_op() bpftool: Clean up HOST_CFLAGS, HOST_LDFLAGS for bootstrap bpftool selftests/bpf: scale benchmark counting by using per-CPU counters bpftool: Remove unnecessary source files from bootstrap version bpftool: Enable libbpf logs when loading pid_iter in debug mode selftests/bpf: add raw_tp/tp_btf BPF cookie subtests libbpf: add support for BPF cookie for raw_tp/tp_btf programs bpf: support BPF cookie in raw tracepoint (raw_tp, tp_btf) programs bpf: pass whole link instead of prog when triggering raw tracepoint bpf: flatten bpf_probe_register call chain selftests/bpf: Prevent client connect before server bind in test_tc_tunnel.sh selftests/bpf: Add a sk_msg prog bpf_get_ns_current_pid_tgid() test ... ====================

Jakub Kicinski committed 2 years ago

Commit 2a702c22 parents ee36b1e 14bb1e850 files · +867 −274Browse files

Unified · Split

50 files
  1. arch/arm/net/bpf_jit_32.c +12 −13
  2. arch/arm64/net/bpf_jit_comp.c +2 −5
  3. arch/loongarch/net/bpf_jit.c +16 −6
  4. arch/mips/net/bpf_jit_comp.c +2 −1
  5. arch/parisc/net/bpf_jit_core.c +7 −1
  6. arch/s390/net/bpf_jit_comp.c +5 −1
  7. arch/sparc/net/bpf_jit_comp_64.c +5 −1
  8. arch/x86/net/bpf_jit_comp.c +3 −7
  9. arch/x86/net/bpf_jit_comp32.c +1 −2
  10. include/linux/bpf.h +7 −2
  11. include/linux/filter.h +16 −4
  12. include/linux/trace_events.h +20 −16
  13. include/trace/bpf_probe.h +1 −2
  14. include/uapi/linux/bpf.h +4 −2
  15. kernel/bpf/bpf_struct_ops.c +6 −4
  16. kernel/bpf/cgroup.c +0 −2
  17. kernel/bpf/core.c +24 −8
  18. kernel/bpf/helpers.c +4 −0
  19. kernel/bpf/lpm_trie.c +13 −5
  20. kernel/bpf/syscall.c +11 −11
  21. kernel/bpf/trampoline.c +5 −10
  22. kernel/bpf/verifier.c +20 −11
  23. kernel/trace/bpf_trace.c +32 −20
  24. net/bpf/bpf_dummy_struct_ops.c +3 −1
  25. net/core/filter.c +0 −2
  26. tools/bpf/bpftool/Makefile +6 −8
  27. tools/bpf/bpftool/gen.c +2 −1
  28. tools/bpf/bpftool/pids.c +12 −7
  29. tools/bpf/bpftool/skeleton/pid_iter.bpf.c +2 −2
  30. tools/include/linux/compiler.h +4 −0
  31. tools/include/uapi/linux/bpf.h +4 −2
  32. tools/lib/bpf/bpf.c +14 −2
  33. tools/lib/bpf/bpf.h +9 −0
  34. tools/lib/bpf/libbpf.c +92 −19
  35. tools/lib/bpf/libbpf.h +11 −0
  36. tools/lib/bpf/libbpf.map +2 −0
  37. tools/testing/selftests/bpf/benchs/bench_local_storage_create.c +1 −1
  38. tools/testing/selftests/bpf/benchs/bench_trigger.c +40 −8
  39. tools/testing/selftests/bpf/prog_tests/bpf_cookie.c +113 −1
  40. tools/testing/selftests/bpf/prog_tests/bpf_tcp_ca.c +1 −12
  41. tools/testing/selftests/bpf/prog_tests/btf_map_in_map.c +1 −25
  42. tools/testing/selftests/bpf/prog_tests/ns_current_pid_tgid.c +183 −31
  43. tools/testing/selftests/bpf/prog_tests/test_struct_ops_module.c +47 −0
  44. tools/testing/selftests/bpf/progs/iters.c +1 −1
  45. tools/testing/selftests/bpf/progs/struct_ops_module.c +15 −1
  46. tools/testing/selftests/bpf/progs/test_bpf_cookie.c +16 −0
  47. tools/testing/selftests/bpf/progs/test_ns_current_pid_tgid.c +28 −3
  48. tools/testing/selftests/bpf/progs/trigger_bench.c +27 −12
  49. tools/testing/selftests/bpf/test_cpp.cpp +5 −0
  50. tools/testing/selftests/bpf/test_tc_tunnel.sh +12 −1
arch/arm/net/bpf_jit_32.c+12−13
@@ -2222,28 +2222,21 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) · 2221 unmodified lines
22222222 /* If building the body of the JITed code fails somehow,
22232223 * we fall back to the interpretation.
22242224 */
2225− if (build_body(&ctx) < 0) {
2226− image_ptr = NULL;
2227− bpf_jit_binary_free(header);
2228− prog = orig_prog;
2229− goto out_imms;
2230− }
2225+ if (build_body(&ctx) < 0)
2226+ goto out_free;
22312227 build_epilogue(&ctx);
22322228
22332229 /* 3.) Extra pass to validate JITed Code */
2234− if (validate_code(&ctx)) {
2235− image_ptr = NULL;
2236− bpf_jit_binary_free(header);
2237− prog = orig_prog;
2238− goto out_imms;
2239− }
2230+ if (validate_code(&ctx))
2231+ goto out_free;
22402232 flush_icache_range((u32)header, (u32)(ctx.target + ctx.idx));
22412233
22422234 if (bpf_jit_enable > 1)
22432235 /* there are 2 passes here */
22442236 bpf_jit_dump(prog->len, image_size, 2, ctx.target);
22452237
2246− bpf_jit_binary_lock_ro(header);
2238+ if (bpf_jit_binary_lock_ro(header))
2239+ goto out_free;
22472240 prog->bpf_func = (void *)ctx.target;
22482241 prog->jited = 1;
22492242 prog->jited_len = image_size;
@@ -2260,5 +2253,11 @@ out: · 10 unmodified lines
22602253 bpf_jit_prog_release_other(prog, prog == orig_prog ?
22612254 tmp : orig_prog);
22622255 return prog;
2256+
2257+out_free:
2258+ image_ptr = NULL;
2259+ bpf_jit_binary_free(header);
2260+ prog = orig_prog;
2261+ goto out_imms;
22632262 }
22642263
arch/arm64/net/bpf_jit_comp.c+2−5
@@ -2176,12 +2176,9 @@ void arch_free_bpf_trampoline(void *image, unsigned int size) · 2175 unmodified lines
21762176 bpf_prog_pack_free(image, size);
21772177 }
21782178
2179−void arch_protect_bpf_trampoline(void *image, unsigned int size)
2180−{
2181−}
2182−
2183−void arch_unprotect_bpf_trampoline(void *image, unsigned int size)
2179+int arch_protect_bpf_trampoline(void *image, unsigned int size)
21842180 {
2181+ return 0;
21852182 }
21862183
21872184 int arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *ro_image,
arch/loongarch/net/bpf_jit.c+16−6
@@ -1294,16 +1294,19 @@ skip_init_ctx: · 1293 unmodified lines
12941294 flush_icache_range((unsigned long)header, (unsigned long)(ctx.image + ctx.idx));
12951295
12961296 if (!prog->is_func || extra_pass) {
1297+ int err;
1298+
12971299 if (extra_pass && ctx.idx != jit_data->ctx.idx) {
12981300 pr_err_once("multi-func JIT bug %d != %d\n",
12991301 ctx.idx, jit_data->ctx.idx);
1300− bpf_jit_binary_free(header);
1301− prog->bpf_func = NULL;
1302− prog->jited = 0;
1303− prog->jited_len = 0;
1304− goto out_offset;
1302+ goto out_free;
1303+ }
1304+ err = bpf_jit_binary_lock_ro(header);
1305+ if (err) {
1306+ pr_err_once("bpf_jit_binary_lock_ro() returned %d\n",
1307+ err);
1308+ goto out_free;
13051309 }
1306− bpf_jit_binary_lock_ro(header);
13071310 } else {
13081311 jit_data->ctx = ctx;
13091312 jit_data->image = image_ptr;
@@ -1334,6 +1337,13 @@ out: · 24 unmodified lines
13341337 out_offset = -1;
13351338
13361339 return prog;
1340+
1341+out_free:
1342+ bpf_jit_binary_free(header);
1343+ prog->bpf_func = NULL;
1344+ prog->jited = 0;
1345+ prog->jited_len = 0;
1346+ goto out_offset;
13371347 }
13381348
13391349 /* Indicate the JIT backend supports mixing bpf2bpf and tailcalls. */
arch/mips/net/bpf_jit_comp.c+2−1
@@ -1012,7 +1012,8 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) · 1011 unmodified lines
10121012 bpf_prog_fill_jited_linfo(prog, &ctx.descriptors[1]);
10131013
10141014 /* Set as read-only exec and flush instruction cache */
1015− bpf_jit_binary_lock_ro(header);
1015+ if (bpf_jit_binary_lock_ro(header))
1016+ goto out_err;
10161017 flush_icache_range((unsigned long)header,
10171018 (unsigned long)&ctx.target[ctx.jit_index]);
10181019
arch/parisc/net/bpf_jit_core.c+7−1
@@ -167,7 +167,13 @@ skip_init_ctx: · 166 unmodified lines
167167 bpf_flush_icache(jit_data->header, ctx->insns + ctx->ninsns);
168168
169169 if (!prog->is_func || extra_pass) {
170− bpf_jit_binary_lock_ro(jit_data->header);
170+ if (bpf_jit_binary_lock_ro(jit_data->header)) {
171+ bpf_jit_binary_free(jit_data->header);
172+ prog->bpf_func = NULL;
173+ prog->jited = 0;
174+ prog->jited_len = 0;
175+ goto out_offset;
176+ }
171177 prologue_len = ctx->epilogue_offset - ctx->body_len;
172178 for (i = 0; i < prog->len; i++)
173179 ctx->offset[i] += prologue_len;
arch/s390/net/bpf_jit_comp.c+5−1
@@ -2111,7 +2111,11 @@ skip_init_ctx: · 2110 unmodified lines
21112111 print_fn_code(jit.prg_buf, jit.size_prg);
21122112 }
21132113 if (!fp->is_func || extra_pass) {
2114− bpf_jit_binary_lock_ro(header);
2114+ if (bpf_jit_binary_lock_ro(header)) {
2115+ bpf_jit_binary_free(header);
2116+ fp = orig_fp;
2117+ goto free_addrs;
2118+ }
21152119 } else {
21162120 jit_data->header = header;
21172121 jit_data->ctx = jit;
arch/sparc/net/bpf_jit_comp_64.c+5−1
@@ -1602,7 +1602,11 @@ skip_init_ctx: · 1601 unmodified lines
16021602 bpf_flush_icache(header, (u8 *)header + header->size);
16031603
16041604 if (!prog->is_func || extra_pass) {
1605− bpf_jit_binary_lock_ro(header);
1605+ if (bpf_jit_binary_lock_ro(header)) {
1606+ bpf_jit_binary_free(header);
1607+ prog = orig_prog;
1608+ goto out_off;
1609+ }
16061610 } else {
16071611 jit_data->ctx = ctx;
16081612 jit_data->image = image_ptr;
arch/x86/net/bpf_jit_comp.c+3−7
@@ -1351,8 +1351,7 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image, u8 *rw_image · 1350 unmodified lines
13511351 break;
13521352
13531353 case BPF_ALU64 | BPF_MOV | BPF_X:
1354− if (insn->off == BPF_ADDR_SPACE_CAST &&
1355− insn->imm == 1U << 16) {
1354+ if (insn_is_cast_user(insn)) {
13561355 if (dst_reg != src_reg)
13571356 /* 32-bit mov */
13581357 emit_mov_reg(&prog, false, dst_reg, src_reg);
@@ -3004,12 +3003,9 @@ void arch_free_bpf_trampoline(void *image, unsigned int size) · 1645 unmodified lines
30043003 bpf_prog_pack_free(image, size);
30053004 }
30063005
3007−void arch_protect_bpf_trampoline(void *image, unsigned int size)
3008−{
3009−}
3010−
3011−void arch_unprotect_bpf_trampoline(void *image, unsigned int size)
3006+int arch_protect_bpf_trampoline(void *image, unsigned int size)
30123007 {
3008+ return 0;
30133009 }
30143010
30153011 int arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *image, void *image_end,
arch/x86/net/bpf_jit_comp32.c+1−2
@@ -2600,8 +2600,7 @@ out_image: · 2599 unmodified lines
26002600 if (bpf_jit_enable > 1)
26012601 bpf_jit_dump(prog->len, proglen, pass + 1, image);
26022602
2603− if (image) {
2604− bpf_jit_binary_lock_ro(header);
2603+ if (image && !bpf_jit_binary_lock_ro(header)) {
26052604 prog->bpf_func = (void *)image;
26062605 prog->jited = 1;
26072606 prog->jited_len = proglen;
include/linux/bpf.h+7−2
@@ -1116,8 +1116,7 @@ int arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *image, void *i · 1115 unmodified lines
11161116 void *func_addr);
11171117 void *arch_alloc_bpf_trampoline(unsigned int size);
11181118 void arch_free_bpf_trampoline(void *image, unsigned int size);
1119−void arch_protect_bpf_trampoline(void *image, unsigned int size);
1120−void arch_unprotect_bpf_trampoline(void *image, unsigned int size);
1119+int __must_check arch_protect_bpf_trampoline(void *image, unsigned int size);
11211120 int arch_bpf_trampoline_size(const struct btf_func_model *m, u32 flags,
11221121 struct bpf_tramp_links *tlinks, void *func_addr);
11231122
@@ -1608,6 +1607,12 @@ struct bpf_tracing_link { · 484 unmodified lines
16081607 struct bpf_prog *tgt_prog;
16091608 };
16101609
1610+struct bpf_raw_tp_link {
1611+ struct bpf_link link;
1612+ struct bpf_raw_event_map *btp;
1613+ u64 cookie;
1614+};
1615+
16111616 struct bpf_link_primer {
16121617 struct bpf_link *link;
16131618 struct file *file;
include/linux/filter.h+16−4
@@ -228,6 +228,16 @@ static inline bool insn_is_zext(const struct bpf_insn *insn) · 227 unmodified lines
228228 return insn->code == (BPF_ALU | BPF_MOV | BPF_X) && insn->imm == 1;
229229 }
230230
231+/* addr_space_cast from as(0) to as(1) is for converting bpf arena pointers
232+ * to pointers in user vma.
233+ */
234+static inline bool insn_is_cast_user(const struct bpf_insn *insn)
235+{
236+ return insn->code == (BPF_ALU64 | BPF_MOV | BPF_X) &&
237+ insn->off == BPF_ADDR_SPACE_CAST &&
238+ insn->imm == 1U << 16;
239+}
240+
231241 /* BPF_LD_IMM64 macro encodes single 'load 64-bit immediate' insn */
232242 #define BPF_LD_IMM64(DST, IMM) \
233243 BPF_LD_IMM64_RAW(DST, 0, IMM)
@@ -887,20 +897,22 @@ bpf_ctx_narrow_access_offset(u32 off, u32 size, u32 size_default) · 653 unmodified lines
887897
888898 #define bpf_classic_proglen(fprog) (fprog->len * sizeof(fprog->filter[0]))
889899
890−static inline void bpf_prog_lock_ro(struct bpf_prog *fp)
900+static inline int __must_check bpf_prog_lock_ro(struct bpf_prog *fp)
891901 {
892902 #ifndef CONFIG_BPF_JIT_ALWAYS_ON
893903 if (!fp->jited) {
894904 set_vm_flush_reset_perms(fp);
895− set_memory_ro((unsigned long)fp, fp->pages);
905+ return set_memory_ro((unsigned long)fp, fp->pages);
896906 }
897907 #endif
908+ return 0;
898909 }
899910
900−static inline void bpf_jit_binary_lock_ro(struct bpf_binary_header *hdr)
911+static inline int __must_check
912+bpf_jit_binary_lock_ro(struct bpf_binary_header *hdr)
901913 {
902914 set_vm_flush_reset_perms(hdr);
903− set_memory_rox((unsigned long)hdr, hdr->size >> PAGE_SHIFT);
915+ return set_memory_rox((unsigned long)hdr, hdr->size >> PAGE_SHIFT);
904916 }
905917
906918 int sk_filter_trim_cap(struct sock *sk, struct sk_buff *skb, unsigned int cap);
include/linux/trace_events.h+20−16
@@ -765,8 +765,11 @@ unsigned int trace_call_bpf(struct trace_event_call *call, void *ctx); · 764 unmodified lines
765765 int perf_event_attach_bpf_prog(struct perf_event *event, struct bpf_prog *prog, u64 bpf_cookie);
766766 void perf_event_detach_bpf_prog(struct perf_event *event);
767767 int perf_event_query_prog_array(struct perf_event *event, void __user *info);
768−int bpf_probe_register(struct bpf_raw_event_map *btp, struct bpf_prog *prog);
769−int bpf_probe_unregister(struct bpf_raw_event_map *btp, struct bpf_prog *prog);
768+
769+struct bpf_raw_tp_link;
770+int bpf_probe_register(struct bpf_raw_event_map *btp, struct bpf_raw_tp_link *link);
771+int bpf_probe_unregister(struct bpf_raw_event_map *btp, struct bpf_raw_tp_link *link);
772+
770773 struct bpf_raw_event_map *bpf_get_raw_tracepoint(const char *name);
771774 void bpf_put_raw_tracepoint(struct bpf_raw_event_map *btp);
772775 int bpf_get_perf_event_info(const struct perf_event *event, u32 *prog_id,
@@ -794,11 +797,12 @@ perf_event_query_prog_array(struct perf_event *event, void __user *info) · 21 unmodified lines
794797 {
795798 return -EOPNOTSUPP;
796799 }
797−static inline int bpf_probe_register(struct bpf_raw_event_map *btp, struct bpf_prog *p)
800+struct bpf_raw_tp_link;
801+static inline int bpf_probe_register(struct bpf_raw_event_map *btp, struct bpf_raw_tp_link *link)
798802 {
799803 return -EOPNOTSUPP;
800804 }
801−static inline int bpf_probe_unregister(struct bpf_raw_event_map *btp, struct bpf_prog *p)
805+static inline int bpf_probe_unregister(struct bpf_raw_event_map *btp, struct bpf_raw_tp_link *link)
802806 {
803807 return -EOPNOTSUPP;
804808 }
@@ -909,31 +913,31 @@ void *perf_trace_buf_alloc(int size, struct pt_regs **regs, int *rctxp); · 104 unmodified lines
909913 int perf_event_set_bpf_prog(struct perf_event *event, struct bpf_prog *prog, u64 bpf_cookie);
910914 void perf_event_free_bpf_prog(struct perf_event *event);
911915
912−void bpf_trace_run1(struct bpf_prog *prog, u64 arg1);
913−void bpf_trace_run2(struct bpf_prog *prog, u64 arg1, u64 arg2);
914−void bpf_trace_run3(struct bpf_prog *prog, u64 arg1, u64 arg2,
916+void bpf_trace_run1(struct bpf_raw_tp_link *link, u64 arg1);
917+void bpf_trace_run2(struct bpf_raw_tp_link *link, u64 arg1, u64 arg2);
918+void bpf_trace_run3(struct bpf_raw_tp_link *link, u64 arg1, u64 arg2,
915919 u64 arg3);
916−void bpf_trace_run4(struct bpf_prog *prog, u64 arg1, u64 arg2,
920+void bpf_trace_run4(struct bpf_raw_tp_link *link, u64 arg1, u64 arg2,
917921 u64 arg3, u64 arg4);
918−void bpf_trace_run5(struct bpf_prog *prog, u64 arg1, u64 arg2,
922+void bpf_trace_run5(struct bpf_raw_tp_link *link, u64 arg1, u64 arg2,
919923 u64 arg3, u64 arg4, u64 arg5);
920−void bpf_trace_run6(struct bpf_prog *prog, u64 arg1, u64 arg2,
924+void bpf_trace_run6(struct bpf_raw_tp_link *link, u64 arg1, u64 arg2,
921925 u64 arg3, u64 arg4, u64 arg5, u64 arg6);
922−void bpf_trace_run7(struct bpf_prog *prog, u64 arg1, u64 arg2,
926+void bpf_trace_run7(struct bpf_raw_tp_link *link, u64 arg1, u64 arg2,
923927 u64 arg3, u64 arg4, u64 arg5, u64 arg6, u64 arg7);
924−void bpf_trace_run8(struct bpf_prog *prog, u64 arg1, u64 arg2,
928+void bpf_trace_run8(struct bpf_raw_tp_link *link, u64 arg1, u64 arg2,
925929 u64 arg3, u64 arg4, u64 arg5, u64 arg6, u64 arg7,
926930 u64 arg8);
927−void bpf_trace_run9(struct bpf_prog *prog, u64 arg1, u64 arg2,
931+void bpf_trace_run9(struct bpf_raw_tp_link *link, u64 arg1, u64 arg2,
928932 u64 arg3, u64 arg4, u64 arg5, u64 arg6, u64 arg7,
929933 u64 arg8, u64 arg9);
930−void bpf_trace_run10(struct bpf_prog *prog, u64 arg1, u64 arg2,
934+void bpf_trace_run10(struct bpf_raw_tp_link *link, u64 arg1, u64 arg2,
931935 u64 arg3, u64 arg4, u64 arg5, u64 arg6, u64 arg7,
932936 u64 arg8, u64 arg9, u64 arg10);
933−void bpf_trace_run11(struct bpf_prog *prog, u64 arg1, u64 arg2,
937+void bpf_trace_run11(struct bpf_raw_tp_link *link, u64 arg1, u64 arg2,
934938 u64 arg3, u64 arg4, u64 arg5, u64 arg6, u64 arg7,
935939 u64 arg8, u64 arg9, u64 arg10, u64 arg11);
936−void bpf_trace_run12(struct bpf_prog *prog, u64 arg1, u64 arg2,
940+void bpf_trace_run12(struct bpf_raw_tp_link *link, u64 arg1, u64 arg2,
937941 u64 arg3, u64 arg4, u64 arg5, u64 arg6, u64 arg7,
938942 u64 arg8, u64 arg9, u64 arg10, u64 arg11, u64 arg12);
939943 void perf_trace_run_bpf_submit(void *raw_data, int size, int rctx,
include/trace/bpf_probe.h+1−2
@@ -46,8 +46,7 @@ · 45 unmodified lines
4646 static notrace void \
4747 __bpf_trace_##call(void *__data, proto) \
4848 { \
49− struct bpf_prog *prog = __data; \
50− CONCATENATE(bpf_trace_run, COUNT_ARGS(args))(prog, CAST_TO_U64(args)); \
49+ CONCATENATE(bpf_trace_run, COUNT_ARGS(args))(__data, CAST_TO_U64(args)); \
5150 }
5251
5352 #undef DECLARE_EVENT_CLASS
include/uapi/linux/bpf.h+4−2
@@ -1662,8 +1662,10 @@ union bpf_attr { · 1661 unmodified lines
16621662 } query;
16631663
16641664 struct { /* anonymous struct used by BPF_RAW_TRACEPOINT_OPEN command */
1665− __u64 name;
1666− __u32 prog_fd;
1665+ __u64 name;
1666+ __u32 prog_fd;
1667+ __u32 :32;
1668+ __aligned_u64 cookie;
16671669 } raw_tracepoint;
16681670
16691671 struct { /* anonymous struct for BPF_BTF_LOAD */
kernel/bpf/bpf_struct_ops.c+6−4
@@ -728,8 +728,6 @@ static long bpf_struct_ops_map_update_elem(struct bpf_map *map, void *key, · 727 unmodified lines
728728 cur_image = image;
729729 trampoline_start = 0;
730730 }
731− if (err < 0)
732− goto reset_unlock;
733731
734732 *(void **)(kdata + moff) = image + trampoline_start + cfi_get_offset();
735733
@@ -742,8 +740,12 @@ static long bpf_struct_ops_map_update_elem(struct bpf_map *map, void *key, · 6 unmodified lines
742740 if (err)
743741 goto reset_unlock;
744742 }
745− for (i = 0; i < st_map->image_pages_cnt; i++)
746− arch_protect_bpf_trampoline(st_map->image_pages[i], PAGE_SIZE);
743+ for (i = 0; i < st_map->image_pages_cnt; i++) {
744+ err = arch_protect_bpf_trampoline(st_map->image_pages[i],
745+ PAGE_SIZE);
746+ if (err)
747+ goto reset_unlock;
748+ }
747749
748750 if (st_map->map.map_flags & BPF_F_LINK) {
749751 err = 0;
kernel/bpf/cgroup.c+0−2
@@ -2575,8 +2575,6 @@ cgroup_current_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog) · 2574 unmodified lines
25752575 switch (func_id) {
25762576 case BPF_FUNC_get_current_uid_gid:
25772577 return &bpf_get_current_uid_gid_proto;
2578− case BPF_FUNC_get_current_pid_tgid:
2579− return &bpf_get_current_pid_tgid_proto;
25802578 case BPF_FUNC_get_current_comm:
25812579 return &bpf_get_current_comm_proto;
25822580 #ifdef CONFIG_CGROUP_NET_CLASSID
kernel/bpf/core.c+24−8
@@ -908,23 +908,30 @@ static LIST_HEAD(pack_list); · 907 unmodified lines
908908 static struct bpf_prog_pack *alloc_new_pack(bpf_jit_fill_hole_t bpf_fill_ill_insns)
909909 {
910910 struct bpf_prog_pack *pack;
911+ int err;
911912
912913 pack = kzalloc(struct_size(pack, bitmap, BITS_TO_LONGS(BPF_PROG_CHUNK_COUNT)),
913914 GFP_KERNEL);
914915 if (!pack)
915916 return NULL;
916917 pack->ptr = bpf_jit_alloc_exec(BPF_PROG_PACK_SIZE);
917− if (!pack->ptr) {
918− kfree(pack);
919− return NULL;
920− }
918+ if (!pack->ptr)
919+ goto out;
921920 bpf_fill_ill_insns(pack->ptr, BPF_PROG_PACK_SIZE);
922921 bitmap_zero(pack->bitmap, BPF_PROG_PACK_SIZE / BPF_PROG_CHUNK_SIZE);
923− list_add_tail(&pack->list, &pack_list);
924922
925923 set_vm_flush_reset_perms(pack->ptr);
926− set_memory_rox((unsigned long)pack->ptr, BPF_PROG_PACK_SIZE / PAGE_SIZE);
924+ err = set_memory_rox((unsigned long)pack->ptr,
925+ BPF_PROG_PACK_SIZE / PAGE_SIZE);
926+ if (err)
927+ goto out;
928+ list_add_tail(&pack->list, &pack_list);
927929 return pack;
930+
931+out:
932+ bpf_jit_free_exec(pack->ptr);
933+ kfree(pack);
934+ return NULL;
928935 }
929936
930937 void *bpf_prog_pack_alloc(u32 size, bpf_jit_fill_hole_t bpf_fill_ill_insns)
@@ -939,9 +946,16 @@ void *bpf_prog_pack_alloc(u32 size, bpf_jit_fill_hole_t bpf_fill_ill_insns) · 8 unmodified lines
939946 size = round_up(size, PAGE_SIZE);
940947 ptr = bpf_jit_alloc_exec(size);
941948 if (ptr) {
949+ int err;
950+
942951 bpf_fill_ill_insns(ptr, size);
943952 set_vm_flush_reset_perms(ptr);
944− set_memory_rox((unsigned long)ptr, size / PAGE_SIZE);
953+ err = set_memory_rox((unsigned long)ptr,
954+ size / PAGE_SIZE);
955+ if (err) {
956+ bpf_jit_free_exec(ptr);
957+ ptr = NULL;
958+ }
945959 }
946960 goto out;
947961 }
@@ -2403,7 +2417,9 @@ struct bpf_prog *bpf_prog_select_runtime(struct bpf_prog *fp, int *err) · 1455 unmodified lines
24032417 }
24042418
24052419 finalize:
2406− bpf_prog_lock_ro(fp);
2420+ *err = bpf_prog_lock_ro(fp);
2421+ if (*err)
2422+ return fp;
24072423
24082424 /* The tail call compatibility check can only be done at
24092425 * this late stage as we need to determine, if we deal
kernel/bpf/helpers.c+4−0
@@ -1730,6 +1730,10 @@ bpf_base_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog) · 1729 unmodified lines
17301730 return &bpf_strtol_proto;
17311731 case BPF_FUNC_strtoul:
17321732 return &bpf_strtoul_proto;
1733+ case BPF_FUNC_get_current_pid_tgid:
1734+ return &bpf_get_current_pid_tgid_proto;
1735+ case BPF_FUNC_get_ns_current_pid_tgid:
1736+ return &bpf_get_ns_current_pid_tgid_proto;
17331737 default:
17341738 break;
17351739 }
kernel/bpf/lpm_trie.c+13−5
@@ -155,16 +155,17 @@ static inline int extract_bit(const u8 *data, size_t index) · 154 unmodified lines
155155 }
156156
157157 /**
158− * longest_prefix_match() - determine the longest prefix
158+ * __longest_prefix_match() - determine the longest prefix
159159 * @trie: The trie to get internal sizes from
160160 * @node: The node to operate on
161161 * @key: The key to compare to @node
162162 *
163163 * Determine the longest prefix of @node that matches the bits in @key.
164164 */
165−static size_t longest_prefix_match(const struct lpm_trie *trie,
166− const struct lpm_trie_node *node,
167− const struct bpf_lpm_trie_key_u8 *key)
165+static __always_inline
166+size_t __longest_prefix_match(const struct lpm_trie *trie,
167+ const struct lpm_trie_node *node,
168+ const struct bpf_lpm_trie_key_u8 *key)
168169 {
169170 u32 limit = min(node->prefixlen, key->prefixlen);
170171 u32 prefixlen = 0, i = 0;
@@ -224,6 +225,13 @@ static size_t longest_prefix_match(const struct lpm_trie *trie, · 53 unmodified lines
224225 return prefixlen;
225226 }
226227
228+static size_t longest_prefix_match(const struct lpm_trie *trie,
229+ const struct lpm_trie_node *node,
230+ const struct bpf_lpm_trie_key_u8 *key)
231+{
232+ return __longest_prefix_match(trie, node, key);
233+}
234+
227235 /* Called from syscall or from eBPF program */
228236 static void *trie_lookup_elem(struct bpf_map *map, void *_key)
229237 {
@@ -245,7 +253,7 @@ static void *trie_lookup_elem(struct bpf_map *map, void *_key) · 15 unmodified lines
245253 * If it's the maximum possible prefix for this trie, we have
246254 * an exact match and can return it directly.
247255 */
248− matchlen = longest_prefix_match(trie, node, key);
256+ matchlen = __longest_prefix_match(trie, node, key);
249257 if (matchlen == trie->max_prefixlen) {
250258 found = node;
251259 break;
kernel/bpf/syscall.c+11−11
@@ -3469,17 +3469,12 @@ out_put_prog: · 3468 unmodified lines
34693469 return err;
34703470 }
34713471
3472−struct bpf_raw_tp_link {
3473− struct bpf_link link;
3474− struct bpf_raw_event_map *btp;
3475−};
3476−
34773472 static void bpf_raw_tp_link_release(struct bpf_link *link)
34783473 {
34793474 struct bpf_raw_tp_link *raw_tp =
34803475 container_of(link, struct bpf_raw_tp_link, link);
34813476
3482− bpf_probe_unregister(raw_tp->btp, raw_tp->link.prog);
3477+ bpf_probe_unregister(raw_tp->btp, raw_tp);
34833478 bpf_put_raw_tracepoint(raw_tp->btp);
34843479 }
34853480
@@ -3779,7 +3774,7 @@ static int bpf_perf_link_attach(const union bpf_attr *attr, struct bpf_prog *pro · 293 unmodified lines
37793774 #endif /* CONFIG_PERF_EVENTS */
37803775
37813776 static int bpf_raw_tp_link_attach(struct bpf_prog *prog,
3782− const char __user *user_tp_name)
3777+ const char __user *user_tp_name, u64 cookie)
37833778 {
37843779 struct bpf_link_primer link_primer;
37853780 struct bpf_raw_tp_link *link;
@@ -3826,6 +3821,7 @@ static int bpf_raw_tp_link_attach(struct bpf_prog *prog, · 40 unmodified lines
38263821 bpf_link_init(&link->link, BPF_LINK_TYPE_RAW_TRACEPOINT,
38273822 &bpf_raw_tp_link_lops, prog);
38283823 link->btp = btp;
3824+ link->cookie = cookie;
38293825
38303826 err = bpf_link_prime(&link->link, &link_primer);
38313827 if (err) {
@@ -3833,7 +3829,7 @@ static int bpf_raw_tp_link_attach(struct bpf_prog *prog, · 1 unmodified line
38333829 goto out_put_btp;
38343830 }
38353831
3836− err = bpf_probe_register(link->btp, prog);
3832+ err = bpf_probe_register(link->btp, link);
38373833 if (err) {
38383834 bpf_link_cleanup(&link_primer);
38393835 goto out_put_btp;
@@ -3846,11 +3842,13 @@ out_put_btp: · 6 unmodified lines
38463842 return err;
38473843 }
38483844
3849−#define BPF_RAW_TRACEPOINT_OPEN_LAST_FIELD raw_tracepoint.prog_fd
3845+#define BPF_RAW_TRACEPOINT_OPEN_LAST_FIELD raw_tracepoint.cookie
38503846
38513847 static int bpf_raw_tracepoint_open(const union bpf_attr *attr)
38523848 {
38533849 struct bpf_prog *prog;
3850+ void __user *tp_name;
3851+ __u64 cookie;
38543852 int fd;
38553853
38563854 if (CHECK_ATTR(BPF_RAW_TRACEPOINT_OPEN))
@@ -3860,7 +3858,9 @@ static int bpf_raw_tracepoint_open(const union bpf_attr *attr) · 3 unmodified lines
38603858 if (IS_ERR(prog))
38613859 return PTR_ERR(prog);
38623860
3863− fd = bpf_raw_tp_link_attach(prog, u64_to_user_ptr(attr->raw_tracepoint.name));
3861+ tp_name = u64_to_user_ptr(attr->raw_tracepoint.name);
3862+ cookie = attr->raw_tracepoint.cookie;
3863+ fd = bpf_raw_tp_link_attach(prog, tp_name, cookie);
38643864 if (fd < 0)
38653865 bpf_prog_put(prog);
38663866 return fd;
@@ -5198,7 +5198,7 @@ static int link_create(union bpf_attr *attr, bpfptr_t uattr) · 1331 unmodified lines
51985198 goto out;
51995199 }
52005200 if (prog->expected_attach_type == BPF_TRACE_RAW_TP)
5201− ret = bpf_raw_tp_link_attach(prog, NULL);
5201+ ret = bpf_raw_tp_link_attach(prog, NULL, attr->link_create.tracing.cookie);
52025202 else if (prog->expected_attach_type == BPF_TRACE_ITER)
52035203 ret = bpf_iter_link_attach(attr, uattr, prog);
52045204 else if (prog->expected_attach_type == BPF_LSM_CGROUP)
kernel/bpf/trampoline.c+5−10
@@ -456,7 +456,9 @@ again: · 455 unmodified lines
456456 if (err < 0)
457457 goto out_free;
458458
459− arch_protect_bpf_trampoline(im->image, im->size);
459+ err = arch_protect_bpf_trampoline(im->image, im->size);
460+ if (err)
461+ goto out_free;
460462
461463 WARN_ON(tr->cur_image && total == 0);
462464 if (tr->cur_image)
@@ -1072,17 +1074,10 @@ void __weak arch_free_bpf_trampoline(void *image, unsigned int size) · 609 unmodified lines
10721074 bpf_jit_free_exec(image);
10731075 }
10741076
1075−void __weak arch_protect_bpf_trampoline(void *image, unsigned int size)
1076−{
1077− WARN_ON_ONCE(size > PAGE_SIZE);
1078− set_memory_rox((long)image, 1);
1079−}
1080−
1081−void __weak arch_unprotect_bpf_trampoline(void *image, unsigned int size)
1077+int __weak arch_protect_bpf_trampoline(void *image, unsigned int size)
10821078 {
10831079 WARN_ON_ONCE(size > PAGE_SIZE);
1084− set_memory_nx((long)image, 1);
1085− set_memory_rw((long)image, 1);
1080+ return set_memory_rox((long)image, 1);
10861081 }
10871082
10881083 int __weak arch_bpf_trampoline_size(const struct btf_func_model *m, u32 flags,
kernel/bpf/verifier.c+20−11
@@ -14544,7 +14544,19 @@ static void regs_refine_cond_op(struct bpf_reg_state *reg1, struct bpf_reg_state · 14543 unmodified lines
1454414544 struct tnum t;
1454514545 u64 val;
1454614546
14547−again:
14547+ /* In case of GE/GT/SGE/JST, reuse LE/LT/SLE/SLT logic from below */
14548+ switch (opcode) {
14549+ case BPF_JGE:
14550+ case BPF_JGT:
14551+ case BPF_JSGE:
14552+ case BPF_JSGT:
14553+ opcode = flip_opcode(opcode);
14554+ swap(reg1, reg2);
14555+ break;
14556+ default:
14557+ break;
14558+ }
14559+
1454814560 switch (opcode) {
1454914561 case BPF_JEQ:
1455014562 if (is_jmp32) {
@@ -14687,14 +14699,6 @@ again: · 136 unmodified lines
1468714699 reg2->smin_value = max(reg1->smin_value + 1, reg2->smin_value);
1468814700 }
1468914701 break;
14690− case BPF_JGE:
14691− case BPF_JGT:
14692− case BPF_JSGE:
14693− case BPF_JSGT:
14694− /* just reuse LE/LT logic above */
14695− opcode = flip_opcode(opcode);
14696− swap(reg1, reg2);
14697− goto again;
1469814702 default:
1469914703 return;
1470014704 }
@@ -19158,6 +19162,7 @@ static int jit_subprogs(struct bpf_verifier_env *env) · 4457 unmodified lines
1915819162 if (bpf_prog_calc_tag(func[i]))
1915919163 goto out_free;
1916019164 func[i]->is_func = 1;
19165+ func[i]->sleepable = prog->sleepable;
1916119166 func[i]->aux->func_idx = i;
1916219167 /* Below members will be freed only at prog->aux */
1916319168 func[i]->aux->btf = prog->aux->btf;
@@ -19262,10 +19267,14 @@ static int jit_subprogs(struct bpf_verifier_env *env) · 98 unmodified lines
1926219267 * bpf_prog_load will add the kallsyms for the main program.
1926319268 */
1926419269 for (i = 1; i < env->subprog_cnt; i++) {
19265− bpf_prog_lock_ro(func[i]);
19266− bpf_prog_kallsyms_add(func[i]);
19270+ err = bpf_prog_lock_ro(func[i]);
19271+ if (err)
19272+ goto out_free;
1926719273 }
1926819274
19275+ for (i = 1; i < env->subprog_cnt; i++)
19276+ bpf_prog_kallsyms_add(func[i]);
19277+
1926919278 /* Last step: make now unused interpreter insns from main
1927019279 * prog consistent for later dump requests, so they can
1927119280 * later look the same as if they were interpreted only.
kernel/trace/bpf_trace.c+32−20
@@ -1053,9 +1053,15 @@ static unsigned long get_entry_ip(unsigned long fentry_ip) · 1052 unmodified lines
10531053 {
10541054 u32 instr;
10551055
1056− /* Being extra safe in here in case entry ip is on the page-edge. */
1057− if (get_kernel_nofault(instr, (u32 *) fentry_ip - 1))
1058− return fentry_ip;
1056+ /* We want to be extra safe in case entry ip is on the page edge,
1057+ * but otherwise we need to avoid get_kernel_nofault()'s overhead.
1058+ */
1059+ if ((fentry_ip & ~PAGE_MASK) < ENDBR_INSN_SIZE) {
1060+ if (get_kernel_nofault(instr, (u32 *)(fentry_ip - ENDBR_INSN_SIZE)))
1061+ return fentry_ip;
1062+ } else {
1063+ instr = *(u32 *)(fentry_ip - ENDBR_INSN_SIZE);
1064+ }
10591065 if (is_endbr(instr))
10601066 fentry_ip -= ENDBR_INSN_SIZE;
10611067 return fentry_ip;
@@ -1525,8 +1531,6 @@ bpf_tracing_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog) · 463 unmodified lines
15251531 return &bpf_ktime_get_boot_ns_proto;
15261532 case BPF_FUNC_tail_call:
15271533 return &bpf_tail_call_proto;
1528− case BPF_FUNC_get_current_pid_tgid:
1529− return &bpf_get_current_pid_tgid_proto;
15301534 case BPF_FUNC_get_current_task:
15311535 return &bpf_get_current_task_proto;
15321536 case BPF_FUNC_get_current_task_btf:
@@ -1582,8 +1586,6 @@ bpf_tracing_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog) · 49 unmodified lines
15821586 return &bpf_send_signal_thread_proto;
15831587 case BPF_FUNC_perf_event_read_value:
15841588 return &bpf_perf_event_read_value_proto;
1585− case BPF_FUNC_get_ns_current_pid_tgid:
1586− return &bpf_get_ns_current_pid_tgid_proto;
15871589 case BPF_FUNC_ringbuf_output:
15881590 return &bpf_ringbuf_output_proto;
15891591 case BPF_FUNC_ringbuf_reserve:
@@ -2008,6 +2010,8 @@ raw_tp_prog_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog) · 418 unmodified lines
20082010 return &bpf_get_stackid_proto_raw_tp;
20092011 case BPF_FUNC_get_stack:
20102012 return &bpf_get_stack_proto_raw_tp;
2013+ case BPF_FUNC_get_attach_cookie:
2014+ return &bpf_get_attach_cookie_proto_tracing;
20112015 default:
20122016 return bpf_tracing_func_proto(func_id, prog);
20132017 }
@@ -2070,6 +2074,9 @@ tracing_prog_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog) · 56 unmodified lines
20702074 case BPF_FUNC_get_func_arg_cnt:
20712075 return bpf_prog_has_trampoline(prog) ? &bpf_get_func_arg_cnt_proto : NULL;
20722076 case BPF_FUNC_get_attach_cookie:
2077+ if (prog->type == BPF_PROG_TYPE_TRACING &&
2078+ prog->expected_attach_type == BPF_TRACE_RAW_TP)
2079+ return &bpf_get_attach_cookie_proto_tracing;
20732080 return bpf_prog_has_trampoline(prog) ? &bpf_get_attach_cookie_proto_tracing : NULL;
20742081 default:
20752082 fn = raw_tp_prog_func_proto(func_id, prog);
@@ -2370,16 +2377,26 @@ void bpf_put_raw_tracepoint(struct bpf_raw_event_map *btp) · 294 unmodified lines
23702377 }
23712378
23722379 static __always_inline
2373−void __bpf_trace_run(struct bpf_prog *prog, u64 *args)
2380+void __bpf_trace_run(struct bpf_raw_tp_link *link, u64 *args)
23742381 {
2382+ struct bpf_prog *prog = link->link.prog;
2383+ struct bpf_run_ctx *old_run_ctx;
2384+ struct bpf_trace_run_ctx run_ctx;
2385+
23752386 cant_sleep();
23762387 if (unlikely(this_cpu_inc_return(*(prog->active)) != 1)) {
23772388 bpf_prog_inc_misses_counter(prog);
23782389 goto out;
23792390 }
2391+
2392+ run_ctx.bpf_cookie = link->cookie;
2393+ old_run_ctx = bpf_set_run_ctx(&run_ctx.run_ctx);
2394+
23802395 rcu_read_lock();
23812396 (void) bpf_prog_run(prog, args);
23822397 rcu_read_unlock();
2398+
2399+ bpf_reset_run_ctx(old_run_ctx);
23832400 out:
23842401 this_cpu_dec(*(prog->active));
23852402 }
@@ -2408,12 +2425,12 @@ out: · 22 unmodified lines
24082425 #define __SEQ_0_11 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
24092426
24102427 #define BPF_TRACE_DEFN_x(x) \
2411− void bpf_trace_run##x(struct bpf_prog *prog, \
2428+ void bpf_trace_run##x(struct bpf_raw_tp_link *link, \
24122429 REPEAT(x, SARG, __DL_COM, __SEQ_0_11)) \
24132430 { \
24142431 u64 args[x]; \
24152432 REPEAT(x, COPY, __DL_SEM, __SEQ_0_11); \
2416− __bpf_trace_run(prog, args); \
2433+ __bpf_trace_run(link, args); \
24172434 } \
24182435 EXPORT_SYMBOL_GPL(bpf_trace_run##x)
24192436 BPF_TRACE_DEFN_x(1);
@@ -2429,9 +2446,10 @@ BPF_TRACE_DEFN_x(10); · 9 unmodified lines
24292446 BPF_TRACE_DEFN_x(11);
24302447 BPF_TRACE_DEFN_x(12);
24312448
2432−static int __bpf_probe_register(struct bpf_raw_event_map *btp, struct bpf_prog *prog)
2449+int bpf_probe_register(struct bpf_raw_event_map *btp, struct bpf_raw_tp_link *link)
24332450 {
24342451 struct tracepoint *tp = btp->tp;
2452+ struct bpf_prog *prog = link->link.prog;
24352453
24362454 /*
24372455 * check that program doesn't access arguments beyond what's
@@ -2443,18 +2461,12 @@ static int __bpf_probe_register(struct bpf_raw_event_map *btp, struct bpf_prog * · 5 unmodified lines
24432461 if (prog->aux->max_tp_access > btp->writable_size)
24442462 return -EINVAL;
24452463
2446− return tracepoint_probe_register_may_exist(tp, (void *)btp->bpf_func,
2447− prog);
2448−}
2449−
2450−int bpf_probe_register(struct bpf_raw_event_map *btp, struct bpf_prog *prog)
2451−{
2452− return __bpf_probe_register(btp, prog);
2464+ return tracepoint_probe_register_may_exist(tp, (void *)btp->bpf_func, link);
24532465 }
24542466
2455−int bpf_probe_unregister(struct bpf_raw_event_map *btp, struct bpf_prog *prog)
2467+int bpf_probe_unregister(struct bpf_raw_event_map *btp, struct bpf_raw_tp_link *link)
24562468 {
2457− return tracepoint_probe_unregister(btp->tp, (void *)btp->bpf_func, prog);
2469+ return tracepoint_probe_unregister(btp->tp, (void *)btp->bpf_func, link);
24582470 }
24592471
24602472 int bpf_get_perf_event_info(const struct perf_event *event, u32 *prog_id,
net/bpf/bpf_dummy_struct_ops.c+3−1
@@ -133,7 +133,9 @@ int bpf_struct_ops_test_run(struct bpf_prog *prog, const union bpf_attr *kattr, · 132 unmodified lines
133133 if (err < 0)
134134 goto out;
135135
136− arch_protect_bpf_trampoline(image, PAGE_SIZE);
136+ err = arch_protect_bpf_trampoline(image, PAGE_SIZE);
137+ if (err)
138+ goto out;
137139 prog_ret = dummy_ops_call_op(image, args);
138140
139141 err = dummy_ops_copy_args(args);
net/core/filter.c+0−2
@@ -8342,8 +8342,6 @@ sk_msg_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog) · 8341 unmodified lines
83428342 return &bpf_event_output_data_proto;
83438343 case BPF_FUNC_get_current_uid_gid:
83448344 return &bpf_get_current_uid_gid_proto;
8345− case BPF_FUNC_get_current_pid_tgid:
8346− return &bpf_get_current_pid_tgid_proto;
83478345 case BPF_FUNC_sk_storage_get:
83488346 return &bpf_sk_storage_get_proto;
83498347 case BPF_FUNC_sk_storage_delete:
tools/bpf/bpftool/Makefile+6−8
@@ -89,6 +89,10 @@ ifneq ($(EXTRA_LDFLAGS),) · 88 unmodified lines
8989 LDFLAGS += $(EXTRA_LDFLAGS)
9090 endif
9191
92+HOST_CFLAGS := $(subst -I$(LIBBPF_INCLUDE),-I$(LIBBPF_BOOTSTRAP_INCLUDE),\
93+ $(subst $(CLANG_CROSS_FLAGS),,$(CFLAGS)))
94+HOST_LDFLAGS := $(LDFLAGS)
95+
9296 INSTALL ?= install
9397 RM ?= rm -f
9498
@@ -178,12 +182,9 @@ ifeq ($(filter -DHAVE_LLVM_SUPPORT -DHAVE_LIBBFD_SUPPORT,$(CFLAGS)),) · 83 unmodified lines
178182 SRCS := $(filter-out jit_disasm.c,$(SRCS))
179183 endif
180184
181−HOST_CFLAGS = $(subst -I$(LIBBPF_INCLUDE),-I$(LIBBPF_BOOTSTRAP_INCLUDE),\
182− $(subst $(CLANG_CROSS_FLAGS),,$(CFLAGS)))
183−
184185 BPFTOOL_BOOTSTRAP := $(BOOTSTRAP_OUTPUT)bpftool
185186
186−BOOTSTRAP_OBJS = $(addprefix $(BOOTSTRAP_OUTPUT),main.o common.o json_writer.o gen.o btf.o xlated_dumper.o btf_dumper.o disasm.o)
187+BOOTSTRAP_OBJS = $(addprefix $(BOOTSTRAP_OUTPUT),main.o common.o json_writer.o gen.o btf.o)
187188 $(BOOTSTRAP_OBJS): $(LIBBPF_BOOTSTRAP)
188189
189190 OBJS = $(patsubst %.c,$(OUTPUT)%.o,$(SRCS)) $(OUTPUT)disasm.o
@@ -231,14 +232,11 @@ endif · 41 unmodified lines
231232
232233 CFLAGS += $(if $(BUILD_BPF_SKELS),,-DBPFTOOL_WITHOUT_SKELETONS)
233234
234−$(BOOTSTRAP_OUTPUT)disasm.o: $(srctree)/kernel/bpf/disasm.c
235− $(QUIET_CC)$(HOSTCC) $(HOST_CFLAGS) -c -MMD $< -o $@
236−
237235 $(OUTPUT)disasm.o: $(srctree)/kernel/bpf/disasm.c
238236 $(QUIET_CC)$(CC) $(CFLAGS) -c -MMD $< -o $@
239237
240238 $(BPFTOOL_BOOTSTRAP): $(BOOTSTRAP_OBJS) $(LIBBPF_BOOTSTRAP)
241− $(QUIET_LINK)$(HOSTCC) $(HOST_CFLAGS) $(LDFLAGS) $(BOOTSTRAP_OBJS) $(LIBS_BOOTSTRAP) -o $@
239+ $(QUIET_LINK)$(HOSTCC) $(HOST_CFLAGS) $(HOST_LDFLAGS) $(BOOTSTRAP_OBJS) $(LIBS_BOOTSTRAP) -o $@
242240
243241 $(OUTPUT)bpftool: $(OBJS) $(LIBBPF)
244242 $(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) $(OBJS) $(LIBS) -o $@
tools/bpf/bpftool/gen.c+2−1
@@ -1131,7 +1131,8 @@ static void gen_st_ops_shadow_init(struct btf *btf, struct bpf_object *obj) · 1130 unmodified lines
11311131 continue;
11321132 codegen("\
11331133 \n\
1134− obj->struct_ops.%1$s = bpf_map__initial_value(obj->maps.%1$s, NULL);\n\
1134+ obj->struct_ops.%1$s = (typeof(obj->struct_ops.%1$s))\n\
1135+ bpf_map__initial_value(obj->maps.%1$s, NULL);\n\
11351136 \n\
11361137 ", ident);
11371138 }
tools/bpf/bpftool/pids.c+12−7
@@ -101,7 +101,6 @@ int build_obj_refs_table(struct hashmap **map, enum bpf_obj_type type) · 100 unmodified lines
101101 char buf[4096 / sizeof(*e) * sizeof(*e)];
102102 struct pid_iter_bpf *skel;
103103 int err, ret, fd = -1, i;
104− libbpf_print_fn_t default_print;
105104
106105 *map = hashmap__new(hash_fn_for_key_as_id, equal_fn_for_key_as_id, NULL);
107106 if (IS_ERR(*map)) {
@@ -118,12 +117,18 @@ int build_obj_refs_table(struct hashmap **map, enum bpf_obj_type type) · 10 unmodified lines
118117
119118 skel->rodata->obj_type = type;
120119
121− /* we don't want output polluted with libbpf errors if bpf_iter is not
122− * supported
123− */
124− default_print = libbpf_set_print(libbpf_print_none);
125− err = pid_iter_bpf__load(skel);
126− libbpf_set_print(default_print);
120+ if (!verifier_logs) {
121+ libbpf_print_fn_t default_print;
122+
123+ /* Unless debug information is on, we don't want the output to
124+ * be polluted with libbpf errors if bpf_iter is not supported.
125+ */
126+ default_print = libbpf_set_print(libbpf_print_none);
127+ err = pid_iter_bpf__load(skel);
128+ libbpf_set_print(default_print);
129+ } else {
130+ err = pid_iter_bpf__load(skel);
131+ }
127132 if (err) {
128133 /* too bad, kernel doesn't support BPF iterators yet */
129134 err = 0;
tools/bpf/bpftool/skeleton/pid_iter.bpf.c+2−2
@@ -102,8 +102,8 @@ int iter(struct bpf_iter__task_file *ctx) · 101 unmodified lines
102102 BPF_LINK_TYPE_PERF_EVENT___local)) {
103103 struct bpf_link *link = (struct bpf_link *) file->private_data;
104104
105− if (link->type == bpf_core_enum_value(enum bpf_link_type___local,
106− BPF_LINK_TYPE_PERF_EVENT___local)) {
105+ if (BPF_CORE_READ(link, type) == bpf_core_enum_value(enum bpf_link_type___local,
106+ BPF_LINK_TYPE_PERF_EVENT___local)) {
107107 e.has_bpf_cookie = true;
108108 e.bpf_cookie = get_bpf_cookie(link);
109109 }
tools/include/linux/compiler.h+4−0
@@ -58,6 +58,10 @@ · 57 unmodified lines
5858 #define noinline
5959 #endif
6060
61+#ifndef __nocf_check
62+#define __nocf_check __attribute__((nocf_check))
63+#endif
64+
6165 /* Are two types/vars the same type (ignoring qualifiers)? */
6266 #ifndef __same_type
6367 # define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b))
tools/include/uapi/linux/bpf.h+4−2
@@ -1662,8 +1662,10 @@ union bpf_attr { · 1661 unmodified lines
16621662 } query;
16631663
16641664 struct { /* anonymous struct used by BPF_RAW_TRACEPOINT_OPEN command */
1665− __u64 name;
1666− __u32 prog_fd;
1665+ __u64 name;
1666+ __u32 prog_fd;
1667+ __u32 :32;
1668+ __aligned_u64 cookie;
16671669 } raw_tracepoint;
16681670
16691671 struct { /* anonymous struct for BPF_BTF_LOAD */
tools/lib/bpf/bpf.c+14−2
@@ -785,6 +785,7 @@ int bpf_link_create(int prog_fd, int target_fd, · 784 unmodified lines
785785 if (!OPTS_ZEROED(opts, uprobe_multi))
786786 return libbpf_err(-EINVAL);
787787 break;
788+ case BPF_TRACE_RAW_TP:
788789 case BPF_TRACE_FENTRY:
789790 case BPF_TRACE_FEXIT:
790791 case BPF_MODIFY_RETURN:
@@ -1173,20 +1174,31 @@ int bpf_link_get_info_by_fd(int link_fd, struct bpf_link_info *info, __u32 *info · 382 unmodified lines
11731174 return bpf_obj_get_info_by_fd(link_fd, info, info_len);
11741175 }
11751176
1176−int bpf_raw_tracepoint_open(const char *name, int prog_fd)
1177+int bpf_raw_tracepoint_open_opts(int prog_fd, struct bpf_raw_tp_opts *opts)
11771178 {
11781179 const size_t attr_sz = offsetofend(union bpf_attr, raw_tracepoint);
11791180 union bpf_attr attr;
11801181 int fd;
11811182
1183+ if (!OPTS_VALID(opts, bpf_raw_tp_opts))
1184+ return libbpf_err(-EINVAL);
1185+
11821186 memset(&attr, 0, attr_sz);
1183− attr.raw_tracepoint.name = ptr_to_u64(name);
11841187 attr.raw_tracepoint.prog_fd = prog_fd;
1188+ attr.raw_tracepoint.name = ptr_to_u64(OPTS_GET(opts, tp_name, NULL));
1189+ attr.raw_tracepoint.cookie = OPTS_GET(opts, cookie, 0);
11851190
11861191 fd = sys_bpf_fd(BPF_RAW_TRACEPOINT_OPEN, &attr, attr_sz);
11871192 return libbpf_err_errno(fd);
11881193 }
11891194
1195+int bpf_raw_tracepoint_open(const char *name, int prog_fd)
1196+{
1197+ LIBBPF_OPTS(bpf_raw_tp_opts, opts, .tp_name = name);
1198+
1199+ return bpf_raw_tracepoint_open_opts(prog_fd, &opts);
1200+}
1201+
11901202 int bpf_btf_load(const void *btf_data, size_t btf_size, struct bpf_btf_load_opts *opts)
11911203 {
11921204 const size_t attr_sz = offsetofend(union bpf_attr, btf_token_fd);
tools/lib/bpf/bpf.h+9−0
@@ -617,6 +617,15 @@ LIBBPF_API int bpf_prog_query(int target_fd, enum bpf_attach_type type, · 616 unmodified lines
617617 __u32 query_flags, __u32 *attach_flags,
618618 __u32 *prog_ids, __u32 *prog_cnt);
619619
620+struct bpf_raw_tp_opts {
621+ size_t sz; /* size of this struct for forward/backward compatibility */
622+ const char *tp_name;
623+ __u64 cookie;
624+ size_t :0;
625+};
626+#define bpf_raw_tp_opts__last_field cookie
627+
628+LIBBPF_API int bpf_raw_tracepoint_open_opts(int prog_fd, struct bpf_raw_tp_opts *opts);
620629 LIBBPF_API int bpf_raw_tracepoint_open(const char *name, int prog_fd);
621630 LIBBPF_API int bpf_task_fd_query(int pid, int fd, __u32 flags, char *buf,
622631 __u32 *buf_len, __u32 *prog_id, __u32 *fd_type,
tools/lib/bpf/libbpf.c+92−19
@@ -1132,8 +1132,26 @@ static int bpf_map__init_kern_struct_ops(struct bpf_map *map) · 1131 unmodified lines
11321132 const char *mname;
11331133
11341134 mname = btf__name_by_offset(btf, member->name_off);
1135+ moff = member->offset / 8;
1136+ mdata = data + moff;
1137+ msize = btf__resolve_size(btf, member->type);
1138+ if (msize < 0) {
1139+ pr_warn("struct_ops init_kern %s: failed to resolve the size of member %s\n",
1140+ map->name, mname);
1141+ return msize;
1142+ }
1143+
11351144 kern_member = find_member_by_name(kern_btf, kern_type, mname);
11361145 if (!kern_member) {
1146+ /* Skip all zeros or null fields if they are not
1147+ * presented in the kernel BTF.
1148+ */
1149+ if (libbpf_is_mem_zeroed(mdata, msize)) {
1150+ pr_info("struct_ops %s: member %s not found in kernel, skipping it as it's set to zero\n",
1151+ map->name, mname);
1152+ continue;
1153+ }
1154+
11371155 pr_warn("struct_ops init_kern %s: Cannot find member %s in kernel BTF\n",
11381156 map->name, mname);
11391157 return -ENOTSUP;
@@ -1147,10 +1165,7 @@ static int bpf_map__init_kern_struct_ops(struct bpf_map *map) · 7 unmodified lines
11471165 return -ENOTSUP;
11481166 }
11491167
1150− moff = member->offset / 8;
11511168 kern_moff = kern_member->offset / 8;
1152−
1153− mdata = data + moff;
11541169 kern_mdata = kern_data + kern_moff;
11551170
11561171 mtype = skip_mods_and_typedefs(btf, member->type, &mtype_id);
@@ -1230,9 +1245,8 @@ static int bpf_map__init_kern_struct_ops(struct bpf_map *map) · 73 unmodified lines
12301245 continue;
12311246 }
12321247
1233− msize = btf__resolve_size(btf, mtype_id);
12341248 kern_msize = btf__resolve_size(kern_btf, kern_mtype_id);
1235− if (msize < 0 || kern_msize < 0 || msize != kern_msize) {
1249+ if (kern_msize < 0 || msize != kern_msize) {
12361250 pr_warn("struct_ops init_kern %s: Error in size of member %s: %zd != %zd(kernel)\n",
12371251 map->name, mname, (ssize_t)msize,
12381252 (ssize_t)kern_msize);
@@ -7317,9 +7331,9 @@ static int bpf_object_load_prog(struct bpf_object *obj, struct bpf_program *prog · 6078 unmodified lines
73177331 char *cp, errmsg[STRERR_BUFSIZE];
73187332 size_t log_buf_size = 0;
73197333 char *log_buf = NULL, *tmp;
7320− int btf_fd, ret, err;
73217334 bool own_log_buf = true;
73227335 __u32 log_level = prog->log_level;
7336+ int ret, err;
73237337
73247338 if (prog->type == BPF_PROG_TYPE_UNSPEC) {
73257339 /*
@@ -7343,9 +7357,8 @@ static int bpf_object_load_prog(struct bpf_object *obj, struct bpf_program *prog · 17 unmodified lines
73437357 load_attr.prog_ifindex = prog->prog_ifindex;
73447358
73457359 /* specify func_info/line_info only if kernel supports them */
7346− btf_fd = btf__fd(obj->btf);
7347− if (btf_fd >= 0 && kernel_supports(obj, FEAT_BTF_FUNC)) {
7348− load_attr.prog_btf_fd = btf_fd;
7360+ if (obj->btf && btf__fd(obj->btf) >= 0 && kernel_supports(obj, FEAT_BTF_FUNC)) {
7361+ load_attr.prog_btf_fd = btf__fd(obj->btf);
73497362 load_attr.func_info = prog->func_info;
73507363 load_attr.func_info_rec_size = prog->func_info_rec_size;
73517364 load_attr.func_info_cnt = prog->func_info_cnt;
@@ -8559,6 +8572,11 @@ int bpf_map__pin(struct bpf_map *map, const char *path) · 1207 unmodified lines
85598572 return libbpf_err(-EINVAL);
85608573 }
85618574
8575+ if (map->fd < 0) {
8576+ pr_warn("map '%s': can't pin BPF map without FD (was it created?)\n", map->name);
8577+ return libbpf_err(-EINVAL);
8578+ }
8579+
85628580 if (map->pin_path) {
85638581 if (path && strcmp(path, map->pin_path)) {
85648582 pr_warn("map '%s' already has pin path '%s' different from '%s'\n",
@@ -9294,6 +9312,7 @@ static const struct bpf_sec_def section_defs[] = { · 729 unmodified lines
92949312 SEC_DEF("sockops", SOCK_OPS, BPF_CGROUP_SOCK_OPS, SEC_ATTACHABLE_OPT),
92959313 SEC_DEF("sk_skb/stream_parser", SK_SKB, BPF_SK_SKB_STREAM_PARSER, SEC_ATTACHABLE_OPT),
92969314 SEC_DEF("sk_skb/stream_verdict",SK_SKB, BPF_SK_SKB_STREAM_VERDICT, SEC_ATTACHABLE_OPT),
9315+ SEC_DEF("sk_skb/verdict", SK_SKB, BPF_SK_SKB_VERDICT, SEC_ATTACHABLE_OPT),
92979316 SEC_DEF("sk_skb", SK_SKB, 0, SEC_NONE),
92989317 SEC_DEF("sk_msg", SK_MSG, BPF_SK_MSG_VERDICT, SEC_ATTACHABLE_OPT),
92999318 SEC_DEF("lirc_mode2", LIRC_MODE2, BPF_LIRC_MODE2, SEC_ATTACHABLE_OPT),
@@ -10303,6 +10322,11 @@ static int validate_map_op(const struct bpf_map *map, size_t key_sz, · 1003 unmodified lines
1030310322 return -EINVAL;
1030410323 }
1030510324
10325+ if (map->fd < 0) {
10326+ pr_warn("map '%s': can't use BPF map without FD (was it created?)\n", map->name);
10327+ return -EINVAL;
10328+ }
10329+
1030610330 if (!check_value_sz)
1030710331 return 0;
1030810332
@@ -10415,8 +10439,15 @@ long libbpf_get_error(const void *ptr) · 106 unmodified lines
1041510439 int bpf_link__update_program(struct bpf_link *link, struct bpf_program *prog)
1041610440 {
1041710441 int ret;
10442+ int prog_fd = bpf_program__fd(prog);
1041810443
10419− ret = bpf_link_update(bpf_link__fd(link), bpf_program__fd(prog), NULL);
10444+ if (prog_fd < 0) {
10445+ pr_warn("prog '%s': can't use BPF program without FD (was it loaded?)\n",
10446+ prog->name);
10447+ return libbpf_err(-EINVAL);
10448+ }
10449+
10450+ ret = bpf_link_update(bpf_link__fd(link), prog_fd, NULL);
1042010451 return libbpf_err_errno(ret);
1042110452 }
1042210453
@@ -10610,7 +10641,7 @@ struct bpf_link *bpf_program__attach_perf_event_opts(const struct bpf_program *p · 187 unmodified lines
1061010641 }
1061110642 prog_fd = bpf_program__fd(prog);
1061210643 if (prog_fd < 0) {
10613− pr_warn("prog '%s': can't attach BPF program w/o FD (did you load it?)\n",
10644+ pr_warn("prog '%s': can't attach BPF program without FD (was it loaded?)\n",
1061410645 prog->name);
1061510646 return libbpf_err_ptr(-EINVAL);
1061610647 }
@@ -11334,6 +11365,13 @@ bpf_program__attach_kprobe_multi_opts(const struct bpf_program *prog, · 717 unmodified lines
1133411365 if (!OPTS_VALID(opts, bpf_kprobe_multi_opts))
1133511366 return libbpf_err_ptr(-EINVAL);
1133611367
11368+ prog_fd = bpf_program__fd(prog);
11369+ if (prog_fd < 0) {
11370+ pr_warn("prog '%s': can't attach BPF program without FD (was it loaded?)\n",
11371+ prog->name);
11372+ return libbpf_err_ptr(-EINVAL);
11373+ }
11374+
1133711375 syms = OPTS_GET(opts, syms, false);
1133811376 addrs = OPTS_GET(opts, addrs, false);
1133911377 cnt = OPTS_GET(opts, cnt, false);
@@ -11374,7 +11412,6 @@ bpf_program__attach_kprobe_multi_opts(const struct bpf_program *prog, · 34 unmodified lines
1137411412 }
1137511413 link->detach = &bpf_link__detach_fd;
1137611414
11377− prog_fd = bpf_program__fd(prog);
1137811415 link_fd = bpf_link_create(prog_fd, 0, BPF_TRACE_KPROBE_MULTI, &lopts);
1137911416 if (link_fd < 0) {
1138011417 err = -errno;
@@ -11757,6 +11794,13 @@ bpf_program__attach_uprobe_multi(const struct bpf_program *prog, · 376 unmodified lines
1175711794 if (!OPTS_VALID(opts, bpf_uprobe_multi_opts))
1175811795 return libbpf_err_ptr(-EINVAL);
1175911796
11797+ prog_fd = bpf_program__fd(prog);
11798+ if (prog_fd < 0) {
11799+ pr_warn("prog '%s': can't attach BPF program without FD (was it loaded?)\n",
11800+ prog->name);
11801+ return libbpf_err_ptr(-EINVAL);
11802+ }
11803+
1176011804 syms = OPTS_GET(opts, syms, NULL);
1176111805 offsets = OPTS_GET(opts, offsets, NULL);
1176211806 ref_ctr_offsets = OPTS_GET(opts, ref_ctr_offsets, NULL);
@@ -11832,7 +11876,6 @@ bpf_program__attach_uprobe_multi(const struct bpf_program *prog, · 69 unmodified lines
1183211876 }
1183311877 link->detach = &bpf_link__detach_fd;
1183411878
11835− prog_fd = bpf_program__fd(prog);
1183611879 link_fd = bpf_link_create(prog_fd, 0, BPF_TRACE_UPROBE_MULTI, &lopts);
1183711880 if (link_fd < 0) {
1183811881 err = -errno;
@@ -12076,7 +12119,7 @@ struct bpf_link *bpf_program__attach_usdt(const struct bpf_program *prog, · 237 unmodified lines
1207612119 return libbpf_err_ptr(-EINVAL);
1207712120
1207812121 if (bpf_program__fd(prog) < 0) {
12079− pr_warn("prog '%s': can't attach BPF program w/o FD (did you load it?)\n",
12122+ pr_warn("prog '%s': can't attach BPF program without FD (was it loaded?)\n",
1208012123 prog->name);
1208112124 return libbpf_err_ptr(-EINVAL);
1208212125 }
@@ -12267,13 +12310,19 @@ static int attach_tp(const struct bpf_program *prog, long cookie, struct bpf_lin · 184 unmodified lines
1226712310 return libbpf_get_error(*link);
1226812311 }
1226912312
12270−struct bpf_link *bpf_program__attach_raw_tracepoint(const struct bpf_program *prog,
12271− const char *tp_name)
12313+struct bpf_link *
12314+bpf_program__attach_raw_tracepoint_opts(const struct bpf_program *prog,
12315+ const char *tp_name,
12316+ struct bpf_raw_tracepoint_opts *opts)
1227212317 {
12318+ LIBBPF_OPTS(bpf_raw_tp_opts, raw_opts);
1227312319 char errmsg[STRERR_BUFSIZE];
1227412320 struct bpf_link *link;
1227512321 int prog_fd, pfd;
1227612322
12323+ if (!OPTS_VALID(opts, bpf_raw_tracepoint_opts))
12324+ return libbpf_err_ptr(-EINVAL);
12325+
1227712326 prog_fd = bpf_program__fd(prog);
1227812327 if (prog_fd < 0) {
1227912328 pr_warn("prog '%s': can't attach before loaded\n", prog->name);
@@ -12285,7 +12334,9 @@ struct bpf_link *bpf_program__attach_raw_tracepoint(const struct bpf_program *pr · 5 unmodified lines
1228512334 return libbpf_err_ptr(-ENOMEM);
1228612335 link->detach = &bpf_link__detach_fd;
1228712336
12288− pfd = bpf_raw_tracepoint_open(tp_name, prog_fd);
12337+ raw_opts.tp_name = tp_name;
12338+ raw_opts.cookie = OPTS_GET(opts, cookie, 0);
12339+ pfd = bpf_raw_tracepoint_open_opts(prog_fd, &raw_opts);
1228912340 if (pfd < 0) {
1229012341 pfd = -errno;
1229112342 free(link);
@@ -12297,6 +12348,12 @@ struct bpf_link *bpf_program__attach_raw_tracepoint(const struct bpf_program *pr · 5 unmodified lines
1229712348 return link;
1229812349 }
1229912350
12351+struct bpf_link *bpf_program__attach_raw_tracepoint(const struct bpf_program *prog,
12352+ const char *tp_name)
12353+{
12354+ return bpf_program__attach_raw_tracepoint_opts(prog, tp_name, NULL);
12355+}
12356+
1230012357 static int attach_raw_tp(const struct bpf_program *prog, long cookie, struct bpf_link **link)
1230112358 {
1230212359 static const char *const prefixes[] = {
@@ -12658,6 +12715,12 @@ struct bpf_link *bpf_program__attach(const struct bpf_program *prog) · 355 unmodified lines
1265812715 if (!prog->sec_def || !prog->sec_def->prog_attach_fn)
1265912716 return libbpf_err_ptr(-EOPNOTSUPP);
1266012717
12718+ if (bpf_program__fd(prog) < 0) {
12719+ pr_warn("prog '%s': can't attach BPF program without FD (was it loaded?)\n",
12720+ prog->name);
12721+ return libbpf_err_ptr(-EINVAL);
12722+ }
12723+
1266112724 err = prog->sec_def->prog_attach_fn(prog, prog->sec_def->cookie, &link);
1266212725 if (err)
1266312726 return libbpf_err_ptr(err);
@@ -12698,8 +12761,13 @@ struct bpf_link *bpf_map__attach_struct_ops(const struct bpf_map *map) · 34 unmodified lines
1269812761 __u32 zero = 0;
1269912762 int err, fd;
1270012763
12701− if (!bpf_map__is_struct_ops(map) || map->fd == -1)
12764+ if (!bpf_map__is_struct_ops(map))
12765+ return libbpf_err_ptr(-EINVAL);
12766+
12767+ if (map->fd < 0) {
12768+ pr_warn("map '%s': can't attach BPF map without FD (was it created?)\n", map->name);
1270212769 return libbpf_err_ptr(-EINVAL);
12770+ }
1270312771
1270412772 link = calloc(1, sizeof(*link));
1270512773 if (!link)
@@ -12747,9 +12815,14 @@ int bpf_link__update_map(struct bpf_link *link, const struct bpf_map *map) · 41 unmodified lines
1274712815 __u32 zero = 0;
1274812816 int err;
1274912817
12750− if (!bpf_map__is_struct_ops(map) || !map_is_created(map))
12818+ if (!bpf_map__is_struct_ops(map))
1275112819 return -EINVAL;
1275212820
12821+ if (map->fd < 0) {
12822+ pr_warn("map '%s': can't use BPF map without FD (was it created?)\n", map->name);
12823+ return -EINVAL;
12824+ }
12825+
1275312826 st_ops_link = container_of(link, struct bpf_link_struct_ops, link);
1275412827 /* Ensure the type of a link is correct */
1275512828 if (st_ops_link->map_fd < 0)
tools/lib/bpf/libbpf.h+11−0
@@ -760,9 +760,20 @@ bpf_program__attach_tracepoint_opts(const struct bpf_program *prog, · 759 unmodified lines
760760 const char *tp_name,
761761 const struct bpf_tracepoint_opts *opts);
762762
763+struct bpf_raw_tracepoint_opts {
764+ size_t sz; /* size of this struct for forward/backward compatibility */
765+ __u64 cookie;
766+ size_t :0;
767+};
768+#define bpf_raw_tracepoint_opts__last_field cookie
769+
763770 LIBBPF_API struct bpf_link *
764771 bpf_program__attach_raw_tracepoint(const struct bpf_program *prog,
765772 const char *tp_name);
773+LIBBPF_API struct bpf_link *
774+bpf_program__attach_raw_tracepoint_opts(const struct bpf_program *prog,
775+ const char *tp_name,
776+ struct bpf_raw_tracepoint_opts *opts);
766777
767778 struct bpf_trace_opts {
768779 /* size of this struct, for forward/backward compatibility */
tools/lib/bpf/libbpf.map+2−0
@@ -410,6 +410,8 @@ LIBBPF_1.3.0 { · 409 unmodified lines
410410
411411 LIBBPF_1.4.0 {
412412 global:
413+ bpf_program__attach_raw_tracepoint_opts;
414+ bpf_raw_tracepoint_open_opts;
413415 bpf_token_create;
414416 btf__new_split;
415417 btf_ext__raw_data;
tools/testing/selftests/bpf/benchs/bench_local_storage_create.c+1−1
@@ -186,7 +186,7 @@ static void *task_producer(void *input) · 185 unmodified lines
186186
187187 for (i = 0; i < batch_sz; i++) {
188188 if (!pthd_results[i])
189− pthread_join(pthds[i], NULL);;
189+ pthread_join(pthds[i], NULL);
190190 }
191191 }
192192
tools/testing/selftests/bpf/benchs/bench_trigger.c+40−8
@@ -1,15 +1,47 @@
11 // SPDX-License-Identifier: GPL-2.0
22 /* Copyright (c) 2020 Facebook */
3+#define _GNU_SOURCE
4+#include <unistd.h>
35 #include "bench.h"
46 #include "trigger_bench.skel.h"
57 #include "trace_helpers.h"
68
9+/* adjust slot shift in inc_hits() if changing */
10+#define MAX_BUCKETS 256
11+
12+#pragma GCC diagnostic ignored "-Wattributes"
13+
714 /* BPF triggering benchmarks */
815 static struct trigger_ctx {
916 struct trigger_bench *skel;
1017 } ctx;
1118
12−static struct counter base_hits;
19+static struct counter base_hits[MAX_BUCKETS];
20+
21+static __always_inline void inc_counter(struct counter *counters)
22+{
23+ static __thread int tid = 0;
24+ unsigned slot;
25+
26+ if (unlikely(tid == 0))
27+ tid = syscall(SYS_gettid);
28+
29+ /* multiplicative hashing, it's fast */
30+ slot = 2654435769U * tid;
31+ slot >>= 24;
32+
33+ atomic_inc(&base_hits[slot].value); /* use highest byte as an index */
34+}
35+
36+static long sum_and_reset_counters(struct counter *counters)
37+{
38+ int i;
39+ long sum = 0;
40+
41+ for (i = 0; i < MAX_BUCKETS; i++)
42+ sum += atomic_swap(&counters[i].value, 0);
43+ return sum;
44+}
1345
1446 static void trigger_validate(void)
1547 {
@@ -23,14 +55,14 @@ static void *trigger_base_producer(void *input) · 7 unmodified lines
2355 {
2456 while (true) {
2557 (void)syscall(__NR_getpgid);
26− atomic_inc(&base_hits.value);
58+ inc_counter(base_hits);
2759 }
2860 return NULL;
2961 }
3062
3163 static void trigger_base_measure(struct bench_res *res)
3264 {
33− res->hits = atomic_swap(&base_hits.value, 0);
65+ res->hits = sum_and_reset_counters(base_hits);
3466 }
3567
3668 static void *trigger_producer(void *input)
@@ -42,7 +74,7 @@ static void *trigger_producer(void *input) · 5 unmodified lines
4274
4375 static void trigger_measure(struct bench_res *res)
4476 {
45− res->hits = atomic_swap(&ctx.skel->bss->hits, 0);
77+ res->hits = sum_and_reset_counters(ctx.skel->bss->hits);
4678 }
4779
4880 static void setup_ctx(void)
@@ -137,7 +169,7 @@ static void trigger_fmodret_setup(void) · 88 unmodified lines
137169 * GCC doesn't generate stack setup preample for these functions due to them
138170 * having no input arguments and doing nothing in the body.
139171 */
140−__weak void uprobe_target_nop(void)
172+__nocf_check __weak void uprobe_target_nop(void)
141173 {
142174 asm volatile ("nop");
143175 }
@@ -146,7 +178,7 @@ __weak void opaque_noop_func(void) · 2 unmodified lines
146178 {
147179 }
148180
149−__weak int uprobe_target_push(void)
181+__nocf_check __weak int uprobe_target_push(void)
150182 {
151183 /* overhead of function call is negligible compared to uprobe
152184 * triggering, so this shouldn't affect benchmark results much
@@ -155,7 +187,7 @@ __weak int uprobe_target_push(void) · 2 unmodified lines
155187 return 1;
156188 }
157189
158−__weak void uprobe_target_ret(void)
190+__nocf_check __weak void uprobe_target_ret(void)
159191 {
160192 asm volatile ("");
161193 }
@@ -164,7 +196,7 @@ static void *uprobe_base_producer(void *input) · 2 unmodified lines
164196 {
165197 while (true) {
166198 uprobe_target_nop();
167− atomic_inc(&base_hits.value);
199+ inc_counter(base_hits);
168200 }
169201 return NULL;
170202 }
tools/testing/selftests/bpf/prog_tests/bpf_cookie.c+113−1
@@ -573,6 +573,115 @@ cleanup: · 572 unmodified lines
573573 close(lsm_fd);
574574 }
575575
576+static void tp_btf_subtest(struct test_bpf_cookie *skel)
577+{
578+ __u64 cookie;
579+ int prog_fd, link_fd = -1;
580+ struct bpf_link *link = NULL;
581+ LIBBPF_OPTS(bpf_link_create_opts, link_opts);
582+ LIBBPF_OPTS(bpf_raw_tp_opts, raw_tp_opts);
583+ LIBBPF_OPTS(bpf_trace_opts, trace_opts);
584+
585+ /* There are three different ways to attach tp_btf (BTF-aware raw
586+ * tracepoint) programs. Let's test all of them.
587+ */
588+ prog_fd = bpf_program__fd(skel->progs.handle_tp_btf);
589+
590+ /* low-level BPF_RAW_TRACEPOINT_OPEN command wrapper */
591+ skel->bss->tp_btf_res = 0;
592+
593+ raw_tp_opts.cookie = cookie = 0x11000000000000L;
594+ link_fd = bpf_raw_tracepoint_open_opts(prog_fd, &raw_tp_opts);
595+ if (!ASSERT_GE(link_fd, 0, "bpf_raw_tracepoint_open_opts"))
596+ goto cleanup;
597+
598+ usleep(1); /* trigger */
599+ close(link_fd); /* detach */
600+ link_fd = -1;
601+
602+ ASSERT_EQ(skel->bss->tp_btf_res, cookie, "raw_tp_open_res");
603+
604+ /* low-level generic bpf_link_create() API */
605+ skel->bss->tp_btf_res = 0;
606+
607+ link_opts.tracing.cookie = cookie = 0x22000000000000L;
608+ link_fd = bpf_link_create(prog_fd, 0, BPF_TRACE_RAW_TP, &link_opts);
609+ if (!ASSERT_GE(link_fd, 0, "bpf_link_create"))
610+ goto cleanup;
611+
612+ usleep(1); /* trigger */
613+ close(link_fd); /* detach */
614+ link_fd = -1;
615+
616+ ASSERT_EQ(skel->bss->tp_btf_res, cookie, "link_create_res");
617+
618+ /* high-level bpf_link-based bpf_program__attach_trace_opts() API */
619+ skel->bss->tp_btf_res = 0;
620+
621+ trace_opts.cookie = cookie = 0x33000000000000L;
622+ link = bpf_program__attach_trace_opts(skel->progs.handle_tp_btf, &trace_opts);
623+ if (!ASSERT_OK_PTR(link, "attach_trace_opts"))
624+ goto cleanup;
625+
626+ usleep(1); /* trigger */
627+ bpf_link__destroy(link); /* detach */
628+ link = NULL;
629+
630+ ASSERT_EQ(skel->bss->tp_btf_res, cookie, "attach_trace_opts_res");
631+
632+cleanup:
633+ if (link_fd >= 0)
634+ close(link_fd);
635+ bpf_link__destroy(link);
636+}
637+
638+static void raw_tp_subtest(struct test_bpf_cookie *skel)
639+{
640+ __u64 cookie;
641+ int prog_fd, link_fd = -1;
642+ struct bpf_link *link = NULL;
643+ LIBBPF_OPTS(bpf_raw_tp_opts, raw_tp_opts);
644+ LIBBPF_OPTS(bpf_raw_tracepoint_opts, opts);
645+
646+ /* There are two different ways to attach raw_tp programs */
647+ prog_fd = bpf_program__fd(skel->progs.handle_raw_tp);
648+
649+ /* low-level BPF_RAW_TRACEPOINT_OPEN command wrapper */
650+ skel->bss->raw_tp_res = 0;
651+
652+ raw_tp_opts.tp_name = "sys_enter";
653+ raw_tp_opts.cookie = cookie = 0x55000000000000L;
654+ link_fd = bpf_raw_tracepoint_open_opts(prog_fd, &raw_tp_opts);
655+ if (!ASSERT_GE(link_fd, 0, "bpf_raw_tracepoint_open_opts"))
656+ goto cleanup;
657+
658+ usleep(1); /* trigger */
659+ close(link_fd); /* detach */
660+ link_fd = -1;
661+
662+ ASSERT_EQ(skel->bss->raw_tp_res, cookie, "raw_tp_open_res");
663+
664+ /* high-level bpf_link-based bpf_program__attach_raw_tracepoint_opts() API */
665+ skel->bss->raw_tp_res = 0;
666+
667+ opts.cookie = cookie = 0x66000000000000L;
668+ link = bpf_program__attach_raw_tracepoint_opts(skel->progs.handle_raw_tp,
669+ "sys_enter", &opts);
670+ if (!ASSERT_OK_PTR(link, "attach_raw_tp_opts"))
671+ goto cleanup;
672+
673+ usleep(1); /* trigger */
674+ bpf_link__destroy(link); /* detach */
675+ link = NULL;
676+
677+ ASSERT_EQ(skel->bss->raw_tp_res, cookie, "attach_raw_tp_opts_res");
678+
679+cleanup:
680+ if (link_fd >= 0)
681+ close(link_fd);
682+ bpf_link__destroy(link);
683+}
684+
576685 void test_bpf_cookie(void)
577686 {
578687 struct test_bpf_cookie *skel;
@@ -601,6 +710,9 @@ void test_bpf_cookie(void) · 22 unmodified lines
601710 tracing_subtest(skel);
602711 if (test__start_subtest("lsm"))
603712 lsm_subtest(skel);
604−
713+ if (test__start_subtest("tp_btf"))
714+ tp_btf_subtest(skel);
715+ if (test__start_subtest("raw_tp"))
716+ raw_tp_subtest(skel);
605717 test_bpf_cookie__destroy(skel);
606718 }
tools/testing/selftests/bpf/prog_tests/bpf_tcp_ca.c+1−12
@@ -89,7 +89,7 @@ static void do_test(const char *tcp_ca, const struct bpf_map *sk_stg_map) · 88 unmodified lines
8989
9090 WRITE_ONCE(stop, 0);
9191
92− lfd = socket(AF_INET6, SOCK_STREAM, 0);
92+ lfd = start_server(AF_INET6, SOCK_STREAM, NULL, 0, 0);
9393 if (!ASSERT_NEQ(lfd, -1, "socket"))
9494 return;
9595
@@ -103,21 +103,10 @@ static void do_test(const char *tcp_ca, const struct bpf_map *sk_stg_map) · 7 unmodified lines
103103 settimeo(lfd, 0) || settimeo(fd, 0))
104104 goto done;
105105
106− /* bind, listen and start server thread to accept */
107− sa6.sin6_family = AF_INET6;
108− sa6.sin6_addr = in6addr_loopback;
109− err = bind(lfd, (struct sockaddr *)&sa6, addrlen);
110− if (!ASSERT_NEQ(err, -1, "bind"))
111− goto done;
112−
113106 err = getsockname(lfd, (struct sockaddr *)&sa6, &addrlen);
114107 if (!ASSERT_NEQ(err, -1, "getsockname"))
115108 goto done;
116109
117− err = listen(lfd, 1);
118− if (!ASSERT_NEQ(err, -1, "listen"))
119− goto done;
120−
121110 if (sk_stg_map) {
122111 err = bpf_map_update_elem(bpf_map__fd(sk_stg_map), &fd,
123112 &expected_stg, BPF_NOEXIST);
tools/testing/selftests/bpf/prog_tests/btf_map_in_map.c+1−25
@@ -25,7 +25,7 @@ static void test_lookup_update(void) · 24 unmodified lines
2525 int map1_fd, map2_fd, map3_fd, map4_fd, map5_fd, map1_id, map2_id;
2626 int outer_arr_fd, outer_hash_fd, outer_arr_dyn_fd;
2727 struct test_btf_map_in_map *skel;
28− int err, key = 0, val, i, fd;
28+ int err, key = 0, val, i;
2929
3030 skel = test_btf_map_in_map__open_and_load();
3131 if (CHECK(!skel, "skel_open", "failed to open&load skeleton\n"))
@@ -102,30 +102,6 @@ static void test_lookup_update(void) · 70 unmodified lines
102102 CHECK(map1_id == 0, "map1_id", "failed to get ID 1\n");
103103 CHECK(map2_id == 0, "map2_id", "failed to get ID 2\n");
104104
105− test_btf_map_in_map__destroy(skel);
106− skel = NULL;
107−
108− /* we need to either wait for or force synchronize_rcu(), before
109− * checking for "still exists" condition, otherwise map could still be
110− * resolvable by ID, causing false positives.
111− *
112− * Older kernels (5.8 and earlier) freed map only after two
113− * synchronize_rcu()s, so trigger two, to be entirely sure.
114− */
115− CHECK(kern_sync_rcu(), "sync_rcu", "failed\n");
116− CHECK(kern_sync_rcu(), "sync_rcu", "failed\n");
117−
118− fd = bpf_map_get_fd_by_id(map1_id);
119− if (CHECK(fd >= 0, "map1_leak", "inner_map1 leaked!\n")) {
120− close(fd);
121− goto cleanup;
122− }
123− fd = bpf_map_get_fd_by_id(map2_id);
124− if (CHECK(fd >= 0, "map2_leak", "inner_map2 leaked!\n")) {
125− close(fd);
126− goto cleanup;
127− }
128−
129105 cleanup:
130106 test_btf_map_in_map__destroy(skel);
131107 }
tools/testing/selftests/bpf/prog_tests/ns_current_pid_tgid.c+183−31
@@ -12,77 +12,229 @@ · 11 unmodified lines
1212 #include <sys/wait.h>
1313 #include <sys/mount.h>
1414 #include <sys/fcntl.h>
15+#include "network_helpers.h"
1516
1617 #define STACK_SIZE (1024 * 1024)
1718 static char child_stack[STACK_SIZE];
1819
19−static int test_current_pid_tgid(void *args)
20+static int get_pid_tgid(pid_t *pid, pid_t *tgid,
21+ struct test_ns_current_pid_tgid__bss *bss)
2022 {
21− struct test_ns_current_pid_tgid__bss *bss;
22− struct test_ns_current_pid_tgid *skel;
23− int err = -1, duration = 0;
24− pid_t tgid, pid;
2523 struct stat st;
24+ int err;
2625
27− skel = test_ns_current_pid_tgid__open_and_load();
28− if (CHECK(!skel, "skel_open_load", "failed to load skeleton\n"))
29− goto cleanup;
30−
31− pid = syscall(SYS_gettid);
32− tgid = getpid();
26+ *pid = syscall(SYS_gettid);
27+ *tgid = getpid();
3328
3429 err = stat("/proc/self/ns/pid", &st);
35− if (CHECK(err, "stat", "failed /proc/self/ns/pid: %d\n", err))
36− goto cleanup;
30+ if (!ASSERT_OK(err, "stat /proc/self/ns/pid"))
31+ return err;
3732
38− bss = skel->bss;
3933 bss->dev = st.st_dev;
4034 bss->ino = st.st_ino;
4135 bss->user_pid = 0;
4236 bss->user_tgid = 0;
37+ return 0;
38+}
39+
40+static int test_current_pid_tgid_tp(void *args)
41+{
42+ struct test_ns_current_pid_tgid__bss *bss;
43+ struct test_ns_current_pid_tgid *skel;
44+ int ret = -1, err;
45+ pid_t tgid, pid;
46+
47+ skel = test_ns_current_pid_tgid__open();
48+ if (!ASSERT_OK_PTR(skel, "test_ns_current_pid_tgid__open"))
49+ return ret;
50+
51+ bpf_program__set_autoload(skel->progs.tp_handler, true);
52+
53+ err = test_ns_current_pid_tgid__load(skel);
54+ if (!ASSERT_OK(err, "test_ns_current_pid_tgid__load"))
55+ goto cleanup;
56+
57+ bss = skel->bss;
58+ if (get_pid_tgid(&pid, &tgid, bss))
59+ goto cleanup;
4360
4461 err = test_ns_current_pid_tgid__attach(skel);
45− if (CHECK(err, "skel_attach", "skeleton attach failed: %d\n", err))
62+ if (!ASSERT_OK(err, "test_ns_current_pid_tgid__attach"))
4663 goto cleanup;
4764
4865 /* trigger tracepoint */
4966 usleep(1);
50− ASSERT_EQ(bss->user_pid, pid, "pid");
51− ASSERT_EQ(bss->user_tgid, tgid, "tgid");
52− err = 0;
67+ if (!ASSERT_EQ(bss->user_pid, pid, "pid"))
68+ goto cleanup;
69+ if (!ASSERT_EQ(bss->user_tgid, tgid, "tgid"))
70+ goto cleanup;
71+ ret = 0;
72+
73+cleanup:
74+ test_ns_current_pid_tgid__destroy(skel);
75+ return ret;
76+}
77+
78+static int test_current_pid_tgid_cgrp(void *args)
79+{
80+ struct test_ns_current_pid_tgid__bss *bss;
81+ struct test_ns_current_pid_tgid *skel;
82+ int server_fd = -1, ret = -1, err;
83+ int cgroup_fd = *(int *)args;
84+ pid_t tgid, pid;
85+
86+ skel = test_ns_current_pid_tgid__open();
87+ if (!ASSERT_OK_PTR(skel, "test_ns_current_pid_tgid__open"))
88+ return ret;
89+
90+ bpf_program__set_autoload(skel->progs.cgroup_bind4, true);
91+
92+ err = test_ns_current_pid_tgid__load(skel);
93+ if (!ASSERT_OK(err, "test_ns_current_pid_tgid__load"))
94+ goto cleanup;
95+
96+ bss = skel->bss;
97+ if (get_pid_tgid(&pid, &tgid, bss))
98+ goto cleanup;
99+
100+ skel->links.cgroup_bind4 = bpf_program__attach_cgroup(
101+ skel->progs.cgroup_bind4, cgroup_fd);
102+ if (!ASSERT_OK_PTR(skel->links.cgroup_bind4, "bpf_program__attach_cgroup"))
103+ goto cleanup;
104+
105+ server_fd = start_server(AF_INET, SOCK_STREAM, NULL, 0, 0);
106+ if (!ASSERT_GE(server_fd, 0, "start_server"))
107+ goto cleanup;
108+
109+ if (!ASSERT_EQ(bss->user_pid, pid, "pid"))
110+ goto cleanup;
111+ if (!ASSERT_EQ(bss->user_tgid, tgid, "tgid"))
112+ goto cleanup;
113+ ret = 0;
53114
54115 cleanup:
55− test_ns_current_pid_tgid__destroy(skel);
116+ if (server_fd >= 0)
117+ close(server_fd);
118+ test_ns_current_pid_tgid__destroy(skel);
119+ return ret;
120+}
121+
122+static int test_current_pid_tgid_sk_msg(void *args)
123+{
124+ int verdict, map, server_fd = -1, client_fd = -1;
125+ struct test_ns_current_pid_tgid__bss *bss;
126+ static const char send_msg[] = "message";
127+ struct test_ns_current_pid_tgid *skel;
128+ int ret = -1, err, key = 0;
129+ pid_t tgid, pid;
130+
131+ skel = test_ns_current_pid_tgid__open();
132+ if (!ASSERT_OK_PTR(skel, "test_ns_current_pid_tgid__open"))
133+ return ret;
134+
135+ bpf_program__set_autoload(skel->progs.sk_msg, true);
136+
137+ err = test_ns_current_pid_tgid__load(skel);
138+ if (!ASSERT_OK(err, "test_ns_current_pid_tgid__load"))
139+ goto cleanup;
140+
141+ bss = skel->bss;
142+ if (get_pid_tgid(&pid, &tgid, skel->bss))
143+ goto cleanup;
144+
145+ verdict = bpf_program__fd(skel->progs.sk_msg);
146+ map = bpf_map__fd(skel->maps.sock_map);
147+ err = bpf_prog_attach(verdict, map, BPF_SK_MSG_VERDICT, 0);
148+ if (!ASSERT_OK(err, "prog_attach"))
149+ goto cleanup;
150+
151+ server_fd = start_server(AF_INET6, SOCK_STREAM, "::1", 0, 0);
152+ if (!ASSERT_GE(server_fd, 0, "start_server"))
153+ goto cleanup;
56154
57− return err;
155+ client_fd = connect_to_fd(server_fd, 0);
156+ if (!ASSERT_GE(client_fd, 0, "connect_to_fd"))
157+ goto cleanup;
158+
159+ err = bpf_map_update_elem(map, &key, &client_fd, BPF_ANY);
160+ if (!ASSERT_OK(err, "bpf_map_update_elem"))
161+ goto cleanup;
162+
163+ err = send(client_fd, send_msg, sizeof(send_msg), 0);
164+ if (!ASSERT_EQ(err, sizeof(send_msg), "send(msg)"))
165+ goto cleanup;
166+
167+ if (!ASSERT_EQ(bss->user_pid, pid, "pid"))
168+ goto cleanup;
169+ if (!ASSERT_EQ(bss->user_tgid, tgid, "tgid"))
170+ goto cleanup;
171+ ret = 0;
172+
173+cleanup:
174+ if (server_fd >= 0)
175+ close(server_fd);
176+ if (client_fd >= 0)
177+ close(client_fd);
178+ test_ns_current_pid_tgid__destroy(skel);
179+ return ret;
58180 }
59181
60−static void test_ns_current_pid_tgid_new_ns(void)
182+static void test_ns_current_pid_tgid_new_ns(int (*fn)(void *), void *arg)
61183 {
62− int wstatus, duration = 0;
184+ int wstatus;
63185 pid_t cpid;
64186
65187 /* Create a process in a new namespace, this process
66188 * will be the init process of this new namespace hence will be pid 1.
67189 */
68− cpid = clone(test_current_pid_tgid, child_stack + STACK_SIZE,
69− CLONE_NEWPID | SIGCHLD, NULL);
190+ cpid = clone(fn, child_stack + STACK_SIZE,
191+ CLONE_NEWPID | SIGCHLD, arg);
70192
71− if (CHECK(cpid == -1, "clone", "%s\n", strerror(errno)))
193+ if (!ASSERT_NEQ(cpid, -1, "clone"))
72194 return;
73195
74− if (CHECK(waitpid(cpid, &wstatus, 0) == -1, "waitpid", "%s\n", strerror(errno)))
196+ if (!ASSERT_NEQ(waitpid(cpid, &wstatus, 0), -1, "waitpid"))
75197 return;
76198
77− if (CHECK(WEXITSTATUS(wstatus) != 0, "newns_pidtgid", "failed"))
199+ if (!ASSERT_OK(WEXITSTATUS(wstatus), "newns_pidtgid"))
78200 return;
79201 }
80202
203+static void test_in_netns(int (*fn)(void *), void *arg)
204+{
205+ struct nstoken *nstoken = NULL;
206+
207+ SYS(cleanup, "ip netns add ns_current_pid_tgid");
208+ SYS(cleanup, "ip -net ns_current_pid_tgid link set dev lo up");
209+
210+ nstoken = open_netns("ns_current_pid_tgid");
211+ if (!ASSERT_OK_PTR(nstoken, "open_netns"))
212+ goto cleanup;
213+
214+ test_ns_current_pid_tgid_new_ns(fn, arg);
215+
216+cleanup:
217+ if (nstoken)
218+ close_netns(nstoken);
219+ SYS_NOFAIL("ip netns del ns_current_pid_tgid");
220+}
221+
81222 /* TODO: use a different tracepoint */
82223 void serial_test_ns_current_pid_tgid(void)
83224 {
84− if (test__start_subtest("ns_current_pid_tgid_root_ns"))
85− test_current_pid_tgid(NULL);
86− if (test__start_subtest("ns_current_pid_tgid_new_ns"))
87− test_ns_current_pid_tgid_new_ns();
225+ if (test__start_subtest("root_ns_tp"))
226+ test_current_pid_tgid_tp(NULL);
227+ if (test__start_subtest("new_ns_tp"))
228+ test_ns_current_pid_tgid_new_ns(test_current_pid_tgid_tp, NULL);
229+ if (test__start_subtest("new_ns_cgrp")) {
230+ int cgroup_fd = -1;
231+
232+ cgroup_fd = test__join_cgroup("/sock_addr");
233+ if (ASSERT_GE(cgroup_fd, 0, "join_cgroup")) {
234+ test_in_netns(test_current_pid_tgid_cgrp, &cgroup_fd);
235+ close(cgroup_fd);
236+ }
237+ }
238+ if (test__start_subtest("new_ns_sk_msg"))
239+ test_in_netns(test_current_pid_tgid_sk_msg, NULL);
88240 }
tools/testing/selftests/bpf/prog_tests/test_struct_ops_module.c+47−0
@@ -93,9 +93,56 @@ cleanup: · 92 unmodified lines
9393 struct_ops_module__destroy(skel);
9494 }
9595
96+static void test_struct_ops_not_zeroed(void)
97+{
98+ struct struct_ops_module *skel;
99+ int err;
100+
101+ /* zeroed is 0, and zeroed_op is null */
102+ skel = struct_ops_module__open();
103+ if (!ASSERT_OK_PTR(skel, "struct_ops_module_open"))
104+ return;
105+
106+ err = struct_ops_module__load(skel);
107+ ASSERT_OK(err, "struct_ops_module_load");
108+
109+ struct_ops_module__destroy(skel);
110+
111+ /* zeroed is not 0 */
112+ skel = struct_ops_module__open();
113+ if (!ASSERT_OK_PTR(skel, "struct_ops_module_open_not_zeroed"))
114+ return;
115+
116+ /* libbpf should reject the testmod_zeroed since struct
117+ * bpf_testmod_ops in the kernel has no "zeroed" field and the
118+ * value of "zeroed" is non-zero.
119+ */
120+ skel->struct_ops.testmod_zeroed->zeroed = 0xdeadbeef;
121+ err = struct_ops_module__load(skel);
122+ ASSERT_ERR(err, "struct_ops_module_load_not_zeroed");
123+
124+ struct_ops_module__destroy(skel);
125+
126+ /* zeroed_op is not null */
127+ skel = struct_ops_module__open();
128+ if (!ASSERT_OK_PTR(skel, "struct_ops_module_open_not_zeroed_op"))
129+ return;
130+
131+ /* libbpf should reject the testmod_zeroed since the value of its
132+ * "zeroed_op" is not null.
133+ */
134+ skel->struct_ops.testmod_zeroed->zeroed_op = skel->progs.test_3;
135+ err = struct_ops_module__load(skel);
136+ ASSERT_ERR(err, "struct_ops_module_load_not_zeroed_op");
137+
138+ struct_ops_module__destroy(skel);
139+}
140+
96141 void serial_test_struct_ops_module(void)
97142 {
98143 if (test__start_subtest("test_struct_ops_load"))
99144 test_struct_ops_load();
145+ if (test__start_subtest("test_struct_ops_not_zeroed"))
146+ test_struct_ops_not_zeroed();
100147 }
101148
tools/testing/selftests/bpf/progs/iters.c+1−1
@@ -673,7 +673,7 @@ static __noinline void fill(struct bpf_iter_num *it, int *arr, __u32 n, int mul) · 672 unmodified lines
673673
674674 static __noinline int sum(struct bpf_iter_num *it, int *arr, __u32 n)
675675 {
676− int *t, i, sum = 0;;
676+ int *t, i, sum = 0;
677677
678678 while ((t = bpf_iter_num_next(it))) {
679679 i = *t;
tools/testing/selftests/bpf/progs/struct_ops_module.c+15−1
@@ -23,7 +23,7 @@ void BPF_PROG(test_2, int a, int b) · 22 unmodified lines
2323 test_2_result = a + b;
2424 }
2525
26−SEC("struct_ops/test_3")
26+SEC("?struct_ops/test_3")
2727 int BPF_PROG(test_3, int a, int b)
2828 {
2929 test_2_result = a + b + 3;
@@ -54,3 +54,17 @@ struct bpf_testmod_ops___v2 testmod_2 = { · 24 unmodified lines
5454 .test_1 = (void *)test_1,
5555 .test_2 = (void *)test_2_v2,
5656 };
57+
58+struct bpf_testmod_ops___zeroed {
59+ int (*test_1)(void);
60+ void (*test_2)(int a, int b);
61+ int (*test_maybe_null)(int dummy, struct task_struct *task);
62+ void (*zeroed_op)(int a, int b);
63+ int zeroed;
64+};
65+
66+SEC(".struct_ops.link")
67+struct bpf_testmod_ops___zeroed testmod_zeroed = {
68+ .test_1 = (void *)test_1,
69+ .test_2 = (void *)test_2_v2,
70+};
tools/testing/selftests/bpf/progs/test_bpf_cookie.c+16−0
@@ -15,6 +15,8 @@ __u64 uprobe_res; · 14 unmodified lines
1515 __u64 uretprobe_res;
1616 __u64 tp_res;
1717 __u64 pe_res;
18+__u64 raw_tp_res;
19+__u64 tp_btf_res;
1820 __u64 fentry_res;
1921 __u64 fexit_res;
2022 __u64 fmod_ret_res;
@@ -87,6 +89,20 @@ int handle_pe(struct pt_regs *ctx) · 66 unmodified lines
8789 return 0;
8890 }
8991
92+SEC("raw_tp/sys_enter")
93+int handle_raw_tp(void *ctx)
94+{
95+ update(ctx, &raw_tp_res);
96+ return 0;
97+}
98+
99+SEC("tp_btf/sys_enter")
100+int handle_tp_btf(void *ctx)
101+{
102+ update(ctx, &tp_btf_res);
103+ return 0;
104+}
105+
90106 SEC("fentry/bpf_fentry_test1")
91107 int BPF_PROG(fentry_test1, int a)
92108 {
tools/testing/selftests/bpf/progs/test_ns_current_pid_tgid.c+28−3
@@ -5,23 +5,48 @@ · 4 unmodified lines
55 #include <stdint.h>
66 #include <bpf/bpf_helpers.h>
77
8+struct {
9+ __uint(type, BPF_MAP_TYPE_SOCKMAP);
10+ __uint(max_entries, 2);
11+ __type(key, __u32);
12+ __type(value, __u32);
13+} sock_map SEC(".maps");
14+
815 __u64 user_pid = 0;
916 __u64 user_tgid = 0;
1017 __u64 dev = 0;
1118 __u64 ino = 0;
1219
13−SEC("tracepoint/syscalls/sys_enter_nanosleep")
14−int handler(const void *ctx)
20+static void get_pid_tgid(void)
1521 {
1622 struct bpf_pidns_info nsdata;
1723
1824 if (bpf_get_ns_current_pid_tgid(dev, ino, &nsdata, sizeof(struct bpf_pidns_info)))
19− return 0;
25+ return;
2026
2127 user_pid = nsdata.pid;
2228 user_tgid = nsdata.tgid;
29+}
2330
31+SEC("?tracepoint/syscalls/sys_enter_nanosleep")
32+int tp_handler(const void *ctx)
33+{
34+ get_pid_tgid();
2435 return 0;
2536 }
2637
38+SEC("?cgroup/bind4")
39+int cgroup_bind4(struct bpf_sock_addr *ctx)
40+{
41+ get_pid_tgid();
42+ return 1;
43+}
44+
45+SEC("?sk_msg")
46+int sk_msg(struct sk_msg_md *msg)
47+{
48+ get_pid_tgid();
49+ return SK_PASS;
50+}
51+
2752 char _license[] SEC("license") = "GPL";
tools/testing/selftests/bpf/progs/trigger_bench.c+27−12
@@ -9,12 +9,27 @@ · 8 unmodified lines
99
1010 char _license[] SEC("license") = "GPL";
1111
12−long hits = 0;
12+#define CPU_MASK 255
13+#define MAX_CPUS (CPU_MASK + 1) /* should match MAX_BUCKETS in benchs/bench_trigger.c */
14+
15+/* matches struct counter in bench.h */
16+struct counter {
17+ long value;
18+} __attribute__((aligned(128)));
19+
20+struct counter hits[MAX_CPUS];
21+
22+static __always_inline void inc_counter(void)
23+{
24+ int cpu = bpf_get_smp_processor_id();
25+
26+ __sync_add_and_fetch(&hits[cpu & CPU_MASK].value, 1);
27+}
1328
1429 SEC("tp/syscalls/sys_enter_getpgid")
1530 int bench_trigger_tp(void *ctx)
1631 {
17− __sync_add_and_fetch(&hits, 1);
32+ inc_counter();
1833 return 0;
1934 }
2035
@@ -22,69 +37,69 @@ SEC("raw_tp/sys_enter") · 1 unmodified line
2237 int BPF_PROG(bench_trigger_raw_tp, struct pt_regs *regs, long id)
2338 {
2439 if (id == __NR_getpgid)
25− __sync_add_and_fetch(&hits, 1);
40+ inc_counter();
2641 return 0;
2742 }
2843
2944 SEC("kprobe/" SYS_PREFIX "sys_getpgid")
3045 int bench_trigger_kprobe(void *ctx)
3146 {
32− __sync_add_and_fetch(&hits, 1);
47+ inc_counter();
3348 return 0;
3449 }
3550
3651 SEC("kretprobe/" SYS_PREFIX "sys_getpgid")
3752 int bench_trigger_kretprobe(void *ctx)
3853 {
39− __sync_add_and_fetch(&hits, 1);
54+ inc_counter();
4055 return 0;
4156 }
4257
4358 SEC("kprobe.multi/" SYS_PREFIX "sys_getpgid")
4459 int bench_trigger_kprobe_multi(void *ctx)
4560 {
46− __sync_add_and_fetch(&hits, 1);
61+ inc_counter();
4762 return 0;
4863 }
4964
5065 SEC("kretprobe.multi/" SYS_PREFIX "sys_getpgid")
5166 int bench_trigger_kretprobe_multi(void *ctx)
5267 {
53− __sync_add_and_fetch(&hits, 1);
68+ inc_counter();
5469 return 0;
5570 }
5671
5772 SEC("fentry/" SYS_PREFIX "sys_getpgid")
5873 int bench_trigger_fentry(void *ctx)
5974 {
60− __sync_add_and_fetch(&hits, 1);
75+ inc_counter();
6176 return 0;
6277 }
6378
6479 SEC("fexit/" SYS_PREFIX "sys_getpgid")
6580 int bench_trigger_fexit(void *ctx)
6681 {
67− __sync_add_and_fetch(&hits, 1);
82+ inc_counter();
6883 return 0;
6984 }
7085
7186 SEC("fentry.s/" SYS_PREFIX "sys_getpgid")
7287 int bench_trigger_fentry_sleep(void *ctx)
7388 {
74− __sync_add_and_fetch(&hits, 1);
89+ inc_counter();
7590 return 0;
7691 }
7792
7893 SEC("fmod_ret/" SYS_PREFIX "sys_getpgid")
7994 int bench_trigger_fmodret(void *ctx)
8095 {
81− __sync_add_and_fetch(&hits, 1);
96+ inc_counter();
8297 return -22;
8398 }
8499
85100 SEC("uprobe")
86101 int bench_trigger_uprobe(void *ctx)
87102 {
88− __sync_add_and_fetch(&hits, 1);
103+ inc_counter();
89104 return 0;
90105 }
tools/testing/selftests/bpf/test_cpp.cpp+5−0
@@ -7,6 +7,7 @@ · 6 unmodified lines
77 #include <bpf/bpf.h>
88 #include <bpf/btf.h>
99 #include "test_core_extern.skel.h"
10+#include "struct_ops_module.skel.h"
1011
1112 template <typename T>
1213 class Skeleton {
@@ -98,6 +99,7 @@ int main(int argc, char *argv[]) · 85 unmodified lines
9899 {
99100 struct btf_dump_opts opts = { };
100101 struct test_core_extern *skel;
102+ struct struct_ops_module *skel2;
101103 struct btf *btf;
102104 int fd;
103105
@@ -118,6 +120,9 @@ int main(int argc, char *argv[]) · 14 unmodified lines
118120 skel = test_core_extern__open_and_load();
119121 test_core_extern__destroy(skel);
120122
123+ skel2 = struct_ops_module__open_and_load();
124+ struct_ops_module__destroy(skel2);
125+
121126 fd = bpf_enable_stats(BPF_STATS_RUN_TIME);
122127 if (fd < 0)
123128 std::cout << "FAILED to enable stats: " << fd << std::endl;
tools/testing/selftests/bpf/test_tc_tunnel.sh+12−1
@@ -72,7 +72,6 @@ cleanup() { · 71 unmodified lines
7272 server_listen() {
7373 ip netns exec "${ns2}" nc "${netcat_opt}" -l "${port}" > "${outfile}" &
7474 server_pid=$!
75− sleep 0.2
7675 }
7776
7877 client_connect() {
@@ -93,6 +92,16 @@ verify_data() { · 14 unmodified lines
9392 fi
9493 }
9594
95+wait_for_port() {
96+ for i in $(seq 20); do
97+ if ip netns exec "${ns2}" ss ${2:--4}OHntl | grep -q "$1"; then
98+ return 0
99+ fi
100+ sleep 0.1
101+ done
102+ return 1
103+}
104+
96105 set -e
97106
98107 # no arguments: automated test, run all
@@ -193,6 +202,7 @@ setup · 94 unmodified lines
193202 # basic communication works
194203 echo "test basic connectivity"
195204 server_listen
205+wait_for_port ${port} ${netcat_opt}
196206 client_connect
197207 verify_data
198208
@@ -204,6 +214,7 @@ ip netns exec "${ns1}" tc filter add dev veth1 egress \ · 5 unmodified lines
204214 section "encap_${tuntype}_${mac}"
205215 echo "test bpf encap without decap (expect failure)"
206216 server_listen
217+wait_for_port ${port} ${netcat_opt}
207218 ! client_connect
208219
209220 if [[ "$tuntype" =~ "udp" ]]; then