diff options
| author | Abhishek Dubey <adubey@linux.ibm.com> | 2026-01-24 13:22:21 +0530 |
|---|---|---|
| committer | Madhavan Srinivasan <maddy@linux.ibm.com> | 2026-01-29 09:06:00 +0530 |
| commit | b1c24f089bcf23faa23397dfb5e05f82a8c6cf56 (patch) | |
| tree | 3a9f3624f0ee79efcd7053a96aa07d45f30d189f /arch/powerpc | |
| parent | 88cb7f40344d8b81ecfc4709b5382a956739c272 (diff) | |
powerpc64/bpf: Add arch_bpf_stack_walk() for BPF JIT
This function is used by bpf_throw() to unwind the stack
until frame of exception-boundary during BPF exception
handling.
This function is necessary to support BPF exceptions on
PowerPC.
Signed-off-by: Abhishek Dubey <adubey@linux.ibm.com>
Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com>
Link: https://patch.msgid.link/20260124075223.6033-5-adubey@linux.ibm.com
Diffstat (limited to 'arch/powerpc')
| -rw-r--r-- | arch/powerpc/net/bpf_jit_comp64.c | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/arch/powerpc/net/bpf_jit_comp64.c b/arch/powerpc/net/bpf_jit_comp64.c index e3f677eaa41c..f97907cc5ed4 100644 --- a/arch/powerpc/net/bpf_jit_comp64.c +++ b/arch/powerpc/net/bpf_jit_comp64.c @@ -247,6 +247,47 @@ void bpf_jit_build_epilogue(u32 *image, struct codegen_context *ctx) bpf_jit_build_fentry_stubs(image, ctx); } +/* + * arch_bpf_stack_walk() - BPF stack walker for PowerPC + * + * Based on arch_stack_walk() from stacktrace.c. + * PowerPC uses stack frames rather than stack pointers. See [1] for + * the equivalence between frame pointers and stack pointers. + * Additional reference at [2]. + * TODO: refactor with arch_stack_walk() + * + * [1]: https://lore.kernel.org/all/20200220115141.2707-1-mpe@ellerman.id.au/ + * [2]: https://lore.kernel.org/bpf/20260122211854.5508-5-adubey@linux.ibm.com/ + */ + +void arch_bpf_stack_walk(bool (*consume_fn)(void *, u64, u64, u64), void *cookie) +{ + // callback processing always in current context + unsigned long sp = current_stack_frame(); + + for (;;) { + unsigned long *stack = (unsigned long *) sp; + unsigned long ip; + + if (!validate_sp(sp, current)) + return; + + ip = stack[STACK_FRAME_LR_SAVE]; + if (!ip) + break; + + /* + * consume_fn common code expects stack pointer in third + * argument. There is no sp in ppc64, rather pass frame + * pointer(named sp here). + */ + if (ip && !consume_fn(cookie, ip, sp, sp)) + break; + + sp = stack[0]; + } +} + int bpf_jit_emit_func_call_rel(u32 *image, u32 *fimage, struct codegen_context *ctx, u64 func) { unsigned long func_addr = func ? ppc_function_entry((void *)func) : 0; |
