All of lore.kernel.org
 help / color / mirror / Atom feed
From: Kumar Kartikeya Dwivedi <memxor@gmail.com>
To: bpf@vger.kernel.org
Cc: Tiezhu Yang <yangtiezhu@loongson.cn>,
	Huacai Chen <chenhuacai@kernel.org>,
	Alexei Starovoitov <ast@kernel.org>,
	Andrii Nakryiko <andrii@kernel.org>,
	Daniel Borkmann <daniel@iogearbox.net>,
	Eduard Zingerman <eddyz87@gmail.com>,
	Emil Tsalapatis <emil@etsalapatis.com>,
	Ihor Solodrai <ihor.solodrai@linux.dev>,
	kkd@meta.com, kernel-team@meta.com
Subject: [PATCH bpf-next v1 09/14] bpf, loongarch: Convert struct_ops arena arguments in trampolines
Date: Sat, 22 Aug 2026 01:35:03 +0200	[thread overview]
Message-ID: <20260821233516.3426127-10-memxor@gmail.com> (raw)
In-Reply-To: <20260821233516.3426127-1-memxor@gmail.com>

A struct_ops callback receives native kernel addresses from its caller,
but an arena BPF program expects each argument marked with
BTF_FMODEL_ARENA_ARG to be a 32-bit offset from its arena mapping.
LoongArch currently copies the native pointer into the BPF ctx unchanged.

Obtain the mapping base through bpf_tramp_arena_base() and materialize it
in t2 while saving arguments. Copy a marked argument through t1, preserve
a nullable native NULL by branching over the subtraction, and otherwise
subtract the base before clearing the upper 32 bits. Truncating the full
address difference produces the required arena offset.

Walk the function model by argument while maintaining a separate ABI slot
index. This keeps argument flags aligned when an earlier small struct spans
two slots, while preserving the existing register and stack slot layout.
The preceding indirect-trampoline fix supplies the correct stack source
for arguments beyond a0-a7.

bpf_tramp_arena_base() only returns a base for the single-program indirect
trampoline. Assert that such a trampoline cannot call the original
function, which expects unconverted kernel addresses, and advertise the
struct_ops-specific arena argument capability.

Cc: Tiezhu Yang <yangtiezhu@loongson.cn>
Cc: Huacai Chen <chenhuacai@kernel.org>
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
---
 arch/loongarch/net/bpf_jit.c | 73 ++++++++++++++++++++++++++++++------
 1 file changed, 61 insertions(+), 12 deletions(-)

diff --git a/arch/loongarch/net/bpf_jit.c b/arch/loongarch/net/bpf_jit.c
index 33cabaa7353f..5020414bfd9f 100644
--- a/arch/loongarch/net/bpf_jit.c
+++ b/arch/loongarch/net/bpf_jit.c
@@ -288,6 +288,11 @@ bool bpf_jit_supports_arena_kfunc_args(void)
 	return true;
 }
 
+bool bpf_jit_supports_arena_struct_ops_args(void)
+{
+	return true;
+}
+
 bool bpf_jit_supports_far_kfunc_call(void)
 {
 	return true;
@@ -1680,21 +1685,55 @@ int bpf_arch_text_invalidate(void *dst, size_t len)
 	return ret;
 }
 
