Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

bpf: support BPF cookie in raw tracepoint (raw_tp, tp_btf) programs

Wire up BPF cookie for raw tracepoint programs (both BTF and non-BTF
aware variants). This brings them up to part w.r.t. BPF cookie usage
with classic tracepoint and fentry/fexit programs.

Acked-by: Stanislav Fomichev <sdf@google.com>
Acked-by: Eduard Zingerman <eddyz87@gmail.com>
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Message-ID: <20240319233852.1977493-4-andrii@kernel.org>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>

authored by

Andrii Nakryiko and committed by
Alexei Starovoitov
68ca5d4e d4dfc570

+28 -6
+1
include/linux/bpf.h
··· 1610 1610 struct bpf_raw_tp_link { 1611 1611 struct bpf_link link; 1612 1612 struct bpf_raw_event_map *btp; 1613 + u64 cookie; 1613 1614 }; 1614 1615 1615 1616 struct bpf_link_primer {
+4 -2
include/uapi/linux/bpf.h
··· 1662 1662 } query; 1663 1663 1664 1664 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; 1667 1669 } raw_tracepoint; 1668 1670 1669 1671 struct { /* anonymous struct for BPF_BTF_LOAD */
+9 -4
kernel/bpf/syscall.c
··· 3774 3774 #endif /* CONFIG_PERF_EVENTS */ 3775 3775 3776 3776 static int bpf_raw_tp_link_attach(struct bpf_prog *prog, 3777 - const char __user *user_tp_name) 3777 + const char __user *user_tp_name, u64 cookie) 3778 3778 { 3779 3779 struct bpf_link_primer link_primer; 3780 3780 struct bpf_raw_tp_link *link; ··· 3821 3821 bpf_link_init(&link->link, BPF_LINK_TYPE_RAW_TRACEPOINT, 3822 3822 &bpf_raw_tp_link_lops, prog); 3823 3823 link->btp = btp; 3824 + link->cookie = cookie; 3824 3825 3825 3826 err = bpf_link_prime(&link->link, &link_primer); 3826 3827 if (err) { ··· 3842 3841 return err; 3843 3842 } 3844 3843 3845 - #define BPF_RAW_TRACEPOINT_OPEN_LAST_FIELD raw_tracepoint.prog_fd 3844 + #define BPF_RAW_TRACEPOINT_OPEN_LAST_FIELD raw_tracepoint.cookie 3846 3845 3847 3846 static int bpf_raw_tracepoint_open(const union bpf_attr *attr) 3848 3847 { 3849 3848 struct bpf_prog *prog; 3849 + void __user *tp_name; 3850 + __u64 cookie; 3850 3851 int fd; 3851 3852 3852 3853 if (CHECK_ATTR(BPF_RAW_TRACEPOINT_OPEN)) ··· 3858 3855 if (IS_ERR(prog)) 3859 3856 return PTR_ERR(prog); 3860 3857 3861 - fd = bpf_raw_tp_link_attach(prog, u64_to_user_ptr(attr->raw_tracepoint.name)); 3858 + tp_name = u64_to_user_ptr(attr->raw_tracepoint.name); 3859 + cookie = attr->raw_tracepoint.cookie; 3860 + fd = bpf_raw_tp_link_attach(prog, tp_name, cookie); 3862 3861 if (fd < 0) 3863 3862 bpf_prog_put(prog); 3864 3863 return fd; ··· 5198 5193 goto out; 5199 5194 } 5200 5195 if (prog->expected_attach_type == BPF_TRACE_RAW_TP) 5201 - ret = bpf_raw_tp_link_attach(prog, NULL); 5196 + ret = bpf_raw_tp_link_attach(prog, NULL, attr->link_create.tracing.cookie); 5202 5197 else if (prog->expected_attach_type == BPF_TRACE_ITER) 5203 5198 ret = bpf_iter_link_attach(attr, uattr, prog); 5204 5199 else if (prog->expected_attach_type == BPF_LSM_CGROUP)
+13
kernel/trace/bpf_trace.c
··· 2004 2004 return &bpf_get_stackid_proto_raw_tp; 2005 2005 case BPF_FUNC_get_stack: 2006 2006 return &bpf_get_stack_proto_raw_tp; 2007 + case BPF_FUNC_get_attach_cookie: 2008 + return &bpf_get_attach_cookie_proto_tracing; 2007 2009 default: 2008 2010 return bpf_tracing_func_proto(func_id, prog); 2009 2011 } ··· 2068 2066 case BPF_FUNC_get_func_arg_cnt: 2069 2067 return bpf_prog_has_trampoline(prog) ? &bpf_get_func_arg_cnt_proto : NULL; 2070 2068 case BPF_FUNC_get_attach_cookie: 2069 + if (prog->type == BPF_PROG_TYPE_TRACING && 2070 + prog->expected_attach_type == BPF_TRACE_RAW_TP) 2071 + return &bpf_get_attach_cookie_proto_tracing; 2071 2072 return bpf_prog_has_trampoline(prog) ? &bpf_get_attach_cookie_proto_tracing : NULL; 2072 2073 default: 2073 2074 fn = raw_tp_prog_func_proto(func_id, prog); ··· 2374 2369 void __bpf_trace_run(struct bpf_raw_tp_link *link, u64 *args) 2375 2370 { 2376 2371 struct bpf_prog *prog = link->link.prog; 2372 + struct bpf_run_ctx *old_run_ctx; 2373 + struct bpf_trace_run_ctx run_ctx; 2377 2374 2378 2375 cant_sleep(); 2379 2376 if (unlikely(this_cpu_inc_return(*(prog->active)) != 1)) { 2380 2377 bpf_prog_inc_misses_counter(prog); 2381 2378 goto out; 2382 2379 } 2380 + 2381 + run_ctx.bpf_cookie = link->cookie; 2382 + old_run_ctx = bpf_set_run_ctx(&run_ctx.run_ctx); 2383 + 2383 2384 rcu_read_lock(); 2384 2385 (void) bpf_prog_run(prog, args); 2385 2386 rcu_read_unlock(); 2387 + 2388 + bpf_reset_run_ctx(old_run_ctx); 2386 2389 out: 2387 2390 this_cpu_dec(*(prog->active)); 2388 2391 }
+1
tools/include/uapi/linux/bpf.h
··· 1664 1664 struct { /* anonymous struct used by BPF_RAW_TRACEPOINT_OPEN command */ 1665 1665 __u64 name; 1666 1666 __u32 prog_fd; 1667 + __aligned_u64 cookie; 1667 1668 } raw_tracepoint; 1668 1669 1669 1670 struct { /* anonymous struct for BPF_BTF_LOAD */