From: "Kumar Kartikeya Dwivedi" <memxor@gmail.com>
To: "Amery Hung" <ameryhung@gmail.com>
Cc: <bpf@vger.kernel.org>, "Tejun Heo" <tj@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>, <kkd@meta.com>,
<kernel-team@meta.com>
Subject: Re: [PATCH bpf-next v3 1/9] bpf: Support __arena and __arena_nullable kfunc argument suffixes
Date: Wed, 05 Aug 2026 17:55:32 +0200 [thread overview]
Message-ID: <DKH4S76GIO67.18GLTGT6YDR6L@gmail.com> (raw)
In-Reply-To: <CAMB2axPCF12OGokrt3R5d9f8Y9JxvGfF7LaNRHW_7bOp6aLnuA@mail.gmail.com>
On Tue Aug 4, 2026 at 7:42 PM CEST, Amery Hung wrote:
> On Mon, Aug 3, 2026 at 6:12 AM Kumar Kartikeya Dwivedi <memxor@gmail.com> wrote:
>>
>> From: Tejun Heo <tj@kernel.org>
>>
>> Passing an arena pointer to a kfunc takes two steps today. There is no
>> arena pointer argument type, so the pointer crosses the boundary as a
>> bare scalar, and the kfunc then offsets it by the arena base and casts
>> it before it can touch the memory. Every such kfunc open-codes the same
>> translation.
>>
>> Add the __arena and __arena_nullable argument suffixes to make this more
>> convenient. The kfunc declares the parameter by its real pointer type
>> and dereferences it directly, with the JIT rebasing the value at the
>> call site, rN = kern_vm_start + (u32)rN. No bounds check is needed: the
>> u32 offset stays within the guard-padded arena kernel mapping, and a
>> fault on an unpopulated page recovers through the per-arena scratch
>> page. A suffixed argument accepts a PTR_TO_ARENA or scalar register,
>> matching global subprog arena arguments.
>>
>> __arena rebases unconditionally, so the kfunc never sees NULL and a
>> value with zero in the low 32 bits arrives as the arena base.
>> __arena_nullable preserves NULL for optional arguments by skipping the
>> rebase when the truncated value, arena offset 0, is zero. Keeping the
>> plain form NULL-free saves the NULL test on every call.
>>
>> This patch adds the verifier side: the suffixes are recognized in
>> check_kfunc_args() and distilled into argument flags in the function
>> model stored in the kfunc descriptor. JITs retrieve the model while
>> emitting the call, avoiding per-call state in insn_aux_data.
>>
>> JITs declare support with bpf_jit_supports_arena_args() and verification
>> fails with -ENOTSUPP elsewhere.
>>
>> Signed-off-by: Tejun Heo <tj@kernel.org>
>> Co-developed-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
>> Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
>> ---
>> Documentation/bpf/kfuncs.rst | 29 ++++++++++++++++++++++++++
>> include/linux/bpf.h | 6 ++++++
>> include/linux/filter.h | 1 +
>> kernel/bpf/btf.c | 18 +++++++++++++++-
>> kernel/bpf/core.c | 5 +++++
>> kernel/bpf/verifier.c | 40 +++++++++++++++++++++++++++++++++++-
>> 6 files changed, 97 insertions(+), 2 deletions(-)
>>
>> diff --git a/Documentation/bpf/kfuncs.rst b/Documentation/bpf/kfuncs.rst
>> index cbde86d082cc..8e84484636c5 100644
>> --- a/Documentation/bpf/kfuncs.rst
>> +++ b/Documentation/bpf/kfuncs.rst
>> @@ -278,6 +278,33 @@ An example is given below::
>> ...
>> }
>>
>> +2.3.8 __arena and __arena_nullable Annotations
>> +----------------------------------------------
>> +
>> +Both annotations indicate that the pointer argument points into the
>> +calling program's arena. The JIT rebases the value at the call site so
>> +the kfunc receives a directly dereferenceable kernel address, subject to
>> +the access rules described in :ref:`BPF_kfunc_arena_access` (at most
>> +``GUARD_SZ / 2``, 32 KiB, past the pointer in a single unchecked access).
>> +
>> +With ``__arena`` the rebase is unconditional and the argument is never
>> +NULL: a value whose lower 32 bits are zero arrives as the arena base
>> +address (arena offset 0). The kfunc must not check the argument for NULL.
>> +With ``__arena_nullable`` such a value arrives as NULL instead and the
>> +kfunc must check before dereferencing.
>> +
>> +An example is given below::
>> +
>> + __bpf_kfunc int bpf_process_item(struct item *item__arena)
>> + {
>> + ...
>> + }
>> +
>> +Calling such a kfunc requires the program to use an arena map and a JIT with
>> +arena argument support (currently x86-64); verification fails otherwise. The
>> +program can pass any value without compromising the kernel. A value that does
>> +not point into the arena is a program bug.
>> +
>> .. _BPF_kfunc_nodef:
>>
>> 2.4 Using an existing kernel function
>> @@ -515,6 +542,8 @@ In order to accommodate such requirements, the verifier will enforce strict
>> PTR_TO_BTF_ID type matching if two types have the exact same name, with one
>> being suffixed with ``___init``.
>>
>> +.. _BPF_kfunc_arena_access:
>> +
>> 2.8 Accessing arena memory through kfunc arguments
>> --------------------------------------------------
>>
>> diff --git a/include/linux/bpf.h b/include/linux/bpf.h
>> index 356884587ae1..6da8a6be930c 100644
>> --- a/include/linux/bpf.h
>> +++ b/include/linux/bpf.h
>> @@ -1213,6 +1213,12 @@ struct bpf_prog_offload {
>> /* The argument is signed. */
>> #define BTF_FMODEL_SIGNED_ARG BIT(1)
>>
>> +/* The argument is an arena pointer. */
>> +#define BTF_FMODEL_ARENA_ARG BIT(2)
>> +
>> +/* The argument is nullable. */
>> +#define BTF_FMODEL_NULLABLE_ARG BIT(3)
>> +
>> struct btf_func_model {
>> u8 ret_size;
>> u8 ret_flags;
>> diff --git a/include/linux/filter.h b/include/linux/filter.h
>> index 32d5297c557e..36ce3403fe59 100644
>> --- a/include/linux/filter.h
>> +++ b/include/linux/filter.h
>> @@ -1183,6 +1183,7 @@ bool bpf_jit_supports_subprog_tailcalls(void);
>> bool bpf_jit_supports_percpu_insn(void);
>> bool bpf_jit_supports_kfunc_call(void);
>> bool bpf_jit_supports_stack_args(void);
>> +bool bpf_jit_supports_arena_args(void);
>> bool bpf_jit_supports_far_kfunc_call(void);
>> bool bpf_jit_supports_exceptions(void);
>> bool bpf_jit_supports_ptr_xchg(void);
>> diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
>> index 5e8ac45ce56a..bf86df91a70b 100644
>> --- a/kernel/bpf/btf.c
>> +++ b/kernel/bpf/btf.c
>> @@ -7541,6 +7541,22 @@ static u8 __get_type_fmodel_flags(const struct btf_type *t)
>> return flags;
>> }
>>
>> +static u8 __get_arg_fmodel_flags(const struct btf *btf,
>> + const struct btf_param *arg,
>> + const struct btf_type *t)
>> +{
>> + u8 flags = __get_type_fmodel_flags(t);
>> +
>> + if (btf_param_match_suffix(btf, arg, "__arena") ||
>> + btf_param_match_suffix(btf, arg, "__arena_nullable"))
>> + flags |= BTF_FMODEL_ARENA_ARG;
>> + if (btf_param_match_suffix(btf, arg, "__nullable") ||
>> + btf_param_match_suffix(btf, arg, "__arena_nullable"))
>> + flags |= BTF_FMODEL_NULLABLE_ARG;
>> +
>> + return flags;
>> +}
>> +
>> int btf_distill_func_proto(struct bpf_verifier_log *log,
>> struct btf *btf,
>> const struct btf_type *func,
>> @@ -7606,7 +7622,7 @@ int btf_distill_func_proto(struct bpf_verifier_log *log,
>> return -EINVAL;
>> }
>> m->arg_size[i] = ret;
>> - m->arg_flags[i] = __get_type_fmodel_flags(t);
>> + m->arg_flags[i] = __get_arg_fmodel_flags(btf, &args[i], t);
>> }
>> m->nr_args = nargs;
>> return 0;
>> diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c
>> index e2076667b245..a3e1fae32eac 100644
>> --- a/kernel/bpf/core.c
>> +++ b/kernel/bpf/core.c
>> @@ -3308,6 +3308,11 @@ bool __weak bpf_jit_supports_stack_args(void)
>> return false;
>> }
>>
>> +bool __weak bpf_jit_supports_arena_args(void)
>> +{
>> + return false;
>> +}
>> +
>> bool __weak bpf_jit_supports_far_kfunc_call(void)
>> {
>> return false;
>> diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
>> index b274004fccfd..4c50237f49f1 100644
>> --- a/kernel/bpf/verifier.c
>> +++ b/kernel/bpf/verifier.c
>> @@ -10907,6 +10907,16 @@ static bool is_kfunc_arg_irq_flag(const struct btf *btf, const struct btf_param
>> return btf_param_match_suffix(btf, arg, "__irq_flag");
>> }
>>
>> +static bool is_kfunc_arg_arena(const struct btf *btf, const struct btf_param *arg)
>> +{
>> + return btf_param_match_suffix(btf, arg, "__arena");
>> +}
>> +
>> +static bool is_kfunc_arg_arena_nullable(const struct btf *btf, const struct btf_param *arg)
>> +{
>> + return btf_param_match_suffix(btf, arg, "__arena_nullable");
>> +}
>> +
>
> From the verifier's point of view, __arena and __arena_nullable all
> maps to KF_ARG_PTR_TO_ARENA and require the same check so maybe
> is_kfunc_arg_arena() alone with two suffix matching is good enough,
> but it also doesn't hurt to have two separated functions.
>
Missed in previous reply; I consolidated both into the same is_kfunc_arg_arena()
predicate.
> [...]
next prev parent reply other threads:[~2026-08-05 15:55 UTC|newest]
Thread overview: 37+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-03 12:51 [PATCH bpf-next v3 0/9] Add arena argument support to kfuncs and struct_ops Kumar Kartikeya Dwivedi
2026-08-03 12:51 ` [PATCH bpf-next v3 1/9] bpf: Support __arena and __arena_nullable kfunc argument suffixes Kumar Kartikeya Dwivedi
2026-08-03 13:19 ` sashiko-bot
2026-08-04 17:42 ` Amery Hung
2026-08-05 15:53 ` Kumar Kartikeya Dwivedi
2026-08-05 17:07 ` Amery Hung
2026-08-05 17:16 ` Kumar Kartikeya Dwivedi
2026-08-05 15:55 ` Kumar Kartikeya Dwivedi [this message]
2026-08-03 12:51 ` [PATCH bpf-next v3 2/9] bpf: Support __arena and __arena_nullable on struct_ops arguments Kumar Kartikeya Dwivedi
2026-08-03 14:19 ` sashiko-bot
2026-08-04 23:55 ` Eduard Zingerman
2026-08-05 5:14 ` Eduard Zingerman
2026-08-05 17:31 ` Amery Hung
2026-08-05 17:36 ` Kumar Kartikeya Dwivedi
2026-08-03 12:51 ` [PATCH bpf-next v3 3/9] bpf, x86: JIT __arena kfunc argument rebasing Kumar Kartikeya Dwivedi
2026-08-05 0:40 ` Eduard Zingerman
2026-08-03 12:51 ` [PATCH bpf-next v3 4/9] bpf, x86: Convert struct_ops arena arguments in the trampoline Kumar Kartikeya Dwivedi
2026-08-03 12:51 ` [PATCH bpf-next v3 5/9] selftests/bpf: Add kfunc __arena and __arena_nullable argument tests Kumar Kartikeya Dwivedi
2026-08-03 13:35 ` sashiko-bot
2026-08-04 20:01 ` Eduard Zingerman
2026-08-04 20:14 ` Kumar Kartikeya Dwivedi
2026-08-04 20:24 ` Eduard Zingerman
2026-08-04 20:26 ` Eduard Zingerman
2026-08-04 20:28 ` Kumar Kartikeya Dwivedi
2026-08-04 20:33 ` Eduard Zingerman
2026-08-04 20:36 ` Eduard Zingerman
2026-08-03 12:51 ` [PATCH bpf-next v3 6/9] selftests/bpf: Add JIT-sequence tests for __arena kfunc arguments Kumar Kartikeya Dwivedi
2026-08-03 13:35 ` sashiko-bot
2026-08-05 5:43 ` Eduard Zingerman
2026-08-03 12:51 ` [PATCH bpf-next v3 7/9] selftests/bpf: Add struct_ops __arena and __arena_nullable argument tests Kumar Kartikeya Dwivedi
2026-08-03 13:39 ` sashiko-bot
2026-08-05 6:52 ` Eduard Zingerman
2026-08-03 12:51 ` [PATCH bpf-next v3 8/9] bpf, x86: Fix stack-passed arguments for indirect trampolines Kumar Kartikeya Dwivedi
2026-08-03 13:42 ` sashiko-bot
2026-08-05 8:00 ` Eduard Zingerman
2026-08-03 12:51 ` [PATCH bpf-next v3 9/9] selftests/bpf: Test stack-passed struct_ops arena arguments Kumar Kartikeya Dwivedi
2026-08-05 8:00 ` Eduard Zingerman
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=DKH4S76GIO67.18GLTGT6YDR6L@gmail.com \
--to=memxor@gmail.com \
--cc=ameryhung@gmail.com \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=eddyz87@gmail.com \
--cc=emil@etsalapatis.com \
--cc=kernel-team@meta.com \
--cc=kkd@meta.com \
--cc=tj@kernel.org \
/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.