-static void store_args(struct jit_ctx *ctx, int nr_arg_slots, int args_off, bool is_struct_ops)
+/*
+ * Convert an arena kernel address into a 32-bit arena offset while copying it
+ * into the BPF ctx. A nullable argument preserves a native NULL.
+ */
+static void emit_arena_arg_conv(struct jit_ctx *ctx, int dst, int src, bool nullable, int base)
+{
+	if (dst != src)
+		move_reg(ctx, dst, src);
+	if (nullable)
+		emit_insn(ctx, beq, dst, LOONGARCH_GPR_ZERO, 2);
+	emit_insn(ctx, subd, dst, dst, base);
+	emit_zext_32(ctx, dst, true);
+}
+
+static void store_args(struct jit_ctx *ctx, const struct btf_func_model *m, int args_off,
+		       bool is_struct_ops, u64 arena_base)
 {
 	int stack_args_off = is_struct_ops ? 0 : 16;
-	int i;
+	int i, slot = 0;
+
+	if (arena_base)
+		move_imm(ctx, LOONGARCH_GPR_T2, arena_base, false);
 
-	for (i = 0; i < nr_arg_slots; i++) {
-		if (i < LOONGARCH_MAX_REG_ARGS)
-			emit_insn(ctx, std, LOONGARCH_GPR_A0 + i, LOONGARCH_GPR_FP, -args_off);
-		else {
-			/* Skip the saved T0 and FP slots for a traced function. */
-			emit_insn(ctx, ldd, LOONGARCH_GPR_T1, LOONGARCH_GPR_FP,
-				  stack_args_off + (i - LOONGARCH_MAX_REG_ARGS) * 8);
-			emit_insn(ctx, std, LOONGARCH_GPR_T1, LOONGARCH_GPR_FP, -args_off);
+	for (i = 0; i < m->nr_args; i++) {
+		bool arena_arg = arena_base && (m->arg_flags[i] & BTF_FMODEL_ARENA_ARG);
+		bool nullable = m->arg_flags[i] & BTF_FMODEL_NULLABLE_ARG;
+		int slots = round_up(m->arg_size[i], 8) / 8;
+
+		while (slots-- > 0) {
+			int src;
+
+			if (slot < LOONGARCH_MAX_REG_ARGS) {
+				src = LOONGARCH_GPR_A0 + slot;
+			} else {
+				/* Skip the saved T0 and FP slots for a traced function. */
+				emit_insn(ctx, ldd, LOONGARCH_GPR_T1, LOONGARCH_GPR_FP,
+					  stack_args_off +
+					  (slot - LOONGARCH_MAX_REG_ARGS) * 8);
+				src = LOONGARCH_GPR_T1;
+			}
+			if (arena_arg) {
+				emit_arena_arg_conv(ctx, LOONGARCH_GPR_T1, src, nullable,
+						    LOONGARCH_GPR_T2);
+				src = LOONGARCH_GPR_T1;
+			}
+			emit_insn(ctx, std, src, LOONGARCH_GPR_FP, -args_off);
+			slot++;
+			args_off -= 8;
 		}
-		args_off -= 8;
 	}
 }
 
@@ -1868,6 +1907,7 @@ static int __arch_prepare_bpf_trampoline(struct jit_ctx *ctx, struct bpf_tramp_i
 	struct bpf_tramp_nodes *fexit = &tnodes[BPF_TRAMP_FEXIT];
 	struct bpf_tramp_nodes *fmod_ret = &tnodes[BPF_TRAMP_MODIFY_RETURN];
 	u32 **branches = NULL;
+	u64 arena_base;
 
 	/*
 	 * FP + 8       [ RA to parent func ] return address to parent
@@ -1922,6 +1962,15 @@ static int __arch_prepare_bpf_trampoline(struct jit_ctx *ctx, struct bpf_tramp_i
 	if (flags & (BPF_TRAMP_F_ORIG_STACK | BPF_TRAMP_F_SHARE_IPMODIFY))
 		return -ENOTSUPP;
 
+	/*
+	 * An indirect trampoline never calls the original function. Arena
+	 * conversion relies on this because the original takes kernel addresses.
+	 */
+	WARN_ON_ONCE((flags & BPF_TRAMP_F_INDIRECT) &&
+		     (flags & ~(BPF_TRAMP_F_INDIRECT | BPF_TRAMP_F_RET_FENTRY_RET)));
+
+	arena_base = bpf_tramp_arena_base(m, tnodes, flags);
+
 	/* Room of trampoline frame to store return address and frame pointer */
 	stack_size = 16;
 
@@ -2014,7 +2063,7 @@ static int __arch_prepare_bpf_trampoline(struct jit_ctx *ctx, struct bpf_tramp_i
 	func_meta = nr_arg_slots;
 	emit_store_stack_imm64(ctx, LOONGARCH_GPR_T1, -func_meta_off, func_meta);
 
-	store_args(ctx, nr_arg_slots, args_off, is_struct_ops);
+	store_args(ctx, m, args_off, is_struct_ops, arena_base);
 
 	if (bpf_fsession_cnt(tnodes)) {
 		/* clear all session cookies' value */
-- 
2.53.0


  parent reply	other threads:[~2026-08-21 23:35 UTC|newest]

Thread overview: 44+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-21 23:34 [PATCH bpf-next v1 00/14] Retire KF_ARENA_ARG kfunc flags Kumar Kartikeya Dwivedi
2026-08-21 23:34 ` [PATCH bpf-next v1 01/14] bpf: Split arena kfunc and struct_ops JIT capabilities Kumar Kartikeya Dwivedi
2026-08-22  0:46   ` bot+bpf-ci
2026-08-24 22:28   ` Eduard Zingerman
2026-08-24 22:37     ` Kumar Kartikeya Dwivedi
2026-08-26 19:52     ` Ihor Solodrai
2026-08-21 23:34 ` [PATCH bpf-next v1 02/14] bpf, riscv: Fix stack-passed arguments for indirect trampolines Kumar Kartikeya Dwivedi
2026-08-24  6:21   ` Pu Lehui
2026-08-21 23:34 ` [PATCH bpf-next v1 03/14] bpf, riscv: JIT arena kfunc argument rebasing Kumar Kartikeya Dwivedi
2026-08-24  6:36   ` Pu Lehui
2026-08-21 23:34 ` [PATCH bpf-next v1 04/14] bpf, riscv: Convert struct_ops arena arguments in the trampoline Kumar Kartikeya Dwivedi
2026-08-21 23:44   ` sashiko-bot
2026-08-24  6:38   ` Pu Lehui
2026-08-21 23:34 ` [PATCH bpf-next v1 05/14] bpf, s390: JIT arena kfunc argument rebasing Kumar Kartikeya Dwivedi
2026-08-21 23:35 ` [PATCH bpf-next v1 06/14] bpf, s390: Convert struct_ops arena arguments Kumar Kartikeya Dwivedi
2026-08-22  0:46   ` bot+bpf-ci
2026-08-21 23:35 ` [PATCH bpf-next v1 07/14] bpf, loongarch: Fix stack arguments for indirect trampolines Kumar Kartikeya Dwivedi
2026-08-22  0:46   ` bot+bpf-ci
2026-08-28  4:33   ` Tiezhu Yang
2026-08-28  4:55     ` Kumar Kartikeya Dwivedi
2026-08-28  8:19       ` Tiezhu Yang
2026-08-21 23:35 ` [PATCH bpf-next v1 08/14] bpf, loongarch: JIT arena kfunc argument rebasing Kumar Kartikeya Dwivedi
2026-08-21 23:46   ` sashiko-bot
2026-08-21 23:35 ` Kumar Kartikeya Dwivedi [this message]
2026-08-21 23:51   ` [PATCH bpf-next v1 09/14] bpf, loongarch: Convert struct_ops arena arguments in trampolines sashiko-bot
2026-08-21 23:35 ` [PATCH bpf-next v1 10/14] bpf, powerpc: JIT arena kfunc argument rebasing Kumar Kartikeya Dwivedi
2026-08-22  0:46   ` bot+bpf-ci
2026-08-21 23:35 ` [PATCH bpf-next v1 11/14] bpf: Replace arena kfunc argument flags with suffixes Kumar Kartikeya Dwivedi
2026-08-21 23:58   ` sashiko-bot
2026-08-22  0:46   ` bot+bpf-ci
2026-08-24 22:15   ` Eduard Zingerman
2026-08-24 22:52     ` Kumar Kartikeya Dwivedi
2026-08-26 20:42   ` Ihor Solodrai
2026-08-28  5:07     ` Kumar Kartikeya Dwivedi
2026-08-21 23:35 ` [PATCH bpf-next v1 12/14] resolve_btfids: Drop KF_ARENA_ARG flag support Kumar Kartikeya Dwivedi
2026-08-22  0:46   ` bot+bpf-ci
2026-08-24 22:25   ` Eduard Zingerman
2026-08-24 22:53     ` Kumar Kartikeya Dwivedi
2026-08-26 20:47   ` Ihor Solodrai
2026-08-21 23:35 ` [PATCH bpf-next v1 13/14] selftests/bpf: Exercise arena arguments on every capable JIT Kumar Kartikeya Dwivedi
2026-08-22  0:46   ` bot+bpf-ci
2026-08-26 20:50   ` Ihor Solodrai
2026-08-28  5:00     ` Kumar Kartikeya Dwivedi
2026-08-21 23:35 ` [PATCH bpf-next v1 14/14] docs/bpf: Document split arena argument JIT capabilities Kumar Kartikeya Dwivedi

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=20260821233516.3426127-10-memxor@gmail.com \
    --to=memxor@gmail.com \
    --cc=andrii@kernel.org \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=chenhuacai@kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=eddyz87@gmail.com \
    --cc=emil@etsalapatis.com \
    --cc=ihor.solodrai@linux.dev \
    --cc=kernel-team@meta.com \
    --cc=kkd@meta.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.