All of lore.kernel.org
 help / color / mirror / Atom feed
From: Pu Lehui <pulehui@huawei.com>
To: Kumar Kartikeya Dwivedi <memxor@gmail.com>, <bpf@vger.kernel.org>
Cc: "Björn Töpel" <bjorn@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: Re: [PATCH bpf-next v1 04/14] bpf, riscv: Convert struct_ops arena arguments in the trampoline
Date: Mon, 24 Aug 2026 14:38:28 +0800	[thread overview]
Message-ID: <a89f4cfd-9898-4e0f-a235-ed27199cb552@huawei.com> (raw)
In-Reply-To: <20260821233516.3426127-5-memxor@gmail.com>


On 2026/8/22 7:34, Kumar Kartikeya Dwivedi wrote:
> A struct_ops callback receives native kernel addresses, while its BPF
> program expects an arena pointer argument as a zero-extended 32-bit offset.
> Convert arguments marked with BTF_FMODEL_ARENA_ARG while the trampoline
> copies them into the BPF context.
> 
> bpf_tramp_arena_base() supplies the known base only for the single-program
> indirect trampoline. Materialize its low 32 bits once in t2, subtract it
> from each tagged argument through t1, and zero-extend the result before
> storing it. For a nullable argument, preserve the full native pointer in t1
> and branch over the variable-length subtraction sequence when it is NULL.
> 
> Walk the function model by argument while keeping a separate ABI slot
> index. This keeps the arena flags aligned with the correct native register
> or stack slot when an earlier argument occupies two slots, including the
> case where a 16-byte argument straddles a7 and the stack. Registered and
> stack-passed arena pointers use the same conversion helper.
> 
> bpf_tramp_arena_base() returns zero for tracing trampolines, so their
> emitted argument-save sequence is unchanged. An indirect trampoline cannot
> call the original function, which ensures a converted pointer never escapes
> back into a native callback. Advertise the struct_ops capability
> independently now that the reverse conversion is implemented.
> 
> Cc: Björn Töpel <bjorn@kernel.org>
> Cc: Pu Lehui <pulehui@huawei.com>
> Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
> ---
>   arch/riscv/net/bpf_jit_comp64.c | 93 +++++++++++++++++++++++++++++----
>   1 file changed, 82 insertions(+), 11 deletions(-)
> 
> diff --git a/arch/riscv/net/bpf_jit_comp64.c b/arch/riscv/net/bpf_jit_comp64.c
> index c97d13a3eae4..8db992a285f6 100644
> --- a/arch/riscv/net/bpf_jit_comp64.c
> +++ b/arch/riscv/net/bpf_jit_comp64.c
> @@ -888,20 +888,75 @@ int bpf_arch_text_poke(void *ip, enum bpf_text_poke_type old_t,
>   	return ret;
>   }
>   
> -static void store_args(int nr_arg_slots, int args_off, int stack_args_off,
> +/*
> + * Convert an arena kernel address into the arena pointer form on its way
> + * into the BPF ctx, dst = (u32)(src - kern_vm_start). A nullable arg
> + * preserves NULL, tested on the full 64-bit kernel pointer. The final
> + * zero-extension makes the stored value satisfy the JIT invariant for arena
> + * pointer registers.
> + */
> +static void emit_arena_arg_conv(u8 dst, u8 src, bool nullable, u8 base,
> +				struct rv_jit_context *ctx)
> +{
> +	int branch_off = 0;
> +
> +	if (nullable) {
> +		if (dst != src)
> +			emit_mv(dst, src, ctx);
> +		branch_off = ctx->ninsns;
> +		/* Patched below once the variable-length conversion is emitted. */
> +		emit(rv_nop(), ctx);
> +		src = dst;
> +	}
> +
> +	emit_sub(dst, src, base, ctx);
> +	emit_zextw(dst, dst, ctx);
> +
> +	if (nullable && ctx->insns) {
> +		u32 insn = rv_beq(dst, RV_REG_ZERO, ctx->ninsns - branch_off);
> +
> +		*(u32 *)(ctx->insns + branch_off) = insn;
> +	}
> +}
> +
> +static void store_args(const struct btf_func_model *m, int args_off,
> +		       int stack_args_off, u64 arena_base,
>   		       struct rv_jit_context *ctx)
>   {
> -	int i;
> +	int i, j, slot = 0;
>   
> -	for (i = 0; i < nr_arg_slots; i++) {
> -		if (i < RV_MAX_REG_ARGS) {
> -			emit_sd(RV_REG_FP, -args_off, RV_REG_A0 + i, ctx);
> -		} else {
> -			emit_ld(RV_REG_T1, stack_args_off +
> -				(i - RV_MAX_REG_ARGS) * 8, RV_REG_FP, ctx);
> -			emit_sd(RV_REG_FP, -args_off, RV_REG_T1, ctx);
> +	/* Only the low 32 bits of the base take part in the subtraction. */
> +	if (arena_base)
> +		emit_imm(RV_REG_T2, (s32)(u32)arena_base, ctx);
> +
> +	/*
> +	 * Walk arguments and slots together so a 16-byte argument consumes two
> +	 * ABI locations before the flags for the following argument are used.
> +	 */
> +	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;

small nits. maybe name `arg_slots` will looks better.

> +
> +		for (j = 0; j < slots; j++, slot++) {
> +			u8 src;
> +
> +			if (slot < RV_MAX_REG_ARGS) {
> +				src = RV_REG_A0 + slot;
> +			} else {
> +				emit_ld(RV_REG_T1, stack_args_off +
> +					(slot - RV_MAX_REG_ARGS) * 8, RV_REG_FP, ctx);
> +				src = RV_REG_T1;
> +			}
> +
> +			if (arena_arg) {
> +				emit_arena_arg_conv(RV_REG_T1, src, nullable,
> +						    RV_REG_T2, ctx);
> +				src = RV_REG_T1;
> +			}
> +			emit_sd(RV_REG_FP, -args_off, src, ctx);
> +			args_off -= 8;
>   		}
> -		args_off -= 8;
>   	}
>   }
>   
> @@ -1039,9 +1094,20 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im,
>   	bool is_struct_ops = is_struct_ops_tramp(fentry);
>   	void *orig_call = func_addr;
>   	bool save_ret;
> +	u64 arena_base;
>   	u64 func_meta;
>   	u32 insn;
>   
> +	/*
> +	 * F_INDIRECT is only compatible with F_RET_FENTRY_RET. In particular,
> +	 * an indirect trampoline never calls the original function with the
> +	 * arena arguments converted into their BPF representation.
> +	 */
> +	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);
> +
>   	/* Two types of generated trampoline stack layout:
>   	 *
>   	 * 1. trampoline called from function entry
> @@ -1189,7 +1255,7 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im,
>   	 * SP, which the trampoline keeps as FP. The fentry path pushes the
>   	 * parent frame first, so its incoming stack arguments start at FP + 16.
>   	 */
> -	store_args(nr_arg_slots, args_off, is_struct_ops ? 0 : 16, ctx);
> +	store_args(m, args_off, is_struct_ops ? 0 : 16, arena_base, ctx);
>   
>   	if (bpf_fsession_cnt(tnodes)) {
>   		/* clear all session cookies' value */
> @@ -2172,6 +2238,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_ptr_xchg(void)
>   {
>   	return true;

  parent reply	other threads:[~2026-08-24  6:38 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 [this message]
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 ` [PATCH bpf-next v1 09/14] bpf, loongarch: Convert struct_ops arena arguments in trampolines Kumar Kartikeya Dwivedi
2026-08-21 23:51   ` 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=a89f4cfd-9898-4e0f-a235-ed27199cb552@huawei.com \
    --to=pulehui@huawei.com \
    --cc=andrii@kernel.org \
    --cc=ast@kernel.org \
    --cc=bjorn@kernel.org \
    --cc=bpf@vger.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=memxor@gmail.com \
    /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.