[PATCH v1] LoongArch: BPF: Implement arch_bpf_stack_walk()
Tiezhu Yang <[email protected]>
| Newsgroups | dev.linux.lists.loongarch,org.kernel.vger.bpf,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
From: George Guo <[email protected]> Implement arch_bpf_stack_walk() on top of the ORC unwinder within the LoongArch BPF JIT backend to provide generic BPF stack walking capabilities. This function is required by advanced BPF features, including timed may_goto timeout tracing and BPF exceptions. It will be invoked in the BPF core subsystem unwinding paths: bpf_prog_find_from_stack(), bpf_stream_stage_dump_stack(), and bpf_throw(). Co-developed-by: Tiezhu Yang <[email protected]> Signed-off-by: Tiezhu Yang <[email protected]> Signed-off-by: George Guo <[email protected]> --- This is an independent feature, so split it from https://lore.kernel.org/loongarch/[email protected]/ Based on the latest loongarch-next, tested on Loongson-3A6000. arch/loongarch/net/bpf_jit.c | 38 ++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/arch/loongarch/net/bpf_jit.c b/arch/loongarch/net/bpf_jit.c index 7533917c6d47..78c20df2a2f3 100644 --- a/arch/loongarch/net/bpf_jit.c +++ b/arch/loongarch/net/bpf_jit.c @@ -2402,6 +2402,44 @@ bool bpf_jit_supports_subprog_tailcalls(void) return true; } +#if defined(CONFIG_UNWINDER_ORC) +#include <asm/unwind.h> + +static noinline void walk_bpf_stackframe(bool (*consume_fn)(void *cookie, u64 ip, u64 sp, u64 bp), + void *cookie, unsigned long fp) +{ + struct pt_regs dummyregs; + struct pt_regs *regs = &dummyregs; + struct unwind_state state; + unsigned long addr; + + regs->regs[3] = (unsigned long)__builtin_frame_address(0); + regs->csr_era = (unsigned long)__builtin_return_address(0); + regs->regs[1] = 0; + regs->regs[22] = fp; + + for (unwind_start(&state, current, regs); + !unwind_done(&state); unwind_next_frame(&state)) { + addr = unwind_get_return_address(&state); + if (!addr || !consume_fn(cookie, (u64)addr, (u64)state.sp, (u64)state.fp)) + break; + } +} + +void arch_bpf_stack_walk(bool (*consume_fn)(void *cookie, u64 ip, u64 sp, u64 bp), void *cookie) +{ + unsigned long fp; + + /* + * Capture the live frame pointer ($r22) at the very front-line before + * any kernel C code clobbers it. This must be a thin wrapper with no + * large stack locals to prevent the compiler from reusing $r22 early. + */ + asm volatile("move %0, $r22" : "=r"(fp)); + walk_bpf_stackframe(consume_fn, cookie, fp); +} +#endif /* CONFIG_UNWINDER_ORC */ + bool bpf_jit_supports_timed_may_goto(void) { return true; -- 2.42.0