On Wed, 2025-05-07 at 10:17 -0700, Kumar Kartikeya Dwivedi wrote: > In preparation of figuring out the closest program that led to the > current point in the kernel, implement a function that scans through the > stack trace and finds out the closest BPF program when walking down the > stack trace. > > Special care needs to be taken to skip over kernel and BPF subprog > frames. We basically scan until we find a BPF main prog frame. The > assumption is that if a program calls into us transitively, we'll > hit it along the way. If not, we end up returning NULL. > > Contextually the function will be used in places where we know the > program may have called into us. > > Due to reliance on arch_bpf_stack_walk(), this function only works on > x86 with CONFIG_UNWINDER_ORC, arm64, and s390. Remove the warning from > arch_bpf_stack_walk as well since we call it outside bpf_throw() > context. > > Signed-off-by: Kumar Kartikeya Dwivedi <memxor@xxxxxxxxx> > --- Acked-by: Eduard Zingerman <eddyz87@xxxxxxxxx> [...] > diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c > index df1bae084abd..dcb665bff22f 100644 > --- a/kernel/bpf/core.c > +++ b/kernel/bpf/core.c > @@ -3244,3 +3244,29 @@ int bpf_prog_get_file_line(struct bpf_prog *prog, unsigned long ip, const char * > *linep += 1; > return BPF_LINE_INFO_LINE_NUM(linfo[idx].line_col); > } > + > +struct walk_stack_ctx { > + struct bpf_prog *prog; > +}; > + > +static bool find_from_stack_cb(void *cookie, u64 ip, u64 sp, u64 bp) > +{ > + struct walk_stack_ctx *ctxp = cookie; > + struct bpf_prog *prog; > + > + if (!is_bpf_text_address(ip)) > + return true; > + prog = bpf_prog_ksym_find(ip); Nit: both bpf_prog_ksym_find() and is_bpf_text_address() use bpf_ksym_find(), so it ends up called twice. > + if (bpf_is_subprog(prog)) > + return true; > + ctxp->prog = prog; > + return false; > +} > + > +struct bpf_prog *bpf_prog_find_from_stack(void) > +{ > + struct walk_stack_ctx ctx = {}; > + > + arch_bpf_stack_walk(find_from_stack_cb, &ctx); > + return ctx.prog; > +}