From 899cbaae6e4c6f0a1dee01426b53e71c58d396c4 Mon Sep 17 00:00:00 2001 From: Eduard Zingerman Date: Mon, 26 Oct 2026 16:38:26 -0700 Subject: [PATCH] bpf: Print 32-bit SCEV bounds as 32-bit numbers - Print large 32-bit bounds without sign extension. - Omit 32-bit bounds when they coincide with 64-bit bounds. Before: loop header at ..., widening r0 to 0x80000000..0xffffffff (s32 0xffffffff80000000..-1) step 1 loop header at ..., widening r0 to 0..3 (s32 0..3) step 1 After: loop header at ..., widening r0 to 0x80000000..0xffffffff (s32 0x80000000..-1) step 1 loop header at ..., widening r0 to 0..3 step 1 Signed-off-by: Eduard Zingerman Signed-off-by: Alexei Starovoitov Link: https://patch.msgid.link/20261026-scev-simpler-clamp-v2-6-f373aec9825f@gmail.com --- include/linux/bpf_verifier.h | 1 + kernel/bpf/log.c | 8 ++++++++ kernel/bpf/scev.c | 8 +++++--- tools/testing/selftests/bpf/progs/verifier_scev.c | 2 +- 4 files changed, 15 insertions(+), 4 deletions(-) diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h index 5926f13ff43c..e51984cb3035 100644 --- a/include/linux/bpf_verifier.h +++ b/include/linux/bpf_verifier.h @@ -1280,6 +1280,7 @@ __printf(3, 4) void verbose_linfo(struct bpf_verifier_env *env, u32 insn_off, const char *prefix_fmt, ...); void bpf_verbose_snum(struct bpf_verifier_env *env, s64 num); +void bpf_verbose_snum32(struct bpf_verifier_env *env, s32 num); #define verifier_bug_if(cond, env, fmt, args...) \ ({ \ diff --git a/kernel/bpf/log.c b/kernel/bpf/log.c index 5432c0fc442b..fa29d9b994e4 100644 --- a/kernel/bpf/log.c +++ b/kernel/bpf/log.c @@ -535,6 +535,14 @@ void bpf_verbose_snum(struct bpf_verifier_env *env, s64 num) verbose(env, "%#llx", num); } +void bpf_verbose_snum32(struct bpf_verifier_env *env, s32 num) +{ + if (is_snum_decimal(num)) + verbose(env, "%d", num); + else + verbose(env, "%#x", (u32)num); +} + int tnum_strn(char *str, size_t size, struct tnum a) { /* print as a constant, if tnum is fully known */ diff --git a/kernel/bpf/scev.c b/kernel/bpf/scev.c index 12b147faa32a..04d4962448e2 100644 --- a/kernel/bpf/scev.c +++ b/kernel/bpf/scev.c @@ -2456,11 +2456,13 @@ static void log_bounds(struct bpf_verifier_env *env, const struct bounds *bounds bpf_verbose_snum(env, cnum64_smin(bounds->r64)); bpf_log(log, ".."); bpf_verbose_snum(env, cnum64_smax(bounds->r64)); - if (bounds->r32.size < U32_MAX) { + if (bounds->r32.size < U32_MAX && + (cnum32_smin(bounds->r32) != cnum64_smin(bounds->r64) || + cnum32_smax(bounds->r32) != cnum64_smax(bounds->r64))) { bpf_log(log, " (s32 "); - bpf_verbose_snum(env, cnum32_smin(bounds->r32)); + bpf_verbose_snum32(env, cnum32_smin(bounds->r32)); bpf_log(log, ".."); - bpf_verbose_snum(env, cnum32_smax(bounds->r32)); + bpf_verbose_snum32(env, cnum32_smax(bounds->r32)); bpf_log(log, ")"); } bpf_log(log, " step %u", bounds->step); diff --git a/tools/testing/selftests/bpf/progs/verifier_scev.c b/tools/testing/selftests/bpf/progs/verifier_scev.c index 9074b2f043d4..2103c58cfaad 100644 --- a/tools/testing/selftests/bpf/progs/verifier_scev.c +++ b/tools/testing/selftests/bpf/progs/verifier_scev.c @@ -1771,7 +1771,7 @@ __success __log_level(2) __flag(BPF_F_TEST_STATE_FREQ) __msg("loop header at 1, header_count is 4") -__msg("loop header at 1, widening r0 to 0..3 (s32 0..3) step 1") +__msg("loop header at 1, widening r0 to 0..3 step 1") __msg("loop header at 1, clamping r0") __msg("4: R0=3") __naked void pre_cond_je32(void)