summaryrefslogtreecommitdiff
path: root/arch/powerpc/net/bpf_jit_comp.c
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2026-03-19 16:15:33 +0100
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2026-03-19 16:15:33 +0100
commit7e2dc8ed7862ac622b5a59953b679de97001dc83 (patch)
treed2d2cf61a22f5a6404000ee007c5e80bc2d9eca9 /arch/powerpc/net/bpf_jit_comp.c
parenta7e8c9cc3a13baf3dcf9734dd55609aa7ff9a1a0 (diff)
parent4a2b0ed2ac7abe9743e1559d212075a0ebac96b3 (diff)
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'arch/powerpc/net/bpf_jit_comp.c')
-rw-r--r--arch/powerpc/net/bpf_jit_comp.c30
1 files changed, 20 insertions, 10 deletions
diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c
index e199976e410a..0d2d2190af9a 100644
--- a/arch/powerpc/net/bpf_jit_comp.c
+++ b/arch/powerpc/net/bpf_jit_comp.c
@@ -437,7 +437,7 @@ void bpf_jit_free(struct bpf_prog *fp)
bool bpf_jit_supports_kfunc_call(void)
{
- return true;
+ return IS_ENABLED(CONFIG_PPC64);
}
bool bpf_jit_supports_arena(void)
@@ -722,9 +722,9 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *rw_im
* retval_off [ return value ]
* [ reg argN ]
* [ ... ]
- * regs_off [ reg_arg1 ] prog ctx context
- * nregs_off [ args count ]
- * ip_off [ traced function ]
+ * regs_off [ reg_arg1 ] prog_ctx
+ * nregs_off [ args count ] ((u64 *)prog_ctx)[-1]
+ * ip_off [ traced function ] ((u64 *)prog_ctx)[-2]
* [ ... ]
* run_ctx_off [ bpf_tramp_run_ctx ]
* [ reg argN ]
@@ -824,7 +824,7 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *rw_im
bpf_trampoline_save_args(image, ctx, func_frame_offset, nr_regs, regs_off);
- /* Save our return address */
+ /* Save our LR/return address */
EMIT(PPC_RAW_MFLR(_R3));
if (IS_ENABLED(CONFIG_PPC_FTRACE_OUT_OF_LINE))
EMIT(PPC_RAW_STL(_R3, _R1, alt_lr_off));
@@ -832,24 +832,34 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *rw_im
EMIT(PPC_RAW_STL(_R3, _R1, bpf_frame_size + PPC_LR_STKOFF));
/*
- * Save ip address of the traced function.
- * We could recover this from LR, but we will need to address for OOL trampoline,
- * and optional GEP area.
+ * Derive IP address of the traced function.
+ * In case of CONFIG_PPC_FTRACE_OUT_OF_LINE or BPF program, LR points to the instruction
+ * after the 'bl' instruction in the OOL stub. Refer to ftrace_init_ool_stub() and
+ * bpf_arch_text_poke() for OOL stub of kernel functions and bpf programs respectively.
+ * Relevant stub sequence:
+ *
+ * bl <tramp>
+ * LR (R3) => mtlr r0
+ * b <func_addr+4>
+ *
+ * Recover kernel function/bpf program address from the unconditional
+ * branch instruction at the end of OOL stub.
*/
if (IS_ENABLED(CONFIG_PPC_FTRACE_OUT_OF_LINE) || flags & BPF_TRAMP_F_IP_ARG) {
EMIT(PPC_RAW_LWZ(_R4, _R3, 4));
EMIT(PPC_RAW_SLWI(_R4, _R4, 6));
EMIT(PPC_RAW_SRAWI(_R4, _R4, 6));
EMIT(PPC_RAW_ADD(_R3, _R3, _R4));
- EMIT(PPC_RAW_ADDI(_R3, _R3, 4));
}
if (flags & BPF_TRAMP_F_IP_ARG)
EMIT(PPC_RAW_STL(_R3, _R1, ip_off));
- if (IS_ENABLED(CONFIG_PPC_FTRACE_OUT_OF_LINE))
+ if (IS_ENABLED(CONFIG_PPC_FTRACE_OUT_OF_LINE)) {
/* Fake our LR for unwind */
+ EMIT(PPC_RAW_ADDI(_R3, _R3, 4));
EMIT(PPC_RAW_STL(_R3, _R1, bpf_frame_size + PPC_LR_STKOFF));
+ }
/* Save function arg count -- see bpf_get_func_arg_cnt() */
EMIT(PPC_RAW_LI(_R3, nr_regs));