BPF List
 help / color / mirror / Atom feed
From: Vineet Gupta <vineet.gupta@linux.dev>
To: bot+bpf-ci@kernel.org, ast@kernel.org, daniel@iogearbox.net,
	andrii@kernel.org, eddyz87@gmail.com, memxor@gmail.com
Cc: martin.lau@linux.dev, song@kernel.org, yonghong.song@linux.dev,
	jolsa@kernel.org, emil@etsalapatis.com, ihor.solodrai@linux.dev,
	john.fastabend@gmail.com, shuah@kernel.org, bpf@vger.kernel.org,
	linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org,
	martin.lau@kernel.org, mason@kernel.org
Subject: Re: [PATCH bpf-next v3 04/12] bpf: Track low-32 scalar equality across zero-extending movs
Date: Mon, 26 Oct 2026 13:30:42 -0700	[thread overview]
Message-ID: <b9fb702d-9782-44b7-803a-26a00fc4206e@linux.dev> (raw)
In-Reply-To: <d6b900be6e27a2ab0ff198e30d28c0d35410daa23bf03ead13a359569f9bfdd9@mail.kernel.org>

On 10/20/26 10:09 AM, bot+bpf-ci@kernel.org wrote:
>> bpf: Track low-32 scalar equality across zero-extending movs
> TL;DR: The comment and changelog claim a zero delta from an add is refused
> composition, but a 32-bit add of known zero records the same link as the mov
> and composes. Behaviour is sound; the explanation looks inaccurate.
>> @@ -17594,11 +17584,28 @@ static int adjust_reg_min_max_vals(struct bpf_verifier_env *env,
>>
>>   		if (dst_reg->link_kind) {
>>   			/*
>> -			 * If the register already went through rX += val
>> -			 * we cannot accumulate another val into rx->off.
>> +			 * Only the zero-extending link the mov above records,
>> +			 * BPF_REG_LINK_ZEXT with delta 0, can take a delta:
>> +			 * (u32)((u32)(base + 0) + off) is (u32)(base + off).
>> +			 * The add has to be 32-bit as well, since a 64-bit one
>> +			 * parts company with the link once the low half wraps.
>> +			 *
>> +			 * Everything else still drops the link. A zero delta
>> +			 * reached by an add rather than by the mov, say "r1 +=
>> +			 * r3" with r3 known to be 0, has already spent its
>> +			 * delta; composing onto it keeps a link alive across a
>> +			 * loop's increments, and since the delta is compared
>> +			 * for equality, every value the loop reaches becomes a
>> +			 * state of its own and stops pruning.
>>   			 */
>> +			if (dst_reg->link_kind != BPF_REG_LINK_ZEXT || !alu32 ||
>> +			    dst_reg->delta) {
>> +				/* also the target of the two gotos above */
>>   clear_id:
>> -			bpf_clear_scalar_id(dst_reg);
>> +				bpf_clear_scalar_id(dst_reg);
>> +			} else {
>> +				dst_reg->delta = off;
>> +			}
>>   		} else {
>>   			if (alu32)
>>   				dst_reg->link_kind = BPF_REG_LINK_ZEXT;
> The comment says a zero delta "reached by an add rather than by the mov"
> has already spent its delta, and the commit message says allowing
> composition onto "a zero delta that an add produced rather than the mov
> still costs 1176 -> 1196".  Can this test actually tell the two apart?

Comment is wrong, fixed in v4.

Walking it through to confirm your reading: a 32-bit add on a register 
that has an id but no kind takes the else arm,

     } else {
         if (alu32)
             dst_reg->link_kind = BPF_REG_LINK_ZEXT;
         else
             dst_reg->link_kind = BPF_REG_LINK_FULL;
         dst_reg->delta = off;
     }

so "w1 += 0" records exactly what the mov records, ZEXT with delta 0, 
and a following "w1 += 1" composes onto it.

The example the comment gives, "r1 += r3", is 64-bit, records 
BPF_REG_LINK_FULL, and is refused for being full link rather than for 
having spent a delta.

The behaviour is sound: (u32)((u32)(base + 0) + off) is (u32)(base + 
off) whichever instruction produced the zero. What is actually refused 
is a *second* delta, and that is what the comment now says.


> A 32-bit add or sub of a known zero ("w1 += 0", "w1 -= 0", or "w1 += w3"
> with w3 known to be 0) on a register that has an id but no link_kind goes
> through the else arm quoted above and records:
>
>      dst_reg->link_kind = BPF_REG_LINK_ZEXT;
>      dst_reg->delta = off;    /* off == 0 */
>
> That is the same state the mov records, so a following "w1 += 1" passes the
> "dst_reg->link_kind != BPF_REG_LINK_ZEXT || !alu32 || dst_reg->delta" test
> and composes.
>
> Only the 64-bit example from the comment ("r1 += r3", which records
> BPF_REG_LINK_FULL) is actually refused.
>
> The result is still sound, since (u32)((u32)(base + 0) + off) is
> (u32)(base + off).  Should the comment and the changelog limit the claim to
> 64-bit adds, or does the mov-produced link need to be made distinguishable
> from the add-produced one?

Former. Composing is already capped at one so comment says second delta 
is refused.

Thx,
-Vineet

>
>
> ---
> 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/39458500836


  reply	other threads:[~2026-10-26 20:30 UTC|newest]

Thread overview: 35+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-20 16:18 [PATCH bpf-next v3 00/12] bpf: track scalar equality across the low 32 bits Vineet Gupta
2026-10-20 16:18 ` [PATCH bpf-next v3 01/12] bpf: Keep the 32-bit range across a sign extension that cannot change it Vineet Gupta
2026-10-20 16:18 ` [PATCH bpf-next v3 02/12] selftests/bpf: Cover sign extensions that cannot change the range Vineet Gupta
2026-10-20 16:18 ` [PATCH bpf-next v3 03/12] bpf: Prepare linked scalars for relations narrower than 64 bits Vineet Gupta
2026-10-20 17:08   ` bot+bpf-ci
2026-10-26 22:52     ` Vineet Gupta
2026-10-20 16:18 ` [PATCH bpf-next v3 04/12] bpf: Track low-32 scalar equality across zero-extending movs Vineet Gupta
2026-10-20 16:39   ` sashiko-bot
2026-10-26 23:06     ` Vineet Gupta
2026-10-20 17:09   ` bot+bpf-ci
2026-10-26 20:30     ` Vineet Gupta [this message]
2026-10-20 16:19 ` [PATCH bpf-next v3 05/12] selftests/bpf: Cover the low-32 link for " Vineet Gupta
2026-10-20 16:53   ` bot+bpf-ci
2026-10-26 18:36     ` Vineet Gupta
2026-10-20 16:19 ` [PATCH bpf-next v3 06/12] bpf: Track low-32 scalar equality across sign-extending movs Vineet Gupta
2026-10-20 16:57   ` sashiko-bot
2026-10-26 20:46     ` Vineet Gupta
2026-10-20 16:19 ` [PATCH bpf-next v3 07/12] selftests/bpf: Cover the low-32 link for " Vineet Gupta
2026-10-20 16:19 ` [PATCH bpf-next v3 08/12] bpf: Recover the low 32 bits on the reverse link direction Vineet Gupta
2026-10-20 16:53   ` bot+bpf-ci
2026-10-26 19:57     ` Vineet Gupta
2026-10-20 17:20   ` sashiko-bot
2026-10-26 21:28     ` Vineet Gupta
2026-10-20 16:19 ` [PATCH bpf-next v3 09/12] bpf: Track low-32 scalar equality across narrowing stack fills Vineet Gupta
2026-10-20 16:19 ` [PATCH bpf-next v3 10/12] selftests/bpf: Cover the low-32 link for " Vineet Gupta
2026-10-20 16:29   ` sashiko-bot
2026-10-20 17:15     ` Vineet Gupta
2026-10-20 16:52   ` bot+bpf-ci
2026-10-26 20:21     ` Vineet Gupta
2026-10-20 16:19 ` [PATCH bpf-next v3 11/12] [do not merge] bpf: Track low-32 scalar equality across narrowing stack spills Vineet Gupta
2026-10-20 16:42   ` sashiko-bot
2026-10-26 21:51     ` Vineet Gupta
2026-10-20 16:19 ` [PATCH bpf-next v3 12/12] [do not merge] selftests/bpf: Cover the low-32 link for " Vineet Gupta
2026-10-20 16:32   ` sashiko-bot
2026-10-26 22:01     ` Vineet Gupta

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=b9fb702d-9782-44b7-803a-26a00fc4206e@linux.dev \
    --to=vineet.gupta@linux.dev \
    --cc=andrii@kernel.org \
    --cc=ast@kernel.org \
    --cc=bot+bpf-ci@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=eddyz87@gmail.com \
    --cc=emil@etsalapatis.com \
    --cc=ihor.solodrai@linux.dev \
    --cc=john.fastabend@gmail.com \
    --cc=jolsa@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-kselftest@vger.kernel.org \
    --cc=martin.lau@kernel.org \
    --cc=martin.lau@linux.dev \
    --cc=mason@kernel.org \
    --cc=memxor@gmail.com \
    --cc=shuah@kernel.org \
    --cc=song@kernel.org \
    --cc=yonghong.song@linux.dev \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox