projects/linux·commit 90b83efa

Merge tag 'bpf-next-6.16' of git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next

90b83efa · Linus Torvalds <[email protected]> · 2025-05-28 15:52:42 -07:00

Pull bpf updates from Alexei Starovoitov:

 - Fix and improve BTF deduplication of identical BTF types (Alan
   Maguire and Andrii Nakryiko)

 - Support up to 12 arguments in BPF trampoline on arm64 (Xu Kuohai and
   Alexis Lothoré)

 - Support load-acquire and store-release instructions in BPF JIT on
   riscv64 (Andrea Parri)

 - Fix uninitialized values in BPF_{CORE,PROBE}_READ macros (Anton
   Protopopov)

 - Streamline allowed helpers across program types (Feng Yang)

 - Support atomic update for hashtab of BPF maps (Hou Tao)

 - Implement json output for BPF helpers (Ihor Solodrai)

 - Several s390 JIT fixes (Ilya Leoshkevich)

 - Various sockmap fixes (Jiayuan Chen)

 - Support mmap of vmlinux BTF data (Lorenz Bauer)

 - Support BPF rbtree traversal and list peeking (Martin KaFai Lau)

 - Tests for sockmap/sockhash redirection (Michal Luczaj)

 - Introduce kfuncs for memory reads into dynptrs (Mykyta Yatsenko)

 - Add support for dma-buf iterators in BPF (T.J. Mercier)

 - The verifier support for __bpf_trap() (Yonghong Song)

* tag 'bpf-next-6.16' of git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next: (135 commits)
  bpf, arm64: Remove unused-but-set function and variable.
  selftests/bpf: Add tests with stack ptr register in conditional jmp
  bpf: Do not include stack ptr register in precision backtracking bookkeeping
  selftests/bpf: enable many-args tests for arm64
  bpf, arm64: Support up to 12 function arguments
  bpf: Check rcu_read_lock_trace_held() in bpf_map_lookup_percpu_elem()
  bpf: Avoid __bpf_prog_ret0_warn when jit fails
  bpftool: Add support for custom BTF path in prog load/loadall
  selftests/bpf: Add unit tests with __bpf_trap() kfunc
  bpf: Warn with __bpf_trap() kfunc maybe due to uninitialized variable
  bpf: Remove special_kfunc_set from verifier
  selftests/bpf: Add test for open coded dmabuf_iter
  selftests/bpf: Add test for dmabuf_iter
  bpf: Add open coded dmabuf iterator
  bpf: Add dmabuf iterator
  dma-buf: Rename debugfs symbols
  bpf: Fix error return value in bpf_copy_from_user_dynptr
  libbpf: Use mmap to parse vmlinux BTF from sysfs
  selftests: bpf: Add a test for mmapable vmlinux BTF
  btf: Allow mmap of vmlinux btf
  ...
Commit
90b83efa6701656e02c86e7df2cb1765ea602d07
Parents
1b98f357 · c5cebb24

Merge commit. Changes below are compared with the first parent: 1b98f357.

Changes

108 files changed · +5801 −1713

FileStatusAddDelContent
Documentation/bpf/bpf_iterators.rstmodified+112−5View file
Documentation/bpf/kfuncs.rstmodified+17−0View file
arch/arm64/net/bpf_jit_comp.cmodified+171−71View file
arch/riscv/net/bpf_jit.hmodified+15−0View file
arch/riscv/net/bpf_jit_comp64.cmodified+227−105View file
arch/riscv/net/bpf_jit_core.cmodified+1−2View file
arch/s390/include/asm/nospec-branch.hmodified+0−4View file
arch/s390/net/bpf_jit_comp.cmodified+66−72View file
drivers/dma-buf/dma-buf.cmodified+78−20View file
include/asm-generic/vmlinux.lds.hmodified+2−1View file
include/linux/bpf-cgroup.hmodified+0−8View file
include/linux/bpf.hmodified+20−0View file
include/linux/bpf_verifier.hmodified+20−4View file
include/linux/dma-buf.hmodified+2−2View file
include/uapi/linux/bpf.hmodified+12−7View file
kernel/bpf/Makefilemodified+3−0View file
kernel/bpf/bpf_struct_ops.cmodified+1−1View file
kernel/bpf/btf.cmodified+20−25View file
kernel/bpf/cgroup.cmodified+0−32View file
kernel/bpf/core.cmodified+17−12View file
kernel/bpf/dmabuf_iter.cadded+150−0View file
kernel/bpf/hashtab.cmodified+72−76View file
kernel/bpf/helpers.cmodified+118−15View file
kernel/bpf/syscall.cmodified+6−4View file
kernel/bpf/sysfs_btf.cmodified+32−0View file
kernel/bpf/verifier.cmodified+334−302View file
kernel/sched/ext.cmodified+1−14View file
kernel/trace/bpf_trace.cmodified+211−110View file
kernel/trace/trace_uprobe.cmodified+1−1View file
net/bpf/test_run.cmodified+7−1View file
net/core/filter.cmodified+0−14View file
net/core/skmsg.cmodified+35−21View file
net/tls/tls_sw.cmodified+13−2View file
scripts/Makefile.btfmodified+2−0View file
scripts/bpf_doc.pymodified+99−20View file
tools/bpf/bpftool/Documentation/bpftool-prog.rstmodified+8−2View file
tools/bpf/bpftool/bash-completion/bpftoolmodified+2−2View file
tools/bpf/bpftool/cgroup.cmodified+7−7View file
tools/bpf/bpftool/link.cmodified+3−0View file
tools/bpf/bpftool/prog.cmodified+11−1View file
tools/include/uapi/linux/bpf.hmodified+12−7View file
tools/lib/bpf/bpf_core_read.hmodified+6−0View file
tools/lib/bpf/bpf_helpers.hmodified+8−0View file
tools/lib/bpf/btf.cmodified+171−55View file
tools/lib/bpf/libbpf.cmodified+48−39View file
tools/lib/bpf/libbpf.hmodified+6−0View file
tools/lib/bpf/libbpf.mapmodified+4−0View file
tools/lib/bpf/libbpf_internal.hmodified+9−0View file
tools/lib/bpf/linker.cmodified+3−3View file
tools/lib/bpf/nlattr.cmodified+7−8View file
tools/testing/selftests/bpf/DENYLISTmodified+1−0View file
tools/testing/selftests/bpf/DENYLIST.aarch64modified+0−2View file
tools/testing/selftests/bpf/Makefilemodified+11−5View file
tools/testing/selftests/bpf/bench.cmodified+4−0View file
tools/testing/selftests/bpf/benchs/bench_htab_mem.cmodified+1−2View file
tools/testing/selftests/bpf/benchs/bench_sockmap.cadded+598−0View file
tools/testing/selftests/bpf/bpf_experimental.hmodified+5−0View file
tools/testing/selftests/bpf/configmodified+3−0View file
tools/testing/selftests/bpf/prog_tests/arena_spin_lock.cmodified+8−6View file
tools/testing/selftests/bpf/prog_tests/attach_probe.cmodified+84−0View file
tools/testing/selftests/bpf/prog_tests/bpf_nf.cmodified+6−0View file
tools/testing/selftests/bpf/prog_tests/btf_dedup_split.cmodified+101−0View file
tools/testing/selftests/bpf/prog_tests/btf_split.cmodified+52−6View file
tools/testing/selftests/bpf/prog_tests/btf_sysfs.cadded+81−0View file
tools/testing/selftests/bpf/prog_tests/dmabuf_iter.cadded+285−0View file
tools/testing/selftests/bpf/prog_tests/dynptr.cmodified+13−0View file
tools/testing/selftests/bpf/prog_tests/fd_htab_lookup.cadded+192−0View file
tools/testing/selftests/bpf/prog_tests/fill_link_info.cmodified+16−2View file
tools/testing/selftests/bpf/prog_tests/kmem_cache_iter.cmodified+1−1View file
tools/testing/selftests/bpf/prog_tests/linked_list.cmodified+6−0View file
tools/testing/selftests/bpf/prog_tests/rbtree.cmodified+6−0View file
tools/testing/selftests/bpf/prog_tests/sk_assign.cmodified+3−1View file
tools/testing/selftests/bpf/prog_tests/socket_helpers.hmodified+79−5View file
tools/testing/selftests/bpf/prog_tests/sockmap_helpers.hmodified+11−14View file
tools/testing/selftests/bpf/prog_tests/sockmap_ktls.cmodified+239−58View file
tools/testing/selftests/bpf/prog_tests/sockmap_listen.cmodified+0−457View file
tools/testing/selftests/bpf/prog_tests/sockmap_redir.cadded+465−0View file
tools/testing/selftests/bpf/prog_tests/tc_redirect.cmodified+6−5View file
tools/testing/selftests/bpf/prog_tests/test_btf_ext.cadded+64−0View file
tools/testing/selftests/bpf/prog_tests/test_veristat.cmodified+5−0View file
tools/testing/selftests/bpf/prog_tests/verifier.cmodified+2−0View file
tools/testing/selftests/bpf/prog_tests/xdp_metadata.cmodified+21−1View file
tools/testing/selftests/bpf/progs/bench_sockmap_prog.cadded+65−0View file
tools/testing/selftests/bpf/bpf_arena_spin_lock.h → tools/testing/selftests/bpf/progs/bpf_arena_spin_lock.hrenamed+12−3View file
tools/testing/selftests/bpf/progs/bpf_misc.hmodified+3−2View file
tools/testing/selftests/bpf/progs/dmabuf_iter.cadded+101−0View file
tools/testing/selftests/bpf/progs/dynptr_success.cmodified+230−0View file
tools/testing/selftests/bpf/progs/fd_htab_lookup.cadded+25−0View file
tools/testing/selftests/bpf/progs/iters.cmodified+0−2View file
tools/testing/selftests/bpf/progs/linked_list_peek.cadded+113−0View file
tools/testing/selftests/bpf/progs/prepare.cmodified+0−1View file
tools/testing/selftests/bpf/progs/rbtree_fail.cmodified+15−14View file
tools/testing/selftests/bpf/progs/rbtree_search.cadded+206−0View file
tools/testing/selftests/bpf/progs/set_global_vars.cmodified+41−0View file
tools/testing/selftests/bpf/progs/test_btf_ext.cadded+22−0View file
tools/testing/selftests/bpf/progs/test_sockmap_ktls.cadded+36−0View file
tools/testing/selftests/bpf/progs/test_sockmap_redir.cadded+68−0View file
tools/testing/selftests/bpf/progs/test_tcp_custom_syncookie.cmodified+3−1View file
tools/testing/selftests/bpf/progs/verifier_bpf_trap.cadded+71−0View file
tools/testing/selftests/bpf/progs/verifier_btf_ctx_access.cmodified+12−0View file
tools/testing/selftests/bpf/progs/verifier_load_acquire.cmodified+32−16View file
tools/testing/selftests/bpf/progs/verifier_precision.cmodified+55−3View file
tools/testing/selftests/bpf/progs/verifier_store_release.cmodified+27−12View file
tools/testing/selftests/bpf/progs/xdp_metadata.cmodified+13−0View file
tools/testing/selftests/bpf/test_kmods/bpf_testmod.cmodified+6−2View file
tools/testing/selftests/bpf/test_loader.cmodified+8−6View file
tools/testing/selftests/bpf/test_verifier.cmodified+4−4View file
tools/testing/selftests/bpf/veristat.cmodified+94−7View file

