Re: [PATCH 2/3] LoongArch: BPF: Add fsession support for trampolines

Menglong Dong
2026-03-04T02:12:01Z

On 2026/2/26 14:59 Hengqi Chen <hengqi.chen@gmail.com> write:
> Implement BPF_TRACE_FSESSION support in LoongArch BPF JIT.
> The logic here is almost identical to what has been done in
> RISC-V JIT.
>
> The key changes are:
> - Allocate stack space for function meta and session cookies
> - Introduce invoke_bpf() as a wrapper around invoke_bpf_prog()
> that populates session cookies before each invocation
> - Implement bpf_jit_supports_fsession() callback
>
> Signed-off-by: Hengqi Chen <hengqi.chen@gmail.com>
> ---
> arch/loongarch/net/bpf_jit.c | 78 +++++++++++++++++++++++++++++++-----
> 1 file changed, 67 insertions(+), 11 deletions(-)
>
> diff --git a/arch/loongarch/net/bpf_jit.c b/arch/loongarch/net/bpf_jit.c
> index e3deb0da6a50..16da53f80266 100644
> --- a/arch/loongarch/net/bpf_jit.c
> +++ b/arch/loongarch/net/bpf_jit.c
> @@ -1549,6 +1549,31 @@ static int invoke_bpf_prog(struct jit_ctx *ctx, struct bpf_tramp_link *l,
> return ret;
> }
>

LGTM.

Reviewed-by: Menglong Dong <menglong8.dong@gmail.com>

Some nits maybe you can do when you respin the V2 if you don't mind,
see below.

> +static int invoke_bpf(struct jit_ctx *ctx, struct bpf_tramp_links *tl,
> + int args_off, int retval_off, int run_ctx_off,
> + int func_meta_off, bool save_ret, u64 func_meta,
> + int cookie_off)
> +{
[...]
>
> + if (bpf_fsession_cnt(tlinks)) {
> + /* clear all session cookies' value */
> + for (i = 0; i < cookie_cnt; i++)
> + emit_insn(ctx, std, LOONGARCH_GPR_ZERO, LOONGARCH_GPR_FP, -cookie_off + 8 * i);
> + /* clear return value to make sure fentry always get 0 */
> + emit_insn(ctx, std, LOONGARCH_GPR_ZERO, LOONGARCH_GPR_FP, -retval_off);
> + }
> +
> /* To traced function */
> /* Ftrace jump skips 2 NOP instructions */
> if (is_kernel_text((unsigned long)orig_call) ||
> @@ -1755,9 +1799,10 @@ static int __arch_prepare_bpf_trampoline(struct jit_ctx *ctx, struct bpf_tramp_i
> return ret;
> }
>
> - for (i = 0; i < fentry->nr_links; i++) {
> - ret = invoke_bpf_prog(ctx, fentry->links[i], args_off, retval_off,
> - run_ctx_off, flags & BPF_TRAMP_F_RET_FENTRY_RET);
> + if (fentry->nr_links) {

This checking is unnecessary, as invoke_bpf() will return directly
if !fentry->nr_links.

PS: I was told this when I implement the fsession for s390 this way :)

> + ret = invoke_bpf(ctx, fentry, args_off, retval_off, run_ctx_off,
> + func_meta_off, flags & BPF_TRAMP_F_RET_FENTRY_RET,
> + func_meta, cookie_off);
> if (ret)
> return ret;
> }
> @@ -1791,8 +1836,14 @@ static int __arch_prepare_bpf_trampoline(struct jit_ctx *ctx, struct bpf_tramp_i
> *branches[i] = larch_insn_gen_bne(LOONGARCH_GPR_T1, LOONGARCH_GPR_ZERO, offset);
> }
>
> - for (i = 0; i < fexit->nr_links; i++) {
> - ret = invoke_bpf_prog(ctx, fexit->links[i], args_off, retval_off, run_ctx_off, false);
> + /* set "is_return" flag for fsession */
> + func_meta |= (1ULL << BPF_TRAMP_IS_RETURN_SHIFT);
> + if (bpf_fsession_cnt(tlinks))
> + emit_store_stack_imm64(ctx, LOONGARCH_GPR_T1, -func_meta_off, func_meta);
> +
> + if (fexit->nr_links) {

And this checking.

Thanks!
Menglong Dong

> + ret = invoke_bpf(ctx, fexit, args_off, retval_off, run_ctx_off,
> + func_meta_off, false, func_meta, cookie_off);
> if (ret)
> goto out;
> }
> @@ -2132,3 +2183,8 @@ bool bpf_jit_supports_subprog_tailcalls(void)
> {
> return true;
> }
> +
> +bool bpf_jit_supports_fsession(void)
> +{
> + return true;
> +}
> --
> 2.43.5
>
>
>