All of lore.kernel.org
 help / color / mirror / Atom feed
From: Yonghong Song <yonghong.song@linux.dev>
To: bpf@vger.kernel.org
Cc: Alexei Starovoitov <ast@kernel.org>,
	Andrii Nakryiko <andrii@kernel.org>,
	Daniel Borkmann <daniel@iogearbox.net>,
	Eduard Zingerman <eddyz87@gmail.com>,
	kernel-team@fb.com
Subject: [PATCH bpf-next v3 11/11] docs/bpf: Document arena pointers in a by-value return
Date: Wed, 26 Aug 2026 23:12:11 -0700	[thread overview]
Message-ID: <20260827061211.2520959-1-yonghong.song@linux.dev> (raw)
In-Reply-To: <20260827061114.2514603-1-yonghong.song@linux.dev>

Section 2.9 describes the by-value return contract as scalars only, which
no longer holds: a kfunc and a global subprogram may now return a struct
or union whose members are scalars or arena pointers. Update it.

Note that an arena pointer member is handed back as a scalar like every
other member. That costs nothing: the program has to cast_kern() the value
before it can be used, and the verifier allows that cast on any scalar, so
the member gives the program no reach it did not already have.

Signed-off-by: Yonghong Song <yonghong.song@linux.dev>
---
 Documentation/bpf/kfuncs.rst | 39 +++++++++++++++++++++---------------
 1 file changed, 23 insertions(+), 16 deletions(-)

diff --git a/Documentation/bpf/kfuncs.rst b/Documentation/bpf/kfuncs.rst
index 89dea6b0b024..96bf63d34432 100644
--- a/Documentation/bpf/kfuncs.rst
+++ b/Documentation/bpf/kfuncs.rst
@@ -581,20 +581,27 @@ against the arena. Larger accesses must verify the range explicitly.
 A kfunc may return a scalar, a pointer, or a small struct or union by
 value. A scalar or pointer of up to 8 bytes is returned in R0, as usual.
 
-A struct or union returned by value must be composed only of scalars
-(recursively), where a scalar is an integer or an enum; arrays of scalars are
-allowed as members. Its bytes are handed back to the program as the raw
-contents of R0 (and R2), so a pointer field would be laundered into a scalar
-and escape the verifier's pointer provenance and reference tracking. A struct
-or union with a pointer member is therefore rejected at load time, and so is
-one with a floating-point member, which the ABI may not return in R0:R2 at
-all.
+A struct or union returned by value must be composed only of scalars and arena
+pointers (recursively), where a scalar is an integer or an enum and an arena
+pointer is one carrying the ``btf_type_tag("arena")`` attribute; arrays of
+either are allowed as members. Its bytes are handed back to the program as the
+raw contents of R0 (and R2), so a member of any other pointer type would be
+laundered into a scalar and escape the verifier's pointer provenance and
+reference tracking. A struct or union with such a member is therefore rejected
+at load time, and so is one with a floating-point member, which the ABI may not
+return in R0:R2 at all.
+
+An arena pointer member is handed back as a scalar too, but nothing is lost by
+that. The program must ``cast_kern()`` the value before it can be used, and the
+verifier allows that cast on any scalar, so a laundered arena address gives the
+program no reach it did not already have. The result is confined to the
+program's arena in either case.
 
 A kfunc may also return a value larger than 8 bytes and up to 16 bytes -- a
-scalar-only struct or union, or an ``__int128``. Such a value is returned
-in the register pair R0:R2, matching the convention LLVM uses for the BPF
-target: the first 8 bytes in R0 and the second 8 bytes in R2. A struct or
-union of 8 bytes or less is returned in R0 alone.
+struct or union of scalars and arena pointers, or an ``__int128``. Such a
+value is returned in the register pair R0:R2, matching the convention LLVM
+uses for the BPF target: the first 8 bytes in R0 and the second 8 bytes in R2.
+A struct or union of 8 bytes or less is returned in R0 alone.
 
 ::
 
@@ -620,10 +627,10 @@ used when the program is JITed, since the interpreter propagates only R0 out of
 a subprogram: without a JIT the return value stays in R0 alone, and a caller
 reading R2 is rejected for reading an uninitialized register. A global
 subprogram is verified in isolation, so its by-value struct or union return is
-restricted to scalars just like a kfunc's; a static subprogram is verified
-inline and has no such restriction. The main program is not covered: its return
-value is the program's exit code, read out of R0 alone, so a declared upper
-half is never looked at.
+restricted to scalars and arena pointers just like a kfunc's; a static
+subprogram is verified inline and has no such restriction. The main program is
+not covered: its return value is the program's exit code, read out of R0
+alone, so a declared upper half is never looked at.
 
 A global subprogram must leave a scalar in *every* register of the pair, so
 both halves of the returned value have to be assigned. Leaving the upper half
-- 
2.53.0-Meta


      parent reply	other threads:[~2026-08-27  6:12 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-27  6:11 [PATCH bpf-next v3 00/11] bpf: Allow arena pointers in by-value returns Yonghong Song
2026-08-27  6:11 ` [PATCH bpf-next v3 01/11] bpf: Record each half of a paired return value in verifier diagnostics Yonghong Song
2026-08-27  6:11 ` [PATCH bpf-next v3 02/11] bpf: Drop the recursion depth argument of btf_type_is_scalar_struct() Yonghong Song
2026-08-27  7:04   ` bot+bpf-ci
2026-08-28 17:39     ` Yonghong Song
2026-08-27  6:11 ` [PATCH bpf-next v3 03/11] bpf: Add btf_type_is_arena_ptr() Yonghong Song
2026-08-27  6:11 ` [PATCH bpf-next v3 04/11] bpf: Let the by-value struct walk take the kinds of member it accepts Yonghong Song
2026-08-27  6:11 ` [PATCH bpf-next v3 05/11] bpf: Report which member makes a kfunc return type unsupported Yonghong Song
2026-08-27  7:04   ` bot+bpf-ci
2026-08-28 17:45     ` Yonghong Song
2026-08-27  6:11 ` [PATCH bpf-next v3 06/11] bpf: Allow a global function to return arena pointers by value Yonghong Song
2026-08-27  6:33   ` sashiko-bot
2026-08-28 18:00     ` Yonghong Song
2026-08-27  6:11 ` [PATCH bpf-next v3 07/11] bpf: Allow arena pointers in a by-value kfunc return Yonghong Song
2026-08-27  6:55   ` sashiko-bot
2026-08-28 18:10     ` Yonghong Song
2026-08-27  6:11 ` [PATCH bpf-next v3 08/11] selftests/bpf: Check the member named for an unsupported kfunc return type Yonghong Song
2026-08-27  7:04   ` bot+bpf-ci
2026-08-28 18:20     ` Yonghong Song
2026-08-27  6:12 ` [PATCH bpf-next v3 09/11] selftests/bpf: Test global functions returning arena pointers by value Yonghong Song
2026-08-27  7:04   ` bot+bpf-ci
2026-08-28 18:26     ` Yonghong Song
2026-08-27  6:12 ` [PATCH bpf-next v3 10/11] selftests/bpf: Test kfuncs " Yonghong Song
2026-08-27  7:17   ` bot+bpf-ci
2026-08-28 18:28     ` Yonghong Song
2026-08-27  6:12 ` Yonghong Song [this message]

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=20260827061211.2520959-1-yonghong.song@linux.dev \
    --to=yonghong.song@linux.dev \
    --cc=andrii@kernel.org \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=eddyz87@gmail.com \
    --cc=kernel-team@fb.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.