From: Hengqi Chen <hengqi.chen@gmail.com>
To: ast@kernel.org, daniel@iogearbox.net, andrii@kernel.org,
martin.lau@linux.dev, chenhuacai@kernel.org,
yangtiezhu@loongson.cn, vincent.mc.li@gmail.com,
menglong8.dong@gmail.com
Cc: loongarch@lists.linux.dev, bpf@vger.kernel.org,
Hengqi Chen <hengqi.chen@gmail.com>
Subject: [PATCH 2/3] LoongArch: BPF: Add fsession support for trampolines
Date: Thu, 26 Feb 2026 06:59:50 +0000 [thread overview]
Message-ID: <20260226065952.4082859-3-hengqi.chen@gmail.com> (raw)
In-Reply-To: <20260226065952.4082859-1-hengqi.chen@gmail.com>
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;
}
+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)
+{
+ int i, cur_cookie = (cookie_off - args_off) / 8;
+
+ for (i = 0; i < tl->nr_links; i++) {
+ int err;
+
+ if (bpf_prog_calls_session_cookie(tl->links[i])) {
+ u64 meta = func_meta | ((u64)cur_cookie << BPF_TRAMP_COOKIE_INDEX_SHIFT);
+
+ emit_store_stack_imm64(ctx, LOONGARCH_GPR_T1, -func_meta_off, meta);
+ cur_cookie--;
+ }
+ err = invoke_bpf_prog(ctx, tl->links[i], args_off, retval_off,
+ run_ctx_off, save_ret);
+ if (err)
+ return err;
+ }
+
+ return 0;
+}
+
static void invoke_bpf_mod_ret(struct jit_ctx *ctx, struct bpf_tramp_links *tl,
int args_off, int retval_off, int run_ctx_off, u32 **branches)
{
@@ -1610,13 +1635,15 @@ static int __arch_prepare_bpf_trampoline(struct jit_ctx *ctx, struct bpf_tramp_i
{
int i, ret, save_ret;
int stack_size, nargs;
- int retval_off, args_off, nargs_off, ip_off, run_ctx_off, sreg_off, tcc_ptr_off;
+ int retval_off, args_off, func_meta_off, ip_off, run_ctx_off, sreg_off, tcc_ptr_off;
+ int cookie_off, cookie_cnt;
bool is_struct_ops = flags & BPF_TRAMP_F_INDIRECT;
void *orig_call = func_addr;
struct bpf_tramp_links *fentry = &tlinks[BPF_TRAMP_FENTRY];
struct bpf_tramp_links *fexit = &tlinks[BPF_TRAMP_FEXIT];
struct bpf_tramp_links *fmod_ret = &tlinks[BPF_TRAMP_MODIFY_RETURN];
u32 **branches = NULL;
+ u64 func_meta;
/*
* FP + 8 [ RA to parent func ] return address to parent
@@ -1634,10 +1661,14 @@ static int __arch_prepare_bpf_trampoline(struct jit_ctx *ctx, struct bpf_tramp_i
* [ ... ]
* FP - args_off [ arg1 ]
*
- * FP - nargs_off [ regs count ]
+ * FP - func_meta_off [ regs count, etc ]
*
* FP - ip_off [ traced func ] BPF_TRAMP_F_IP_ARG
*
+ * [ stack cookie N ]
+ * [ ... ]
+ * FP - cookie_off [ stack cookie 1 ]
+ *
* FP - run_ctx_off [ bpf_tramp_run_ctx ]
*
* FP - sreg_off [ callee saved reg ]
@@ -1671,9 +1702,9 @@ static int __arch_prepare_bpf_trampoline(struct jit_ctx *ctx, struct bpf_tramp_i
stack_size += nargs * 8;
args_off = stack_size;
- /* Room of trampoline frame to store args number */
+ /* function metadata, such as regs count */
stack_size += 8;
- nargs_off = stack_size;
+ func_meta_off = stack_size;
/* Room of trampoline frame to store ip address */
if (flags & BPF_TRAMP_F_IP_ARG) {
@@ -1681,6 +1712,11 @@ static int __arch_prepare_bpf_trampoline(struct jit_ctx *ctx, struct bpf_tramp_i
ip_off = stack_size;
}
+ cookie_cnt = bpf_fsession_cookie_cnt(tlinks);
+ /* room for session cookies */
+ stack_size += cookie_cnt * 8;
+ cookie_off = stack_size;
+
/* Room of trampoline frame to store struct bpf_tramp_run_ctx */
stack_size += round_up(sizeof(struct bpf_tramp_run_ctx), 8);
run_ctx_off = stack_size;
@@ -1734,11 +1770,19 @@ static int __arch_prepare_bpf_trampoline(struct jit_ctx *ctx, struct bpf_tramp_i
if (flags & BPF_TRAMP_F_IP_ARG)
emit_store_stack_imm64(ctx, LOONGARCH_GPR_T1, -ip_off, (u64)func_addr);
- /* store nargs number */
- emit_store_stack_imm64(ctx, LOONGARCH_GPR_T1, -nargs_off, nargs);
+ func_meta = nargs;
+ emit_store_stack_imm64(ctx, LOONGARCH_GPR_T1, -func_meta_off, func_meta);
store_args(ctx, nargs, args_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) {
+ 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) {
+ 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
next prev parent reply other threads:[~2026-02-26 7:00 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-02-26 6:59 [PATCH 0/3] bpf: fsession support for LoongArch Hengqi Chen
2026-02-26 6:59 ` [PATCH 1/3] LoongArch: BPF: Introduce emit_store_stack_imm64() helper Hengqi Chen
2026-03-04 2:04 ` Menglong Dong
2026-02-26 6:59 ` Hengqi Chen [this message]
2026-03-04 2:11 ` [PATCH 2/3] LoongArch: BPF: Add fsession support for trampolines Menglong Dong
2026-02-26 6:59 ` [PATCH bpf-next 3/3] bpf/selftests: Enable fsession tests for LoongArch Hengqi Chen
2026-02-27 1:59 ` Vincent Li
2026-03-04 1:43 ` Menglong Dong
2026-03-04 2:51 ` [PATCH 0/3] bpf: fsession support " Menglong Dong
2026-04-22 8:18 ` Huacai Chen
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260226065952.4082859-3-hengqi.chen@gmail.com \
--to=hengqi.chen@gmail.com \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=chenhuacai@kernel.org \
--cc=daniel@iogearbox.net \
--cc=loongarch@lists.linux.dev \
--cc=martin.lau@linux.dev \
--cc=menglong8.dong@gmail.com \
--cc=vincent.mc.li@gmail.com \
--cc=yangtiezhu@loongson.cn \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.