* [PATCH bpf-next 0/9] bpf: follow-up for scalar evolution series
@ 2026-10-11 6:21 Eduard Zingerman
2026-10-11 6:21 ` [PATCH bpf-next 1/9] bpf: static subprogram arguments liveness should use BTF type info Eduard Zingerman
` (8 more replies)
0 siblings, 9 replies; 14+ messages in thread
From: Eduard Zingerman @ 2026-10-11 6:21 UTC (permalink / raw)
To: bpf, ast; +Cc: andrii, daniel, kernel-team, yonghong.song, Eduard Zingerman
Assorted follow-ups for the series [1]:
- Use BTF type information for static subprograms when inferring live
arguments at call sites.
- Handle ARG_SCALAR and ARG_PTR_TO_DYNPTR in
bpf_global_subprog_stack_access_bytes().
- Fixes for other nits reported by bots for the series.
Fix for build errors on 32-bit platforms was shared previously: [2].
[1] https://lore.kernel.org/bpf/4b4912cf5f30a3c6866a09511c9b5d3a427cb471.camel@gmail.com/T/
bpf: use scalar evolution to widen bounded loops
[2] https://lore.kernel.org/bpf/20261010205828.3366892-1-eddyz87@gmail.com/T/
bpf: use div64_u64{,_rem}() in scev.c
Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
---
Eduard Zingerman (9):
bpf: static subprogram arguments liveness should use BTF type info
bpf: more precise stack liveness effects for global func params
bpf: avoid duplicate declaration for BPF_SCEV_REGS_NUM
bpf: reg_bounds_sync() comment fixup
selftests/bpf: static subprogram argument side liveness tests
selftests/bpf: stack effects of scalar/dynptr global subprog params
selftests/bpf: harden __msg pattern for global_callee_btf_arg
selftests/bpf: harden __msg patterns for step_movsx_bounds_on_line
selftests/bpf: BPF_F_ANY_ALIGNMENT for byte_array_size_spanning()
include/linux/bpf_verifier.h | 3 --
kernel/bpf/btf.c | 8 +--
kernel/bpf/liveness.c | 15 +++---
kernel/bpf/verifier.c | 34 ++++++++----
.../testing/selftests/bpf/prog_tests/exceptions.c | 2 +-
.../bpf/progs/btf__compute_live_registers.c | 21 ++++++++
.../selftests/bpf/progs/compute_live_registers.c | 32 ++++++++---
.../selftests/bpf/progs/verifier_bounds_step.c | 4 +-
.../bpf/progs/verifier_btf_array_access.c | 1 +
.../selftests/bpf/progs/verifier_live_stack.c | 62 +++++++++++++++++++++-
10 files changed, 150 insertions(+), 32 deletions(-)
---
base-commit: 15b578b1715d9a318c804350d98af87c203672bc
change-id: 20261010-scev-minimal-v3-followups-c1e3f247f224
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH bpf-next 1/9] bpf: static subprogram arguments liveness should use BTF type info
2026-10-11 6:21 [PATCH bpf-next 0/9] bpf: follow-up for scalar evolution series Eduard Zingerman
@ 2026-10-11 6:21 ` Eduard Zingerman
2026-10-11 6:38 ` sashiko-bot
2026-10-11 13:29 ` Alexei Starovoitov
2026-10-11 6:21 ` [PATCH bpf-next 2/9] bpf: more precise stack liveness effects for global func params Eduard Zingerman
` (7 subsequent siblings)
8 siblings, 2 replies; 14+ messages in thread
From: Eduard Zingerman @ 2026-10-11 6:21 UTC (permalink / raw)
To: bpf, ast; +Cc: andrii, daniel, kernel-team, yonghong.song, Eduard Zingerman
When computing liveness marks for arguments of static subprograms
bpf_compute_live_registers() should mark all arguments in the
subprogram's BTF type as live.
This over-approximates the program behaviour but avoids gaps in
unreliable BTF detection:
- Suppose subprogram has arguments A, B, C.
- As a result of compiler optimizations, only arguments A and C are
used and passed at call sites.
- As it is now, bpf_compute_live_registers() would detect that and
mark the register r2 as dead at call sites.
- Dead registers are ignored during states pruning, meaning that a
cached state from a path that initializes r2 can prune a path that
leaves it uninitialized.
- This would bypass btf_check_func_arg_match() call and thus would not
set bpf_func_info_aux->unreliable mark for the subprogram.
Revert the expectation in the test case [1] back to it's original
value, subprogram `subprog()` is considered reliable again.
[1] "exceptions/non-throwing extension -> non-throwing subprog"
Fixes: 147400e9c27c ("bpf: Compute parameters liveness in bpf_compute_live_registers()")
Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
---
kernel/bpf/btf.c | 8 ++++---
kernel/bpf/liveness.c | 15 +++++++------
kernel/bpf/verifier.c | 26 ++++++++++++++++------
.../testing/selftests/bpf/prog_tests/exceptions.c | 2 +-
4 files changed, 33 insertions(+), 18 deletions(-)
diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
index f4d119f3d5ef..5f4e211b1bdb 100644
--- a/kernel/bpf/btf.c
+++ b/kernel/bpf/btf.c
@@ -8634,7 +8634,6 @@ int btf_prepare_func_args(struct bpf_verifier_env *env, int subprog)
}
args = (const struct btf_param *)(t + 1);
nargs = btf_type_vlen(t);
- sub->arg_slot_cnt = nargs;
if (nargs > MAX_BPF_FUNC_ARGS) {
bpf_log(log, "kernel supports at most %d parameters, function %s has %d\n",
MAX_BPF_FUNC_ARGS, tname, nargs);
@@ -8829,10 +8828,13 @@ int btf_prepare_func_args(struct bpf_verifier_env *env, int subprog)
return -EINVAL;
}
- err = btf_check_arg_slots(log, tname, is_global, slots_used, sub);
+ if (verifier_bug_if(slots_used != sub->arg_slot_cnt, env,
+ "func#%d argument slot count mismatch: %u != %u",
+ subprog, slots_used, sub->arg_slot_cnt))
+ return -EFAULT;
+ err = btf_check_arg_slots(log, tname, is_global, sub->arg_slot_cnt, sub);
if (err)
return err;
- sub->arg_slot_cnt = slots_used;
sub->args_cached = true;
diff --git a/kernel/bpf/liveness.c b/kernel/bpf/liveness.c
index e657e6d95408..024790097f96 100644
--- a/kernel/bpf/liveness.c
+++ b/kernel/bpf/liveness.c
@@ -2623,14 +2623,15 @@ static void compute_insn_live_regs(struct bpf_verifier_env *env,
if (bpf_get_call_summary(env, insn, &cs)) {
use = GENMASK(min_t(u8, cs.arg_slot_cnt, MAX_BPF_FUNC_REG_ARGS), 1);
} else if (bpf_pseudo_call(insn)) {
- /* a static callee's reads are added in bpf_compute_live_registers() */
+ /*
+ * Use BTF signatures as a starting point.
+ * See special case for static subprograms
+ * in the bpf_compute_live_registers()'s main loop.
+ */
subprog = callee_subprog(env, insn);
- if (bpf_subprog_is_global(env, subprog)) {
- reg_args = min_t(u8, env->subprog_info[subprog].arg_slot_cnt, MAX_BPF_FUNC_REG_ARGS);
- use = GENMASK(reg_args, 1);
- } else {
- use = 0;
- }
+ reg_args = min_t(u8, env->subprog_info[subprog].arg_slot_cnt,
+ MAX_BPF_FUNC_REG_ARGS);
+ use = GENMASK(reg_args, 1);
}
def = mask_widen(def);
use = mask_widen(use);
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 2f190abe3448..fc1937b37dcf 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -14834,15 +14834,27 @@ static bool try_btf_prepare_func_args(struct bpf_verifier_env *env, int subprog)
return !err;
}
-/* Prepare argument metadata for liveness; the main program is handled separately. */
+/* Initialize env->subprog_info[].arg_slot_cnt */
static void prepare_subprog_args(struct bpf_verifier_env *env)
{
+ struct bpf_prog_aux *aux = env->prog->aux;
+ const struct btf_type *t;
int i;
- for (i = 1; i < env->subprog_cnt; i++) {
- if (!try_btf_prepare_func_args(env, i) && bpf_subprog_is_global(env, i))
- /* Keep all argument registers live if the prototype is unavailable. */
- env->subprog_info[i].arg_slot_cnt = MAX_BPF_FUNC_REG_ARGS;
+ for (i = 0; i < env->subprog_cnt; i++) {
+ /*
+ * Keep all argument registers live if the prototype is unavailable.
+ * No need to include stack args, as those are not supported for
+ * subprograms w/o BTF.
+ */
+ env->subprog_info[i].arg_slot_cnt = MAX_BPF_FUNC_REG_ARGS;
+ if (!aux->func_info)
+ continue;
+ /* BTF validation guarantees FUNC -> FUNC_PROTO. */
+ t = btf_type_by_id(aux->btf, aux->func_info[i].type_id);
+ t = btf_type_by_id(aux->btf, t->type);
+ env->subprog_info[i].arg_slot_cnt = min_t(u32, btf_proto_slots(aux->btf, t),
+ MAX_BPF_FUNC_ARGS);
}
}
@@ -23396,6 +23408,8 @@ int bpf_check(struct bpf_prog **prog, union bpf_attr *attr, bpfptr_t uattr,
if (ret < 0)
goto skip_full_check;
+ prepare_subprog_args(env);
+
ret = check_subprogs(env);
if (ret < 0)
goto skip_full_check;
@@ -23458,8 +23472,6 @@ int bpf_check(struct bpf_prog **prog, union bpf_attr *attr, bpfptr_t uattr,
if (ret < 0)
goto skip_full_check;
- prepare_subprog_args(env);
-
ret = bpf_compute_idoms(env);
if (ret < 0)
goto skip_full_check;
diff --git a/tools/testing/selftests/bpf/prog_tests/exceptions.c b/tools/testing/selftests/bpf/prog_tests/exceptions.c
index cea01d638f6f..3705db18c1bb 100644
--- a/tools/testing/selftests/bpf/prog_tests/exceptions.c
+++ b/tools/testing/selftests/bpf/prog_tests/exceptions.c
@@ -322,7 +322,7 @@ static void test_exceptions_success(void)
bpf_program__fd(skel->progs.exception_throw_subprog),
"subprog"), "set_attach_target"))
goto done;
- }), "Cannot replace static functions", 0);
+ }), "subprog() is not a global function", 0);
if (test__start_subtest("non-throwing extension -> throwing subprog"))
/* non-throwing extension -> throwing subprog : BAD (!global) */
--
2.53.0
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH bpf-next 2/9] bpf: more precise stack liveness effects for global func params
2026-10-11 6:21 [PATCH bpf-next 0/9] bpf: follow-up for scalar evolution series Eduard Zingerman
2026-10-11 6:21 ` [PATCH bpf-next 1/9] bpf: static subprogram arguments liveness should use BTF type info Eduard Zingerman
@ 2026-10-11 6:21 ` Eduard Zingerman
2026-10-11 6:21 ` [PATCH bpf-next 3/9] bpf: avoid duplicate declaration for BPF_SCEV_REGS_NUM Eduard Zingerman
` (6 subsequent siblings)
8 siblings, 0 replies; 14+ messages in thread
From: Eduard Zingerman @ 2026-10-11 6:21 UTC (permalink / raw)
To: bpf, ast; +Cc: andrii, daniel, kernel-team, yonghong.song, Eduard Zingerman
The following types can be returned by the btf_prepare_func_args():
- ARG_PTR_TO_CTX
- ARG_PTR_TO_BTF_ID (+ flags)
- ARG_PTR_TO_MEM (+ flags)
- ARG_PTR_TO_ARENA
- ARG_PTR_TO_DYNPTR
- ARG_SCALAR
Of these, valid programs can pass frame pointer only as
ARG_PTR_TO_{MEM,BTF_ID,DYNPTR}. Additionally, pointer arithmetic
allows the following trick:
0: (bf) r1 = r10
1: (07) r1 += -8
2: (1f) r1 -= r10
3: (85) call pc+1 // r1=fp0 ?
4: (95) exit
This commit changes bpf_global_subprog_stack_access_bytes() to handle
ARG_SCALAR and ARG_PTR_TO_DYNPTR, thus addressing the full set of
possible returned values.
Fixes: 8212c1c2986d ("bpf: Derive global subprog stack liveness from BTF signatures")
Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
---
kernel/bpf/verifier.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index fc1937b37dcf..5b6200083d05 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -14883,7 +14883,7 @@ bpf_global_subprog_stack_access_bytes(struct bpf_verifier_env *env, struct bpf_i
switch (base_type(sub->args[arg].arg_type)) {
case ARG_UNUSED: /* Not an argument slot. */
- case ARG_ANYTHING: /* A scalar, the callee can't dereference it. */
+ case ARG_SCALAR: /* A scalar, the callee can't dereference it. */
return (struct arg_access_info) {};
case ARG_PTR_TO_BTF_ID:
/*
@@ -14899,6 +14899,10 @@ bpf_global_subprog_stack_access_bytes(struct bpf_verifier_env *env, struct bpf_i
info.must_write = true;
}
return info;
+ case ARG_PTR_TO_DYNPTR:
+ /* The callee may adjust the view, but cannot reinitialize the dynptr. */
+ info.size = BPF_DYNPTR_SIZE;
+ return info;
default:
return info;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH bpf-next 3/9] bpf: avoid duplicate declaration for BPF_SCEV_REGS_NUM
2026-10-11 6:21 [PATCH bpf-next 0/9] bpf: follow-up for scalar evolution series Eduard Zingerman
2026-10-11 6:21 ` [PATCH bpf-next 1/9] bpf: static subprogram arguments liveness should use BTF type info Eduard Zingerman
2026-10-11 6:21 ` [PATCH bpf-next 2/9] bpf: more precise stack liveness effects for global func params Eduard Zingerman
@ 2026-10-11 6:21 ` Eduard Zingerman
2026-10-11 6:55 ` bot+bpf-ci
2026-10-11 6:21 ` [PATCH bpf-next 4/9] bpf: reg_bounds_sync() comment fixup Eduard Zingerman
` (5 subsequent siblings)
8 siblings, 1 reply; 14+ messages in thread
From: Eduard Zingerman @ 2026-10-11 6:21 UTC (permalink / raw)
To: bpf, ast; +Cc: andrii, daniel, kernel-team, yonghong.song, Eduard Zingerman
The "bpf: Use SCEV to widen bounded loops" commit introduced a
second (identical and unnecessary) definition for the
BPF_SCEV_REGS_NUM macro.
Fixes: 088a5477a9bd ("bpf: Avoid widening registers that hinder exact stack-slot tracking")
Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
---
include/linux/bpf_verifier.h | 3 ---
1 file changed, 3 deletions(-)
diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h
index 54cb6d3d0653..791398e14962 100644
--- a/include/linux/bpf_verifier.h
+++ b/include/linux/bpf_verifier.h
@@ -708,9 +708,6 @@ struct bpf_loop_exit {
int to; /* instruction outside the loop */
};
-/* SCEV/widening register space: r0..r10 plus every stack slot of a frame. */
-#define BPF_SCEV_REGS_NUM (MAX_BPF_REG + MAX_BPF_STACK_SLOTS)
-
struct bpf_loop {
struct bpf_backedge backedges[MAX_BACKEDGES];
/* edges exiting from this loop, includes edges from nested loops */
--
2.53.0
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH bpf-next 4/9] bpf: reg_bounds_sync() comment fixup
2026-10-11 6:21 [PATCH bpf-next 0/9] bpf: follow-up for scalar evolution series Eduard Zingerman
` (2 preceding siblings ...)
2026-10-11 6:21 ` [PATCH bpf-next 3/9] bpf: avoid duplicate declaration for BPF_SCEV_REGS_NUM Eduard Zingerman
@ 2026-10-11 6:21 ` Eduard Zingerman
2026-10-11 6:21 ` [PATCH bpf-next 5/9] selftests/bpf: static subprogram argument side liveness tests Eduard Zingerman
` (4 subsequent siblings)
8 siblings, 0 replies; 14+ messages in thread
From: Eduard Zingerman @ 2026-10-11 6:21 UTC (permalink / raw)
To: bpf, ast; +Cc: andrii, daniel, kernel-team, yonghong.song, Eduard Zingerman
Array traversal logic in btf_struct_access() starts from reg_smin().
Update comment to match the logic.
Fixes: 0892ef2a7ef3 ("bpf: Representation for intervals with steps")
Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
---
kernel/bpf/verifier.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 5b6200083d05..503c01a36a12 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -2354,7 +2354,7 @@ static void reg_bounds_sync(struct bpf_reg_state *reg)
* potentially w/o intersection, or intersecting after N
* tnum_step()'s, where N can be large. On the other hand,
* step+base *must* be in sync with r64 in order for
- * array traversal logic starting at reg_umin() to be sound.
+ * array traversal logic starting at reg_smin() to be sound.
* Hence, place this as a final step in the reg_bounds_sync().
*/
__update_bounds_from_step(reg);
--
2.53.0
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH bpf-next 5/9] selftests/bpf: static subprogram argument side liveness tests
2026-10-11 6:21 [PATCH bpf-next 0/9] bpf: follow-up for scalar evolution series Eduard Zingerman
` (3 preceding siblings ...)
2026-10-11 6:21 ` [PATCH bpf-next 4/9] bpf: reg_bounds_sync() comment fixup Eduard Zingerman
@ 2026-10-11 6:21 ` Eduard Zingerman
2026-10-11 7:17 ` bot+bpf-ci
2026-10-11 6:21 ` [PATCH bpf-next 6/9] selftests/bpf: stack effects of scalar/dynptr global subprog params Eduard Zingerman
` (3 subsequent siblings)
8 siblings, 1 reply; 14+ messages in thread
From: Eduard Zingerman @ 2026-10-11 6:21 UTC (permalink / raw)
To: bpf, ast; +Cc: andrii, daniel, kernel-team, yonghong.song, Eduard Zingerman
Verify that liveness at calls to static subprograms includes both
the argument registers declared in BTF and those that are actually
read by the callee.
Cover cases where the BTF declaration matches the callee's register
use and where it does not (as might happen as a result of compiler
optimizations).
Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
---
.../bpf/progs/btf__compute_live_registers.c | 21 ++++++++++++++
.../selftests/bpf/progs/compute_live_registers.c | 32 ++++++++++++++++++----
2 files changed, 47 insertions(+), 6 deletions(-)
diff --git a/tools/testing/selftests/bpf/progs/btf__compute_live_registers.c b/tools/testing/selftests/bpf/progs/btf__compute_live_registers.c
new file mode 100644
index 000000000000..b6633fa88030
--- /dev/null
+++ b/tools/testing/selftests/bpf/progs/btf__compute_live_registers.c
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/bpf.h>
+#include <bpf/bpf_helpers.h>
+#include "bpf_misc.h"
+
+/* Use both parameters so clang keeps them in the static functions' BTF. */
+static __noinline __used int static_two(int a, int b)
+{
+ return a + b;
+}
+
+static __noinline __used int static_three(int a, int b)
+{
+ return a + b;
+}
+
+__noinline __used int global_two(int a, int b)
+{
+ return a;
+}
diff --git a/tools/testing/selftests/bpf/progs/compute_live_registers.c b/tools/testing/selftests/bpf/progs/compute_live_registers.c
index b0aaf5961ac9..61605385b3a3 100644
--- a/tools/testing/selftests/bpf/progs/compute_live_registers.c
+++ b/tools/testing/selftests/bpf/progs/compute_live_registers.c
@@ -414,9 +414,21 @@ static __used __naked int aux1(void)
::: __clobber_all);
}
-static __noinline __used int static_two(int a, int b)
+static __used __naked int static_two(int a, int b)
{
- return a;
+ asm volatile (
+ "w0 = w1;"
+ "exit;"
+ ::: __clobber_all);
+}
+
+static __used __naked int static_three(int a, int b)
+{
+ asm volatile (
+ "w0 = w1;"
+ "w0 += w3;"
+ "exit;"
+ ::: __clobber_all);
}
__noinline __used int global_two(int a, int b)
@@ -425,10 +437,15 @@ __noinline __used int global_two(int a, int b)
}
SEC("socket")
-__log_level(2)
-/* a static callee reads r1 only, a global callee its declared arguments */
-__msg("2: .1........ (85) call pc+")
-__msg("5: .12....... (85) call pc+")
+__success __log_level(2)
+__btf_func_path("btf__compute_live_registers.bpf.o")
+/*
+ * BTF declares r1 and r2 for each callee. static_two reads only r1,
+ * while static_three also reads r3, so its call must keep all three live.
+ */
+__msg("2: .12....... (85) call pc+")
+__msg("5: .123...... (85) call pc+")
+__msg("8: .12....... (85) call pc+")
__naked void subprog_declared_args(void)
{
asm volatile (
@@ -436,6 +453,9 @@ __naked void subprog_declared_args(void)
"r2 = 2;"
"call static_two;"
"r1 = 1;"
+ "r3 = 3;"
+ "call static_three;"
+ "r1 = 1;"
"r2 = 2;"
"call global_two;"
"r0 = 0;"
--
2.53.0
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH bpf-next 6/9] selftests/bpf: stack effects of scalar/dynptr global subprog params
2026-10-11 6:21 [PATCH bpf-next 0/9] bpf: follow-up for scalar evolution series Eduard Zingerman
` (4 preceding siblings ...)
2026-10-11 6:21 ` [PATCH bpf-next 5/9] selftests/bpf: static subprogram argument side liveness tests Eduard Zingerman
@ 2026-10-11 6:21 ` Eduard Zingerman
2026-10-11 6:21 ` [PATCH bpf-next 7/9] selftests/bpf: harden __msg pattern for global_callee_btf_arg Eduard Zingerman
` (2 subsequent siblings)
8 siblings, 0 replies; 14+ messages in thread
From: Eduard Zingerman @ 2026-10-11 6:21 UTC (permalink / raw)
To: bpf, ast; +Cc: andrii, daniel, kernel-team, yonghong.song, Eduard Zingerman
Verify that a frame pointer derived value does not induce stack
liveness effects, when passed as a scalar argument of a
global function.
Verify that a stack-based dynptr passed to a global function marks
live only corresponding 16 bytes.
Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
---
.../selftests/bpf/progs/verifier_live_stack.c | 56 ++++++++++++++++++++++
1 file changed, 56 insertions(+)
diff --git a/tools/testing/selftests/bpf/progs/verifier_live_stack.c b/tools/testing/selftests/bpf/progs/verifier_live_stack.c
index 3d88cb28b8fe..d2fdc65c84c5 100644
--- a/tools/testing/selftests/bpf/progs/verifier_live_stack.c
+++ b/tools/testing/selftests/bpf/progs/verifier_live_stack.c
@@ -182,6 +182,62 @@ __naked void global_callee_arg(void)
::: __clobber_all);
}
+__noinline int global_int_arg(int x)
+{
+ return 0;
+}
+
+SEC("socket")
+__success __log_level(2)
+__msg("stack use/def subprog#0 global_noop_int_arg (d0,cs0):")
+__msg_next(" 0: (bf) r1 = r10{{$}}")
+__msg_next(" 1: (07) r1 += -8{{$}}")
+__msg_next(" 2: (1f) r1 -= r10{{$}}")
+__msg_next(" 3: (85) call pc+1{{$}}")
+__msg_next(" 4: (95) exit")
+__naked void global_noop_int_arg(void)
+{
+ asm volatile (
+ "r1 = r10;"
+ "r1 += -8;"
+ "r1 -= r10;" /* This is a scalar now. */
+ "call global_int_arg;" /* And should not be tracked as stack effect. */
+ "exit;"
+ ::: __clobber_all);
+}
+
+static char global_dynptr_buf[8];
+
+__noinline int global_noop_dynptr_arg(struct bpf_dynptr *p)
+{
+ return 0;
+}
+
+SEC("socket")
+__success __log_level(2)
+/* A global dynptr argument may read/write only its 16 bytes, with no definite write. */
+__msg("stack use/def subprog#0 global_callee_dynptr_arg (d0,cs0):")
+__msg(" 7: (bf) r1 = r10{{$}}")
+__msg_next(" 8: (07) r1 += -32{{$}}")
+__msg_next(" 9: (85) call pc+1{{ +}}; use: fp0-24 fp0-32 may_def: fp0-24 fp0-32{{$}}")
+__msg_next(" 10: (95) exit{{$}}")
+__naked void global_callee_dynptr_arg(void)
+{
+ asm volatile (
+ "r1 = %[global_dynptr_buf] ll;"
+ "r2 = 8;"
+ "r3 = 0;"
+ "r4 = r10;"
+ "r4 += -32;"
+ "call %[bpf_dynptr_from_mem];"
+ "r1 = r10;"
+ "r1 += -32;"
+ "call global_noop_dynptr_arg;"
+ "exit;"
+ :: __imm_addr(global_dynptr_buf), __imm(bpf_dynptr_from_mem)
+ : __clobber_all);
+}
+
struct task_struct { int pid; };
__noinline int global_noop_btf_arg(struct task_struct *p __arg_untrusted)
--
2.53.0
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH bpf-next 7/9] selftests/bpf: harden __msg pattern for global_callee_btf_arg
2026-10-11 6:21 [PATCH bpf-next 0/9] bpf: follow-up for scalar evolution series Eduard Zingerman
` (5 preceding siblings ...)
2026-10-11 6:21 ` [PATCH bpf-next 6/9] selftests/bpf: stack effects of scalar/dynptr global subprog params Eduard Zingerman
@ 2026-10-11 6:21 ` Eduard Zingerman
2026-10-11 6:21 ` [PATCH bpf-next 8/9] selftests/bpf: harden __msg patterns for step_movsx_bounds_on_line Eduard Zingerman
2026-10-11 6:21 ` [PATCH bpf-next 9/9] selftests/bpf: BPF_F_ANY_ALIGNMENT for byte_array_size_spanning() Eduard Zingerman
8 siblings, 0 replies; 14+ messages in thread
From: Eduard Zingerman @ 2026-10-11 6:21 UTC (permalink / raw)
To: bpf, ast; +Cc: andrii, daniel, kernel-team, yonghong.song, Eduard Zingerman
The original pattern:
__msg("3: (85) call pc+{{[0-9]+}}\n")
Is ambigous, as this line is printed on the main verification pass as
well. Harden the test case by ensuring a __msg_next sequence matching
the stack use/def results specifically.
Fixes: 063c85f5d8c7 ("selftests/bpf: Tests for BTF-based global subprog stack liveness")
Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
---
tools/testing/selftests/bpf/progs/verifier_live_stack.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/tools/testing/selftests/bpf/progs/verifier_live_stack.c b/tools/testing/selftests/bpf/progs/verifier_live_stack.c
index d2fdc65c84c5..5f9b11a81260 100644
--- a/tools/testing/selftests/bpf/progs/verifier_live_stack.c
+++ b/tools/testing/selftests/bpf/progs/verifier_live_stack.c
@@ -249,7 +249,11 @@ SEC("socket")
__success __log_level(2)
/* Untrusted BTF pointer arguments need no caller stack state. */
__msg("stack use/def subprog#0 global_callee_btf_arg (d0,cs0):")
-__msg("3: (85) call pc+{{[0-9]+}}\n")
+__msg_next(" 0: (7a) *(u64 *)(r10 -8) = 0{{.*}}")
+__msg_next(" 1: (bf) r1 = r10{{$}}")
+__msg_next(" 2: (07) r1 += -8{{$}}")
+__msg_next(" 3: (85) call pc+1{{$}}")
+__msg_next(" 4: (95) exit{{$}}")
__naked void global_callee_btf_arg(void)
{
asm volatile (
--
2.53.0
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH bpf-next 8/9] selftests/bpf: harden __msg patterns for step_movsx_bounds_on_line
2026-10-11 6:21 [PATCH bpf-next 0/9] bpf: follow-up for scalar evolution series Eduard Zingerman
` (6 preceding siblings ...)
2026-10-11 6:21 ` [PATCH bpf-next 7/9] selftests/bpf: harden __msg pattern for global_callee_btf_arg Eduard Zingerman
@ 2026-10-11 6:21 ` Eduard Zingerman
2026-10-11 6:21 ` [PATCH bpf-next 9/9] selftests/bpf: BPF_F_ANY_ALIGNMENT for byte_array_size_spanning() Eduard Zingerman
8 siblings, 0 replies; 14+ messages in thread
From: Eduard Zingerman @ 2026-10-11 6:21 UTC (permalink / raw)
To: bpf, ast; +Cc: andrii, daniel, kernel-team, yonghong.song, Eduard Zingerman
The `{{.*}}` in the pattern for R5 below might hide the `step=...`
logging from the __no_step annotation. Replace it with full expected
log instead. Also drop __no_step for R3 above, where it is
unnecessary.
Fixes: 2db5837f9ada ("selftests/bpf: Tests for register base/step arithmetic")
Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
---
tools/testing/selftests/bpf/progs/verifier_bounds_step.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tools/testing/selftests/bpf/progs/verifier_bounds_step.c b/tools/testing/selftests/bpf/progs/verifier_bounds_step.c
index c9ee1c7efcbb..d824a5d48a39 100644
--- a/tools/testing/selftests/bpf/progs/verifier_bounds_step.c
+++ b/tools/testing/selftests/bpf/progs/verifier_bounds_step.c
@@ -338,9 +338,9 @@ SEC("socket")
__success __log_level(2)
__msg("r1 = (s16)r0 {{.*}}R1=scalar(id={{[0-9]+}},smin=smin32=0,smax=umax=smax32=umax32=168,{{.*}}step=0+24)")
__msg("r2 = (s16)r0 {{.*}}R2=scalar(smin=smin32=-24,smax=smax32=144,{{.*}}step=0+24)")
-__msg("r3 = (s8)r0 {{.*}}R3=scalar(smin=smin32=-128,smax=smax32=127)") __no_step
+__msg("r3 = (s8)r0 {{.*}}R3=scalar(smin=smin32=-128,smax=smax32=127)")
__msg("w4 = (s16)w1 {{.*}}R4=scalar(id={{[0-9]+}},smin=smin32=0,smax=umax=smax32=umax32=168,{{.*}}step=0+24)")
-__msg("w5 = (s8)w1 {{.*}}R5=scalar({{.*}}smin32=-128,smax32=127,{{.*}})") __no_step
+__msg("w5 = (s8)w1 {{.*}}R5=scalar({{.*}}smin32=-128,smax32=127,var_off=(0x0; 0xffffffff))")
__naked void step_movsx_bounds_on_line(void)
{
asm volatile (" \
--
2.53.0
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH bpf-next 9/9] selftests/bpf: BPF_F_ANY_ALIGNMENT for byte_array_size_spanning()
2026-10-11 6:21 [PATCH bpf-next 0/9] bpf: follow-up for scalar evolution series Eduard Zingerman
` (7 preceding siblings ...)
2026-10-11 6:21 ` [PATCH bpf-next 8/9] selftests/bpf: harden __msg patterns for step_movsx_bounds_on_line Eduard Zingerman
@ 2026-10-11 6:21 ` Eduard Zingerman
8 siblings, 0 replies; 14+ messages in thread
From: Eduard Zingerman @ 2026-10-11 6:21 UTC (permalink / raw)
To: bpf, ast; +Cc: andrii, daniel, kernel-team, yonghong.song, Eduard Zingerman
The test case indexes inside `char bytes[32]` array with unaligned
offset. Use BPF_F_ANY_ALIGNMENT flag to avoid the test rejection for
unrelated reason.
Fixes: e187fac8ac6b ("selftests/bpf: Tests for varying offset access to PTR_TO_BTF_ID")
Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
---
tools/testing/selftests/bpf/progs/verifier_btf_array_access.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/tools/testing/selftests/bpf/progs/verifier_btf_array_access.c b/tools/testing/selftests/bpf/progs/verifier_btf_array_access.c
index be001cc77f81..9dc2c9a5f8b7 100644
--- a/tools/testing/selftests/bpf/progs/verifier_btf_array_access.c
+++ b/tools/testing/selftests/bpf/progs/verifier_btf_array_access.c
@@ -114,6 +114,7 @@ int long_array_in_bounds(void *ctx)
*/
SEC("syscall")
__failure
+__flag(BPF_F_ANY_ALIGNMENT)
__msg("invalid variable offset access into struct outer")
int byte_array_size_spanning(void *ctx)
{
--
2.53.0
^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH bpf-next 1/9] bpf: static subprogram arguments liveness should use BTF type info
2026-10-11 6:21 ` [PATCH bpf-next 1/9] bpf: static subprogram arguments liveness should use BTF type info Eduard Zingerman
@ 2026-10-11 6:38 ` sashiko-bot
2026-10-11 13:29 ` Alexei Starovoitov
1 sibling, 0 replies; 14+ messages in thread
From: sashiko-bot @ 2026-10-11 6:38 UTC (permalink / raw)
To: Eduard Zingerman; +Cc: bpf
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] bpf: state explosion for non-BTF static subprograms
--
commit aaf0f2ac344fe68dd84ff5e9d26151d93e265a96
Author: Eduard Zingerman <eddyz87@gmail.com>
bpf: static subprogram arguments liveness should use BTF type info
When computing liveness marks for arguments of static subprograms, this
commit modifies the verifier to mark all arguments in the subprogram's
BTF type as live to avoid gaps in unreliable BTF detection.
> diff --git a/kernel/bpf/liveness.c b/kernel/bpf/liveness.c
> index e657e6d95408f..024790097f960 100644
> --- a/kernel/bpf/liveness.c
> +++ b/kernel/bpf/liveness.c
[ ... ]
> @@ -2623,14 +2623,15 @@ static void compute_insn_live_regs(struct bpf_verifier_env *env,
> if (bpf_get_call_summary(env, insn, &cs)) {
> use = GENMASK(min_t(u8, cs.arg_slot_cnt, MAX_BPF_FUNC_REG_ARGS), 1);
> } else if (bpf_pseudo_call(insn)) {
> - /* a static callee's reads are added in bpf_compute_live_registers() */
> + /*
> + * Use BTF signatures as a starting point.
> + * See special case for static subprograms
> + * in the bpf_compute_live_registers()'s main loop.
> + */
> subprog = callee_subprog(env, insn);
> - if (bpf_subprog_is_global(env, subprog)) {
> - reg_args = min_t(u8, env->subprog_info[subprog].arg_slot_cnt, MAX_BPF_FUNC_REG_ARGS);
> - use = GENMASK(reg_args, 1);
> - } else {
> - use = 0;
> - }
> + reg_args = min_t(u8, env->subprog_info[subprog].arg_slot_cnt,
> + MAX_BPF_FUNC_REG_ARGS);
> + use = GENMASK(reg_args, 1);
[Severity: Medium]
Will this unconditionally force registers R1-R5 to be tracked as live for
static subprograms when BTF is missing?
Before this patch, `use` was initialized to 0 for static subprograms, which
correctly limited liveness to registers actually read by the callee. By
removing the `bpf_subprog_is_global()` check, could this unnecessarily widen
the liveness mask?
> diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
> index 2f190abe34489..fc1937b37dcff 100644
> --- a/kernel/bpf/verifier.c
> +++ b/kernel/bpf/verifier.c
[ ... ]
> @@ -14834,15 +14834,27 @@ static bool try_btf_prepare_func_args(struct bpf_verifier_env *env, int subprog)
> return !err;
> }
>
> -/* Prepare argument metadata for liveness; the main program is handled separately. */
> +/* Initialize env->subprog_info[].arg_slot_cnt */
> static void prepare_subprog_args(struct bpf_verifier_env *env)
> {
> + struct bpf_prog_aux *aux = env->prog->aux;
> + const struct btf_type *t;
> int i;
>
> - for (i = 1; i < env->subprog_cnt; i++) {
> - if (!try_btf_prepare_func_args(env, i) && bpf_subprog_is_global(env, i))
> - /* Keep all argument registers live if the prototype is unavailable. */
> - env->subprog_info[i].arg_slot_cnt = MAX_BPF_FUNC_REG_ARGS;
> + for (i = 0; i < env->subprog_cnt; i++) {
> + /*
> + * Keep all argument registers live if the prototype is unavailable.
> + * No need to include stack args, as those are not supported for
> + * subprograms w/o BTF.
> + */
> + env->subprog_info[i].arg_slot_cnt = MAX_BPF_FUNC_REG_ARGS;
> + if (!aux->func_info)
> + continue;
[Severity: Medium]
Does initializing `arg_slot_cnt` to 5 for all subprograms without BTF severely
degrade state pruning?
If a BPF program without BTF makes a pseudo-call to a static subprogram, the
verifier now requires exact state matches for R1-R5 during pruning, even if
the callee never reads them. Could this cause previously valid programs to be
rejected by the 1M instruction complexity limit due to state explosion?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261010-scev-minimal-v3-followups-v1-0-6000e95ef993@gmail.com?part=1
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH bpf-next 3/9] bpf: avoid duplicate declaration for BPF_SCEV_REGS_NUM
2026-10-11 6:21 ` [PATCH bpf-next 3/9] bpf: avoid duplicate declaration for BPF_SCEV_REGS_NUM Eduard Zingerman
@ 2026-10-11 6:55 ` bot+bpf-ci
0 siblings, 0 replies; 14+ messages in thread
From: bot+bpf-ci @ 2026-10-11 6:55 UTC (permalink / raw)
To: eddyz87, bpf, ast
Cc: andrii, daniel, kernel-team, yonghong.song, eddyz87, ast, andrii,
daniel, martin.lau, eddyz87, yonghong.song, mason, ihor.solodrai
[-- Attachment #1: Type: text/plain, Size: 1928 bytes --]
> bpf: avoid duplicate declaration for BPF_SCEV_REGS_NUM
TL;DR: Commit message only: the body may blame the wrong commit for the
duplicate BPF_SCEV_REGS_NUM define (it disagrees with the Fixes: tag), and the
subject says "declaration" instead of "definition". No code issues.
> bpf: avoid duplicate declaration for BPF_SCEV_REGS_NUM
>
> The "bpf: Use SCEV to widen bounded loops" commit introduced a
> second (identical and unnecessary) definition for the
> BPF_SCEV_REGS_NUM macro.
> Fixes: 088a5477a9bd ("bpf: Avoid widening registers that hinder exact stack-slot tracking")
> Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
Is the commit message body attributing the duplicate to the wrong commit?
The body says 6ccf49f79327 ("bpf: Use SCEV to widen bounded loops")
introduced the second definition, but the Fixes: tag names 088a5477a9bd
("bpf: Avoid widening registers that hinder exact stack-slot tracking").
Looking at the history of the macro:
git log -S'define BPF_SCEV_REGS_NUM' -- include/linux/bpf_verifier.h
6ccf49f79327 added the first definition, just before struct bpf_loop_iters,
and that is the one this patch keeps. The definition this patch removes,
just before struct bpf_loop, was added by 088a5477a9bd, which matches the
Fixes: tag but not the prose.
Could the body be reworded along these lines?
The "bpf: Avoid widening registers that hinder exact stack-slot
tracking" commit re-defined BPF_SCEV_REGS_NUM, which was already
defined by "bpf: Use SCEV to widen bounded loops".
This isn't a bug, but the subject says "declaration" while the patch
removes a macro definition. Would "definition" be more accurate there?
---
AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md
CI run summary: https://github.com/kernel-patches/bpf/actions/runs/38118645453
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH bpf-next 5/9] selftests/bpf: static subprogram argument side liveness tests
2026-10-11 6:21 ` [PATCH bpf-next 5/9] selftests/bpf: static subprogram argument side liveness tests Eduard Zingerman
@ 2026-10-11 7:17 ` bot+bpf-ci
0 siblings, 0 replies; 14+ messages in thread
From: bot+bpf-ci @ 2026-10-11 7:17 UTC (permalink / raw)
To: eddyz87, bpf, ast
Cc: andrii, daniel, kernel-team, yonghong.song, eddyz87, ast, andrii,
daniel, martin.lau, eddyz87, yonghong.song, mason, ihor.solodrai
[-- Attachment #1: Type: text/plain, Size: 3279 bytes --]
> selftests/bpf: static subprogram argument side liveness tests
TL;DR: Test-only nit: __btf_func_path() and the new
btf__compute_live_registers.c (including its unused global_two()) may be
unnecessary, since unnamed params on static naked functions should load and
give the same liveness masks.
> diff --git a/tools/testing/selftests/bpf/progs/btf__compute_live_registers.c b/tools/testing/selftests/bpf/progs/btf__compute_live_registers.c
> new file mode 100644
> index 000000000000..b6633fa88030
> --- /dev/null
> +++ b/tools/testing/selftests/bpf/progs/btf__compute_live_registers.c
> @@ -0,0 +1,21 @@
> +// SPDX-License-Identifier: GPL-2.0
> +
> +#include <linux/bpf.h>
> +#include <bpf/bpf_helpers.h>
> +#include "bpf_misc.h"
> +
> +/* Use both parameters so clang keeps them in the static functions' BTF. */
> +static __noinline __used int static_two(int a, int b)
> +{
> + return a + b;
> +}
> +
> +static __noinline __used int static_three(int a, int b)
> +{
> + return a + b;
> +}
> +
> +__noinline __used int global_two(int a, int b)
> +{
> + return a;
> +}
[ ... ]
> @@ -425,10 +437,15 @@ __noinline __used int global_two(int a, int b)
> }
>
> SEC("socket")
> -__log_level(2)
> -/* a static callee reads r1 only, a global callee its declared arguments */
> -__msg("2: .1........ (85) call pc+")
> -__msg("5: .12....... (85) call pc+")
> +__success __log_level(2)
> +__btf_func_path("btf__compute_live_registers.bpf.o")
^^^^
This isn't a bug, but is __btf_func_path() needed for this test?
fixup_btf_from_path() in test_loader.c only rewrites FUNC entries whose
first parameter has no name, and it only does so when the parameter counts
match. It keeps the parameter types from the program's own BTF, so all it
changes is the parameter names.
The liveness code only looks at counts and types: prepare_subprog_args()
sets arg_slot_cnt from btf_proto_slots(), which ignores names. The kernel's
btf_func_check() also accepts unnamed parameters for BTF_FUNC_STATIC
functions, so the BTF from the naked static_two()/static_three() in
compute_live_registers.c should load and give arg_slot_cnt == 2 without the
fixup. That would produce the same .12 and .123 masks.
Also, global_two() in btf__compute_live_registers.c can never be used,
because global_two() in compute_live_registers.c is plain C with named
parameters, so the fixup skips it.
The existing __btf_func_path() users (verifier_stack_arg_order.c,
stack_arg_precision.c) need the fixup because their naked subprograms are
global, and the kernel requires parameter names for global functions.
Could the test drop btf__compute_live_registers.c, or at least the unused
global_two() in it?
> +/*
> + * BTF declares r1 and r2 for each callee. static_two reads only r1,
> + * while static_three also reads r3, so its call must keep all three live.
> + */
> +__msg("2: .12....... (85) call pc+")
> +__msg("5: .123...... (85) call pc+")
> +__msg("8: .12....... (85) call pc+")
> __naked void subprog_declared_args(void)
> {
> asm volatile (
---
AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md
CI run summary: https://github.com/kernel-patches/bpf/actions/runs/38118645453
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH bpf-next 1/9] bpf: static subprogram arguments liveness should use BTF type info
2026-10-11 6:21 ` [PATCH bpf-next 1/9] bpf: static subprogram arguments liveness should use BTF type info Eduard Zingerman
2026-10-11 6:38 ` sashiko-bot
@ 2026-10-11 13:29 ` Alexei Starovoitov
1 sibling, 0 replies; 14+ messages in thread
From: Alexei Starovoitov @ 2026-10-11 13:29 UTC (permalink / raw)
To: Eduard Zingerman, bpf; +Cc: andrii, daniel, kernel-team, yonghong.song
On Sat, Oct 10, 2026 at 11:21 PM Eduard Zingerman <eddyz87@gmail.com> wrote:
> @@ -8829,10 +8828,13 @@ int btf_prepare_func_args(struct bpf_verifier_env *env, int subprog)
> return -EINVAL;
> }
>
> - err = btf_check_arg_slots(log, tname, is_global, slots_used, sub);
> + if (verifier_bug_if(slots_used != sub->arg_slot_cnt, env,
> + "func#%d argument slot count mismatch: %u != %u",
> + subprog, slots_used, sub->arg_slot_cnt))
> + return -EFAULT;
> + err = btf_check_arg_slots(log, tname, is_global, sub->arg_slot_cnt, sub);
> if (err)
> return err;
> - sub->arg_slot_cnt = slots_used;
[...]
> + /* BTF validation guarantees FUNC -> FUNC_PROTO. */
> + t = btf_type_by_id(aux->btf, aux->func_info[i].type_id);
> + t = btf_type_by_id(aux->btf, t->type);
> + env->subprog_info[i].arg_slot_cnt = min_t(u32, btf_proto_slots(aux->btf, t),
> + MAX_BPF_FUNC_ARGS);
Consider the following...
arg_slot_cnt is not only for liveness.
bpf_in_stack_arg_cnt() is derived from it and it has to be in sync
with sub->stack_arg_cnt, which is still set by btf_check_arg_slots() only.
For example:
struct with_ptr { void *p; u64 x; };
static u64 f(int a, int b, int c, int d, struct with_ptr s)
nargs == 5, so the first btf_check_arg_slots() does nothing.
Then btf_prepare_func_args() returns -EINVAL on 's' and
the second btf_check_arg_slots() is not reached.
Before this patch arg_slot_cnt was 5 and r11 + 8 load in f()
was rejected.
Now arg_slot_cnt == 6 and stack_arg_cnt == 0.
The load is accepted, bpf_jit_supports_stack_args() is not checked,
and bpf_out_stack_arg_cnt() returns (u16)(0 - 1).
x86 JIT emits 'sub rsp, 65520' in the prologue of f().
This scenario looks bad enough.
Also btf_arg_slots() returns (size + 7) / 8 for a struct of any size.
BTF has the source signature. The compiler passes 48 byte struct by
reference or promotes its fields, but here it's 6 slots, so
check_outgoing_stack_args() returns -EFAULT and the prog is rejected.
It was loading fine with this subprog marked as unreliable.
Why is this rewrite needed?
prepare_subprog_args() was calling btf_prepare_func_args() for static
subprogs already. When it succeeds arg_slot_cnt is exact.
When it fails the first call marks the subprog as unreliable
regardless of what is in the registers.
So the liveness.c hunk alone should be enough?
The other patches look good.
pw-bot: cr
^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2026-10-11 13:29 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-11 6:21 [PATCH bpf-next 0/9] bpf: follow-up for scalar evolution series Eduard Zingerman
2026-10-11 6:21 ` [PATCH bpf-next 1/9] bpf: static subprogram arguments liveness should use BTF type info Eduard Zingerman
2026-10-11 6:38 ` sashiko-bot
2026-10-11 13:29 ` Alexei Starovoitov
2026-10-11 6:21 ` [PATCH bpf-next 2/9] bpf: more precise stack liveness effects for global func params Eduard Zingerman
2026-10-11 6:21 ` [PATCH bpf-next 3/9] bpf: avoid duplicate declaration for BPF_SCEV_REGS_NUM Eduard Zingerman
2026-10-11 6:55 ` bot+bpf-ci
2026-10-11 6:21 ` [PATCH bpf-next 4/9] bpf: reg_bounds_sync() comment fixup Eduard Zingerman
2026-10-11 6:21 ` [PATCH bpf-next 5/9] selftests/bpf: static subprogram argument side liveness tests Eduard Zingerman
2026-10-11 7:17 ` bot+bpf-ci
2026-10-11 6:21 ` [PATCH bpf-next 6/9] selftests/bpf: stack effects of scalar/dynptr global subprog params Eduard Zingerman
2026-10-11 6:21 ` [PATCH bpf-next 7/9] selftests/bpf: harden __msg pattern for global_callee_btf_arg Eduard Zingerman
2026-10-11 6:21 ` [PATCH bpf-next 8/9] selftests/bpf: harden __msg patterns for step_movsx_bounds_on_line Eduard Zingerman
2026-10-11 6:21 ` [PATCH bpf-next 9/9] selftests/bpf: BPF_F_ANY_ALIGNMENT for byte_array_size_spanning() Eduard Zingerman
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.