Only the first 600 diff lines are shown. Download the complete patch.

Documentation/bpf/bpf_iterators.rst

View file
diff --git a/Documentation/bpf/bpf_iterators.rst b/Documentation/bpf/bpf_iterators.rst
index 7f514cb..189e3ec 100644
--- a/Documentation/bpf/bpf_iterators.rst
+++ b/Documentation/bpf/bpf_iterators.rst
@@ -2,10 +2,117 @@
BPF Iterators
=============
+--------
+Overview
+--------
+
+BPF supports two separate entities collectively known as "BPF iterators": BPF
+iterator *program type* and *open-coded* BPF iterators. The former is
+a stand-alone BPF program type which, when attached and activated by user,
+will be called once for each entity (task_struct, cgroup, etc) that is being
+iterated. The latter is a set of BPF-side APIs implementing iterator
+functionality and available across multiple BPF program types. Open-coded
+iterators provide similar functionality to BPF iterator programs, but gives
+more flexibility and control to all other BPF program types. BPF iterator
+programs, on the other hand, can be used to implement anonymous or BPF
+FS-mounted special files, whose contents are generated by attached BPF iterator
+program, backed by seq_file functionality. Both are useful depending on
+specific needs.
+
+When adding a new BPF iterator program, it is expected that similar
+functionality will be added as open-coded iterator for maximum flexibility.
+It's also expected that iteration logic and code will be maximally shared and
+reused between two iterator API surfaces.
-----------
-Motivation
-----------
+------------------------
+Open-coded BPF Iterators
+------------------------
+
+Open-coded BPF iterators are implemented as tightly-coupled trios of kfuncs
+(constructor, next element fetch, destructor) and iterator-specific type
+describing on-the-stack iterator state, which is guaranteed by the BPF
+verifier to not be tampered with outside of the corresponding
+constructor/destructor/next APIs.
+
+Each kind of open-coded BPF iterator has its own associated
+struct bpf_iter_<type>, where <type> denotes a specific type of iterator.
+bpf_iter_<type> state needs to live on BPF program stack, so make sure it's
+small enough to fit on BPF stack. For performance reasons its best to avoid
+dynamic memory allocation for iterator state and size the state struct big
+enough to fit everything necessary. But if necessary, dynamic memory
+allocation is a way to bypass BPF stack limitations. Note, state struct size
+is part of iterator's user-visible API, so changing it will break backwards
+compatibility, so be deliberate about designing it.
+
+All kfuncs (constructor, next, destructor) have to be named consistently as
+bpf_iter_<type>_{new,next,destroy}(), respectively. <type> represents iterator
+type, and iterator state should be represented as a matching
+`struct bpf_iter_<type>` state type. Also, all iter kfuncs should have
+a pointer to this `struct bpf_iter_<type>` as the very first argument.
+
+Additionally:
+ - Constructor, i.e., `bpf_iter_<type>_new()`, can have arbitrary extra
+ number of arguments. Return type is not enforced either.
+ - Next method, i.e., `bpf_iter_<type>_next()`, has to return a pointer
+ type and should have exactly one argument: `struct bpf_iter_<type> *`
+ (const/volatile/restrict and typedefs are ignored).
+ - Destructor, i.e., `bpf_iter_<type>_destroy()`, should return void and
+ should have exactly one argument, similar to the next method.
+ - `struct bpf_iter_<type>` size is enforced to be positive and
+ a multiple of 8 bytes (to fit stack slots correctly).
+
+Such strictness and consistency allows to build generic helpers abstracting
+important, but boilerplate, details to be able to use open-coded iterators
+effectively and ergonomically (see libbpf's bpf_for_each() macro). This is
+enforced at kfunc registration point by the kernel.
+
+Constructor/next/destructor implementation contract is as follows:
+ - constructor, `bpf_iter_<type>_new()`, always initializes iterator state on
+ the stack. If any of the input arguments are invalid, constructor should
+ make sure to still initialize it such that subsequent next() calls will
+ return NULL. I.e., on error, *return error and construct empty iterator*.
+ Constructor kfunc is marked with KF_ITER_NEW flag.
+
+ - next method, `bpf_iter_<type>_next()`, accepts pointer to iterator state
+ and produces an element. Next method should always return a pointer. The
+ contract between BPF verifier is that next method *guarantees* that it
+ will eventually return NULL when elements are exhausted. Once NULL is
+ returned, subsequent next calls *should keep returning NULL*. Next method
+ is marked with KF_ITER_NEXT (and should also have KF_RET_NULL as
+ NULL-returning kfunc, of course).
+
+ - destructor, `bpf_iter_<type>_destroy()`, is always called once. Even if
+ constructor failed or next returned nothing. Destructor frees up any
+ resources and marks stack space used by `struct bpf_iter_<type>` as usable
+ for something else. Destructor is marked with KF_ITER_DESTROY flag.
+
+Any open-coded BPF iterator implementation has to implement at least these
+three methods. It is enforced that for any given type of iterator only
+applicable constructor/destructor/next are callable. I.e., verifier ensures
+you can't pass number iterator state into, say, cgroup iterator's next method.
+
+From a 10,000-feet BPF verification point of view, next methods are the points
+of forking a verification state, which are conceptually similar to what
+verifier is doing when validating conditional jumps. Verifier is branching out
+`call bpf_iter_<type>_next` instruction and simulates two outcomes: NULL
+(iteration is done) and non-NULL (new element is returned). NULL is simulated
+first and is supposed to reach exit without looping. After that non-NULL case
+is validated and it either reaches exit (for trivial examples with no real
+loop), or reaches another `call bpf_iter_<type>_next` instruction with the
+state equivalent to already (partially) validated one. State equivalency at
+that point means we technically are going to be looping forever without
+"breaking out" out of established "state envelope" (i.e., subsequent
+iterations don't add any new knowledge or constraints to the verifier state,
+so running 1, 2, 10, or a million of them doesn't matter). But taking into
+account the contract stating that iterator next method *has to* return NULL
+eventually, we can conclude that loop body is safe and will eventually
+terminate. Given we validated logic outside of the loop (NULL case), and
+concluded that loop body is safe (though potentially looping many times),
+verifier can claim safety of the overall program logic.
+
+------------------------
+BPF Iterators Motivation
+------------------------
There are a few existing ways to dump kernel data into user space. The most
popular one is the ``/proc`` system. For example, ``cat /proc/net/tcp6`` dumps
@@ -323,8 +430,8 @@ Now, in the userspace program, pass the pointer of struct to the
::
- link = bpf_program__attach_iter(prog, &opts); iter_fd =
- bpf_iter_create(bpf_link__fd(link));
+ link = bpf_program__attach_iter(prog, &opts);
+ iter_fd = bpf_iter_create(bpf_link__fd(link));
If both *tid* and *pid* are zero, an iterator created from this struct
``bpf_iter_attach_opts`` will include every opened file of every task in the

Documentation/bpf/kfuncs.rst

View file
diff --git a/Documentation/bpf/kfuncs.rst b/Documentation/bpf/kfuncs.rst
index a8f5782..ae468b7 100644
--- a/Documentation/bpf/kfuncs.rst
+++ b/Documentation/bpf/kfuncs.rst
@@ -160,6 +160,23 @@ Or::
...
}
+2.2.6 __prog Annotation
+---------------------------
+This annotation is used to indicate that the argument needs to be fixed up to
+the bpf_prog_aux of the caller BPF program. Any value passed into this argument
+is ignored, and rewritten by the verifier.
+
+An example is given below::
+
+ __bpf_kfunc int bpf_wq_set_callback_impl(struct bpf_wq *wq,
+ int (callback_fn)(void *map, int *key, void *value),
+ unsigned int flags,
+ void *aux__prog)
+ {
+ struct bpf_prog_aux *aux = aux__prog;
+ ...
+ }
+
.. _BPF_kfunc_nodef:
2.3 Using an existing kernel function

arch/arm64/net/bpf_jit_comp.c

View file
diff --git a/arch/arm64/net/bpf_jit_comp.c b/arch/arm64/net/bpf_jit_comp.c
index 634d784..da8b89d 100644
--- a/arch/arm64/net/bpf_jit_comp.c
+++ b/arch/arm64/net/bpf_jit_comp.c
@@ -2113,7 +2113,7 @@ bool bpf_jit_supports_subprog_tailcalls(void)
}
static void invoke_bpf_prog(struct jit_ctx *ctx, struct bpf_tramp_link *l,
- int args_off, int retval_off, int run_ctx_off,
+ int bargs_off, int retval_off, int run_ctx_off,
bool save_ret)
{
__le32 *branch;
@@ -2155,7 +2155,7 @@ static void invoke_bpf_prog(struct jit_ctx *ctx, struct bpf_tramp_link *l,
branch = ctx->image + ctx->idx;
emit(A64_NOP, ctx);
- emit(A64_ADD_I(1, A64_R(0), A64_SP, args_off), ctx);
+ emit(A64_ADD_I(1, A64_R(0), A64_SP, bargs_off), ctx);
if (!p->jited)
emit_addr_mov_i64(A64_R(1), (const u64)p->insnsi, ctx);
@@ -2180,7 +2180,7 @@ static void invoke_bpf_prog(struct jit_ctx *ctx, struct bpf_tramp_link *l,
}
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,
+ int bargs_off, int retval_off, int run_ctx_off,
__le32 **branches)
{
int i;
@@ -2190,7 +2190,7 @@ static void invoke_bpf_mod_ret(struct jit_ctx *ctx, struct bpf_tramp_links *tl,
*/
emit(A64_STR64I(A64_ZR, A64_SP, retval_off), ctx);
for (i = 0; i < tl->nr_links; i++) {
- invoke_bpf_prog(ctx, tl->links[i], args_off, retval_off,
+ invoke_bpf_prog(ctx, tl->links[i], bargs_off, retval_off,
run_ctx_off, true);
/* if (*(u64 *)(sp + retval_off) != 0)
* goto do_fexit;
@@ -2204,23 +2204,125 @@ static void invoke_bpf_mod_ret(struct jit_ctx *ctx, struct bpf_tramp_links *tl,
}
}
-static void save_args(struct jit_ctx *ctx, int args_off, int nregs)
+struct arg_aux {
+ /* how many args are passed through registers, the rest of the args are
+ * passed through stack
+ */
+ int args_in_regs;
+ /* how many registers are used to pass arguments */
+ int regs_for_args;
+ /* how much stack is used for additional args passed to bpf program
+ * that did not fit in original function registers
+ */
+ int bstack_for_args;
+ /* home much stack is used for additional args passed to the
+ * original function when called from trampoline (this one needs
+ * arguments to be properly aligned)
+ */
+ int ostack_for_args;
+};
+
+static int calc_arg_aux(const struct btf_func_model *m,
+ struct arg_aux *a)
{
- int i;
+ int stack_slots, nregs, slots, i;
+
+ /* verifier ensures m->nr_args <= MAX_BPF_FUNC_ARGS */
+ for (i = 0, nregs = 0; i < m->nr_args; i++) {
+ slots = (m->arg_size[i] + 7) / 8;
+ if (nregs + slots <= 8) /* passed through register ? */
+ nregs += slots;
+ else
+ break;
+ }
+
+ a->args_in_regs = i;
+ a->regs_for_args = nregs;
+ a->ostack_for_args = 0;
+ a->bstack_for_args = 0;
+
+ /* the rest arguments are passed through stack */
+ for (; i < m->nr_args; i++) {
+ /* We can not know for sure about exact alignment needs for
+ * struct passed on stack, so deny those
+ */
+ if (m->arg_flags[i] & BTF_FMODEL_STRUCT_ARG)
+ return -ENOTSUPP;
+ stack_slots = (m->arg_size[i] + 7) / 8;
+ a->bstack_for_args += stack_slots * 8;
+ a->ostack_for_args = a->ostack_for_args + stack_slots * 8;
+ }
+
+ return 0;
+}
- for (i = 0; i < nregs; i++) {
- emit(A64_STR64I(i, A64_SP, args_off), ctx);
- args_off += 8;
+static void clear_garbage(struct jit_ctx *ctx, int reg, int effective_bytes)
+{
+ if (effective_bytes) {
+ int garbage_bits = 64 - 8 * effective_bytes;
+#ifdef CONFIG_CPU_BIG_ENDIAN
+ /* garbage bits are at the right end */
+ emit(A64_LSR(1, reg, reg, garbage_bits), ctx);
+ emit(A64_LSL(1, reg, reg, garbage_bits), ctx);
+#else
+ /* garbage bits are at the left end */
+ emit(A64_LSL(1, reg, reg, garbage_bits), ctx);
+ emit(A64_LSR(1, reg, reg, garbage_bits), ctx);
+#endif
}
}
-static void restore_args(struct jit_ctx *ctx, int args_off, int nregs)
+static void save_args(struct jit_ctx *ctx, int bargs_off, int oargs_off,
+ const struct btf_func_model *m,
+ const struct arg_aux *a,
+ bool for_call_origin)
{
int i;
+ int reg;
+ int doff;
+ int soff;
+ int slots;
+ u8 tmp = bpf2a64[TMP_REG_1];
+
+ /* store arguments to the stack for the bpf program, or restore
+ * arguments from stack for the original function
+ */
+ for (reg = 0; reg < a->regs_for_args; reg++) {
+ emit(for_call_origin ?
+ A64_LDR64I(reg, A64_SP, bargs_off) :
+ A64_STR64I(reg, A64_SP, bargs_off),
+ ctx);
+ bargs_off += 8;
+ }
+
+ soff = 32; /* on stack arguments start from FP + 32 */
+ doff = (for_call_origin ? oargs_off : bargs_off);
+
+ /* save on stack arguments */
+ for (i = a->args_in_regs; i < m->nr_args; i++) {
+ slots = (m->arg_size[i] + 7) / 8;
+ /* verifier ensures arg_size <= 16, so slots equals 1 or 2 */
+ while (slots-- > 0) {
+ emit(A64_LDR64I(tmp, A64_FP, soff), ctx);
+ /* if there is unused space in the last slot, clear
+ * the garbage contained in the space.
+ */
+ if (slots == 0 && !for_call_origin)
+ clear_garbage(ctx, tmp, m->arg_size[i] % 8);
+ emit(A64_STR64I(tmp, A64_SP, doff), ctx);
+ soff += 8;
+ doff += 8;
+ }
+ }
+}
- for (i = 0; i < nregs; i++) {
- emit(A64_LDR64I(i, A64_SP, args_off), ctx);
- args_off += 8;
+static void restore_args(struct jit_ctx *ctx, int bargs_off, int nregs)
+{
+ int reg;
+
+ for (reg = 0; reg < nregs; reg++) {
+ emit(A64_LDR64I(reg, A64_SP, bargs_off), ctx);
+ bargs_off += 8;
}
}
@@ -2243,17 +2345,21 @@ static bool is_struct_ops_tramp(const struct bpf_tramp_links *fentry_links)
*/
static int prepare_trampoline(struct jit_ctx *ctx, struct bpf_tramp_image *im,
struct bpf_tramp_links *tlinks, void *func_addr,
- int nregs, u32 flags)
+ const struct btf_func_model *m,
+ const struct arg_aux *a,
+ u32 flags)
{
int i;
int stack_size;
int retaddr_off;
int regs_off;
int retval_off;
- int args_off;
- int nregs_off;
+ int bargs_off;
+ int nfuncargs_off;
int ip_off;
int run_ctx_off;
+ int oargs_off;
+ int nfuncargs;
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];
@@ -2262,31 +2368,38 @@ static int prepare_trampoline(struct jit_ctx *ctx, struct bpf_tramp_image *im,
bool is_struct_ops = is_struct_ops_tramp(fentry);
/* trampoline stack layout:
- * [ parent ip ]
- * [ FP ]
- * SP + retaddr_off [ self ip ]
- * [ FP ]
+ * [ parent ip ]
+ * [ FP ]
+ * SP + retaddr_off [ self ip ]
+ * [ FP ]
*
- * [ padding ] align SP to multiples of 16
+ * [ padding ] align SP to multiples of 16
*
- * [ x20 ] callee saved reg x20
- * SP + regs_off [ x19 ] callee saved reg x19
+ * [ x20 ] callee saved reg x20
+ * SP + regs_off [ x19 ] callee saved reg x19
*
- * SP + retval_off [ return value ] BPF_TRAMP_F_CALL_ORIG or
- * BPF_TRAMP_F_RET_FENTRY_RET
+ * SP + retval_off [ return value ] BPF_TRAMP_F_CALL_ORIG or
+ * BPF_TRAMP_F_RET_FENTRY_RET
+ * [ arg reg N ]
+ * [ ... ]
+ * SP + bargs_off [ arg reg 1 ] for bpf
*
- * [ arg reg N ]
- * [ ... ]
- * SP + args_off [ arg reg 1 ]
+ * SP + nfuncargs_off [ arg regs count ]
*
- * SP + nregs_off [ arg regs count ]
+ * SP + ip_off [ traced function ] BPF_TRAMP_F_IP_ARG flag
*
- * SP + ip_off [ traced function ] BPF_TRAMP_F_IP_ARG flag
+ * SP + run_ctx_off [ bpf_tramp_run_ctx ]
*
- * SP + run_ctx_off [ bpf_tramp_run_ctx ]
+ * [ stack arg N ]
+ * [ ... ]
+ * SP + oargs_off [ stack arg 1 ] for original func
*/
stack_size = 0;
+ oargs_off = stack_size;
+ if (flags & BPF_TRAMP_F_CALL_ORIG)
+ stack_size += a->ostack_for_args;
+
run_ctx_off = stack_size;
/* room for bpf_tramp_run_ctx */
stack_size += round_up(sizeof(struct bpf_tramp_run_ctx), 8);
@@ -2296,13 +2409,14 @@ static int prepare_trampoline(struct jit_ctx *ctx, struct bpf_tramp_image *im,
if (flags & BPF_TRAMP_F_IP_ARG)
stack_size += 8;
- nregs_off = stack_size;
+ nfuncargs_off = stack_size;
/* room for args count */
stack_size += 8;
- args_off = stack_size;
+ bargs_off = stack_size;
/* room for args */
- stack_size += nregs * 8;
+ nfuncargs = a->regs_for_args + a->bstack_for_args / 8;
+ stack_size += 8 * nfuncargs;
/* room for return value */
retval_off = stack_size;
@@ -2349,11 +2463,11 @@ static int prepare_trampoline(struct jit_ctx *ctx, struct bpf_tramp_image *im,
}
/* save arg regs count*/
- emit(A64_MOVZ(1, A64_R(10), nregs, 0), ctx);
- emit(A64_STR64I(A64_R(10), A64_SP, nregs_off), ctx);
+ emit(A64_MOVZ(1, A64_R(10), nfuncargs, 0), ctx);
+ emit(A64_STR64I(A64_R(10), A64_SP, nfuncargs_off), ctx);
- /* save arg regs */
- save_args(ctx, args_off, nregs);
+ /* save args for bpf */
+ save_args(ctx, bargs_off, oargs_off, m, a, false);
/* save callee saved registers */
emit(A64_STR64I(A64_R(19), A64_SP, regs_off), ctx);
@@ -2369,7 +2483,7 @@ static int prepare_trampoline(struct jit_ctx *ctx, struct bpf_tramp_image *im,
}
for (i = 0; i < fentry->nr_links; i++)
- invoke_bpf_prog(ctx, fentry->links[i], args_off,
+ invoke_bpf_prog(ctx, fentry->links[i], bargs_off,
retval_off, run_ctx_off,
flags & BPF_TRAMP_F_RET_FENTRY_RET);
@@ -2379,12 +2493,13 @@ static int prepare_trampoline(struct jit_ctx *ctx, struct bpf_tramp_image *im,
if (!branches)
return -ENOMEM;
- invoke_bpf_mod_ret(ctx, fmod_ret, args_off, retval_off,
+ invoke_bpf_mod_ret(ctx, fmod_ret, bargs_off, retval_off,
run_ctx_off, branches);
}
if (flags & BPF_TRAMP_F_CALL_ORIG) {
- restore_args(ctx, args_off, nregs);
+ /* save args for original func */
+ save_args(ctx, bargs_off, oargs_off, m, a, true);
/* call original func */
emit(A64_LDR64I(A64_R(10), A64_SP, retaddr_off), ctx);
emit(A64_ADR(A64_LR, AARCH64_INSN_SIZE * 2), ctx);
@@ -2403,7 +2518,7 @@ static int prepare_trampoline(struct jit_ctx *ctx, struct bpf_tramp_image *im,
}
for (i = 0; i < fexit->nr_links; i++)
- invoke_bpf_prog(ctx, fexit->links[i], args_off, retval_off,
+ invoke_bpf_prog(ctx, fexit->links[i], bargs_off, retval_off,
run_ctx_off, false);
if (flags & BPF_TRAMP_F_CALL_ORIG) {
@@ -2417,7 +2532,7 @@ static int prepare_trampoline(struct jit_ctx *ctx, struct bpf_tramp_image *im,
}
if (flags & BPF_TRAMP_F_RESTORE_REGS)
- restore_args(ctx, args_off, nregs);
+ restore_args(ctx, bargs_off, a->regs_for_args);
/* restore callee saved register x19 and x20 */
emit(A64_LDR64I(A64_R(19), A64_SP, regs_off), ctx);
@@ -2454,21 +2569,6 @@ static int prepare_trampoline(struct jit_ctx *ctx, struct bpf_tramp_image *im,
return ctx->idx;
}
-static int btf_func_model_nregs(const struct btf_func_model *m)
-{
- int nregs = m->nr_args;
- int i;
-
- /* extra registers needed for struct argument */
- for (i = 0; i < MAX_BPF_FUNC_ARGS; i++) {
- /* The arg_size is at most 16 bytes, enforced by the verifier. */
- if (m->arg_flags[i] & BTF_FMODEL_STRUCT_ARG)
- nregs += (m->arg_size[i] + 7) / 8 - 1;
- }
-
- return nregs;
-}
-
int arch_bpf_trampoline_size(const struct btf_func_model *m, u32 flags,
struct bpf_tramp_links *tlinks, void *func_addr)
{
@@ -2477,14 +2577,14 @@ int arch_bpf_trampoline_size(const struct btf_func_model *m, u32 flags,
.idx = 0,
};
struct bpf_tramp_image im;
- int nregs, ret;
+ struct arg_aux aaux;
+ int ret;
- nregs = btf_func_model_nregs(m);
- /* the first 8 registers are used for arguments */
- if (nregs > 8)
- return -ENOTSUPP;
+ ret = calc_arg_aux(m, &aaux);
+ if (ret < 0)
+ return ret;
- ret = prepare_trampoline(&ctx, &im, tlinks, func_addr, nregs, flags);
+ ret = prepare_trampoline(&ctx, &im, tlinks, func_addr, m, &aaux, flags);
if (ret < 0)
return ret;
@@ -2511,9 +2611,10 @@ int arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *ro_image,
u32 flags, struct bpf_tramp_links *tlinks,
void *func_addr)
{
- int ret, nregs;
- void *image, *tmp;
u32 size = ro_image_end - ro_image;
+ struct arg_aux aaux;
+ void *image, *tmp;
+ int ret;
/* image doesn't need to be in module memory range, so we can
* use kvmalloc.
@@ -2529,13 +2630,12 @@ int arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *ro_image,
.write = true,
};
- nregs = btf_func_model_nregs(m);
- /* the first 8 registers are used for arguments */
- if (nregs > 8)
- return -ENOTSUPP;
jit_fill_hole(image, (unsigned int)(ro_image_end - ro_image));
- ret = prepare_trampoline(&ctx, im, tlinks, func_addr, nregs, flags);
+ ret = calc_arg_aux(m, &aaux);
+ if (ret)
+ goto out;
+ ret = prepare_trampoline(&ctx, im, tlinks, func_addr, m, &aaux, flags);
if (ret > 0 && validate_code(&ctx) < 0) {
ret = -EINVAL;

arch/riscv/net/bpf_jit.h

View file
diff --git a/arch/riscv/net/bpf_jit.h b/arch/riscv/net/bpf_jit.h
index 1d1c78d..e7b032d 100644
--- a/arch/riscv/net/bpf_jit.h
+++ b/arch/riscv/net/bpf_jit.h
@@ -608,6 +608,21 @@ static inline u32 rv_fence(u8 pred, u8 succ)
return rv_i_insn(imm11_0, 0, 0, 0, 0xf);
}
+static inline void emit_fence_r_rw(struct rv_jit_context *ctx)
+{
+ emit(rv_fence(0x2, 0x3), ctx);
+}
+
+static inline void emit_fence_rw_w(struct rv_jit_context *ctx)
+{
+ emit(rv_fence(0x3, 0x1), ctx);
+}
+
+static inline void emit_fence_rw_rw(struct rv_jit_context *ctx)
+{
+ emit(rv_fence(0x3, 0x3), ctx);
+}
+
static inline u32 rv_nop(void)
{
return rv_i_insn(0, 0, 0, 0, 0x13);

arch/riscv/net/bpf_jit_comp64.c

View file
diff --git a/arch/riscv/net/bpf_jit_comp64.c b/arch/riscv/net/bpf_jit_comp64.c
index ca60db7..10e01ff 100644
--- a/arch/riscv/net/bpf_jit_comp64.c
+++ b/arch/riscv/net/bpf_jit_comp64.c
@@ -473,11 +473,212 @@ static inline void emit_kcfi(u32 hash, struct rv_jit_context *ctx)

This diff is incomplete. Download the complete patch.

arch/riscv/net/bpf_jit_core.c

View file

This diff is incomplete. Download the complete patch.

arch/s390/include/asm/nospec-branch.h

View file

This diff is incomplete. Download the complete patch.

arch/s390/net/bpf_jit_comp.c

View file

This diff is incomplete. Download the complete patch.

drivers/dma-buf/dma-buf.c

View file

This diff is incomplete. Download the complete patch.

include/asm-generic/vmlinux.lds.h

View file

This diff is incomplete. Download the complete patch.

include/linux/bpf-cgroup.h

View file

This diff is incomplete. Download the complete patch.

include/linux/bpf.h

View file

This diff is incomplete. Download the complete patch.

include/linux/bpf_verifier.h

View file

This diff is incomplete. Download the complete patch.

include/linux/dma-buf.h

View file

This diff is incomplete. Download the complete patch.

include/uapi/linux/bpf.h

View file

This diff is incomplete. Download the complete patch.

kernel/bpf/Makefile

View file

This diff is incomplete. Download the complete patch.

kernel/bpf/bpf_struct_ops.c

View file

This diff is incomplete. Download the complete patch.

kernel/bpf/btf.c

View file

This diff is incomplete. Download the complete patch.

kernel/bpf/cgroup.c

View file

This diff is incomplete. Download the complete patch.

kernel/bpf/core.c

View file

This diff is incomplete. Download the complete patch.

kernel/bpf/dmabuf_iter.c

View file

This diff is incomplete. Download the complete patch.

kernel/bpf/hashtab.c

View file

This diff is incomplete. Download the complete patch.

kernel/bpf/helpers.c

View file

This diff is incomplete. Download the complete patch.

kernel/bpf/syscall.c

View file

This diff is incomplete. Download the complete patch.

kernel/bpf/sysfs_btf.c

View file

This diff is incomplete. Download the complete patch.

kernel/bpf/verifier.c

View file

This diff is incomplete. Download the complete patch.

kernel/sched/ext.c

View file

This diff is incomplete. Download the complete patch.

kernel/trace/bpf_trace.c

View file

This diff is incomplete. Download the complete patch.

kernel/trace/trace_uprobe.c

View file

This diff is incomplete. Download the complete patch.

net/bpf/test_run.c

View file

This diff is incomplete. Download the complete patch.

net/core/filter.c

View file

This diff is incomplete. Download the complete patch.

net/core/skmsg.c

View file

This diff is incomplete. Download the complete patch.

net/tls/tls_sw.c

View file

This diff is incomplete. Download the complete patch.

scripts/Makefile.btf

View file

This diff is incomplete. Download the complete patch.

scripts/bpf_doc.py

View file

This diff is incomplete. Download the complete patch.

tools/bpf/bpftool/Documentation/bpftool-prog.rst

View file

This diff is incomplete. Download the complete patch.

tools/bpf/bpftool/bash-completion/bpftool

View file

This diff is incomplete. Download the complete patch.

tools/bpf/bpftool/cgroup.c

View file

This diff is incomplete. Download the complete patch.

tools/bpf/bpftool/link.c

View file

This diff is incomplete. Download the complete patch.

tools/bpf/bpftool/prog.c

View file

This diff is incomplete. Download the complete patch.

tools/include/uapi/linux/bpf.h

View file

This diff is incomplete. Download the complete patch.

tools/lib/bpf/bpf_core_read.h

View file

This diff is incomplete. Download the complete patch.

tools/lib/bpf/bpf_helpers.h

View file

This diff is incomplete. Download the complete patch.

tools/lib/bpf/btf.c

View file

This diff is incomplete. Download the complete patch.

tools/lib/bpf/libbpf.c

View file

This diff is incomplete. Download the complete patch.

tools/lib/bpf/libbpf.h

View file

This diff is incomplete. Download the complete patch.

tools/lib/bpf/libbpf.map

View file

This diff is incomplete. Download the complete patch.

tools/lib/bpf/libbpf_internal.h

View file

This diff is incomplete. Download the complete patch.

tools/lib/bpf/linker.c

View file

This diff is incomplete. Download the complete patch.

tools/lib/bpf/nlattr.c

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/bpf/DENYLIST

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/bpf/DENYLIST.aarch64

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/bpf/Makefile

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/bpf/bench.c

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/bpf/benchs/bench_htab_mem.c

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/bpf/benchs/bench_sockmap.c

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/bpf/bpf_experimental.h

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/bpf/config

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/bpf/prog_tests/arena_spin_lock.c

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/bpf/prog_tests/attach_probe.c

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/bpf/prog_tests/bpf_nf.c

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/bpf/prog_tests/btf_dedup_split.c

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/bpf/prog_tests/btf_split.c

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/bpf/prog_tests/btf_sysfs.c

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/bpf/prog_tests/dmabuf_iter.c

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/bpf/prog_tests/dynptr.c

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/bpf/prog_tests/fd_htab_lookup.c

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/bpf/prog_tests/fill_link_info.c

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/bpf/prog_tests/kmem_cache_iter.c

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/bpf/prog_tests/linked_list.c

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/bpf/prog_tests/rbtree.c

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/bpf/prog_tests/sk_assign.c

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/bpf/prog_tests/socket_helpers.h

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/bpf/prog_tests/sockmap_helpers.h

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/bpf/prog_tests/sockmap_ktls.c

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/bpf/prog_tests/sockmap_listen.c

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/bpf/prog_tests/sockmap_redir.c

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/bpf/prog_tests/tc_redirect.c

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/bpf/prog_tests/test_btf_ext.c

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/bpf/prog_tests/test_veristat.c

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/bpf/prog_tests/verifier.c

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/bpf/prog_tests/xdp_metadata.c

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/bpf/progs/bench_sockmap_prog.c

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/bpf/progs/bpf_arena_spin_lock.h

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/bpf/progs/bpf_misc.h

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/bpf/progs/dmabuf_iter.c

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/bpf/progs/dynptr_success.c

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/bpf/progs/fd_htab_lookup.c

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/bpf/progs/iters.c

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/bpf/progs/linked_list_peek.c

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/bpf/progs/prepare.c

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/bpf/progs/rbtree_fail.c

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/bpf/progs/rbtree_search.c

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/bpf/progs/set_global_vars.c

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/bpf/progs/test_btf_ext.c

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/bpf/progs/test_sockmap_ktls.c

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/bpf/progs/test_sockmap_redir.c

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/bpf/progs/test_tcp_custom_syncookie.c

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/bpf/progs/verifier_bpf_trap.c

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/bpf/progs/verifier_btf_ctx_access.c

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/bpf/progs/verifier_load_acquire.c

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/bpf/progs/verifier_precision.c

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/bpf/progs/verifier_store_release.c

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/bpf/progs/xdp_metadata.c

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/bpf/test_kmods/bpf_testmod.c

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/bpf/test_loader.c

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/bpf/test_verifier.c

View file

This diff is incomplete. Download the complete patch.

tools/testing/selftests/bpf/veristat.c

View file

This diff is incomplete. Download the complete patch.