From: Vineet Gupta <vineet.gupta@linux.dev>
To: 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,
Vineet Gupta <vineet.gupta@linux.dev>
Subject: [RFC bpf-next 6/6] selftests/bpf: cover 32-bit sign-extension low-32 links
Date: Fri, 14 Aug 2026 16:19:45 -0700 [thread overview]
Message-ID: <20260814231945.3884596-7-vineet.gupta@linux.dev> (raw)
In-Reply-To: <20260814231945.3884596-1-vineet.gupta@linux.dev>
Tests for the BPF_FLAG_SUBREG_SEXT link, mostly built with the
div-by-zero-guard idiom: the div is unreachable iff the verifier deduces the
sign-extended register is 0, so a missed deduction turns __success into a
"div by zero" rejection.
Deduction through the link:
- sext_linked_low_narrow_to_zero, sext_linked_separate_dest_narrow_to_zero:
in-place and dst != src sign extension narrowed to 0 via the source's low
32 bits. The separate-dest case runs with BPF_F_TEST_STATE_FREQ so the
link has to survive state cleaning.
- sext_narrow_{branch_on_source,copied_back,inplace_pre_copy,spill_fill}:
variants derived from real "R0 ... should have been in [0, 1]" exit
rejections -- branch on source vs dest, copy-back, spill/fill across a
call.
- sext_resext_preserves_range: a redundant re-sext of a value clamped to
[-4095, 0] must keep the tight range (the errno-or-zero return pattern).
In-loop behaviour:
- sext_in_loop_converges: convergence regression test, reproducing the
bytecode bpf-gcc emits for a cond_break loop -- a counter incremented with
an ALU32 add (zero-extending the high half) then sign-extended in place
every iteration. Forming the link refreshes the linked scalar id and
BPF_FLAG_SUBREG_SEXT each iteration, so the loop-carried state never
repeats. It converges only because regsafe() demands a matching low-32
link just when the old state already has one: ~9 insns with that, versus
a load failure at 1,000,001 insns without.
- sext_in_loop_separate_dest_index: the companion case, a fresh in-loop temp
(a bounds-checked array index) that is dead across the back-edge. The link
is formed here too -- there is no liveness or loop-carried exclusion, the
gate is just (sz == 4) -- but because the temp is not loop-carried the link
costs nothing in convergence and simply buys precision: the narrowing
reaches it.
Interaction with the zero-extending link:
- zext_mov_from_sext_src_zero_extends: a 32-bit zero-extending mov (w2 = w1)
whose source is sign-extended (r1 = (s32)r6) must still zero-extend, i.e.
its link must be BPF_FLAG_SUBREG_ZEXT and must not inherit
BPF_FLAG_SUBREG_SEXT from the source. Otherwise sync_linked_regs() rebuilds
the destination with reconstruct_sext32() on a later low-32 narrowing,
computing a negative value for what is really a large positive
zero-extended one. After "if w6 s>= 0" falls through, r6's low 32 bits have
bit 31 set, so the zero-extended r2 is strictly positive and the guarded
div is reachable only on a mis-reconstruction.
Two more cases the earlier tests did not reach:
- sext_mov_keeps_add_const_src: mirror of zext_mov_keeps_add_const_src. A
sext whose source carries an ADD_CONST delta must not destroy that link.
Fails without the ADD_CONST source exclusion in the previous patch.
- sext_dest_driven_does_not_narrow_base: narrows the LINKED register and
requires the wide base is NOT narrowed, i.e. the "known_reg is
subreg-linked" continue in sync_linked_regs(). A __failure test -- the
div must stay reachable. Companion to the zero-extend version added by
the zero-extend selftest patch.
All are written in asm so the bytecode is identical regardless of the host
BPF compiler.
Signed-off-by: Vineet Gupta <vineet.gupta@linux.dev>
---
.../bpf/progs/verifier_linked_scalars.c | 412 ++++++++++++++++++
1 file changed, 412 insertions(+)
diff --git a/tools/testing/selftests/bpf/progs/verifier_linked_scalars.c b/tools/testing/selftests/bpf/progs/verifier_linked_scalars.c
index 2cc6f9e45aff..ff71e168d4cc 100644
--- a/tools/testing/selftests/bpf/progs/verifier_linked_scalars.c
+++ b/tools/testing/selftests/bpf/progs/verifier_linked_scalars.c
@@ -826,4 +826,416 @@ l_out_%=: \
: __clobber_all);
}
+/*
+ * The tests below use the cpuv4 32-bit sign extension (r0 = (s32)r0), so they
+ * need a compiler that can emit it and a JIT that can run it. Same gate as
+ * verifier_movsx.c, except the compiler clause also accepts bpf-gcc, which
+ * does not define __clang_major__ but does define __BPF_FEATURE_MOVSX.
+ *
+ * The tests above do not need cpuv4, so the guard starts here rather than
+ * covering the whole file.
+ */
+#if (defined(__TARGET_ARCH_arm64) || defined(__TARGET_ARCH_x86) || \
+ (defined(__TARGET_ARCH_riscv) && __riscv_xlen == 64) || \
+ defined(__TARGET_ARCH_arm) || defined(__TARGET_ARCH_s390) || \
+ defined(__TARGET_ARCH_loongarch)) && \
+ (__clang_major__ >= 18 || defined(__BPF_FEATURE_MOVSX))
+
+/*
+ * Sign-extension linked-register tracking, in-place narrow-to-zero.
+ *
+ * r1 = r0 ties r0,r1 with a shared id. r0 = (s32)r0 sign-extends r0's low 32
+ * bits; the helper return is a full 64-bit unknown so the sign bit isn't
+ * provably 0, and r0 keeps a BPF_FLAG_SUBREG_SEXT link to r1. On the w1 == 0
+ * fall-through, r1's low 32 bits are 0; r0's low 32 bits equal r1's and r0's
+ * upper bits are the sign-extension of that (0) -- so r0 == 0.
+ *
+ * The guarded div-by-zero is unreachable iff the verifier deduces r0 == 0.
+ */
+SEC("socket")
+__success
+__naked void sext_linked_low_narrow_to_zero(void)
+{
+ asm volatile (" \
+ call %[bpf_get_prandom_u32]; \
+ r1 = r0; /* r1 == r0, shared id */ \
+ r0 = (s32)r0; /* r0 = sext32(r0) */ \
+ if w1 != 0 goto l0_%=; /* fall-through: w1 == 0 */ \
+ /* want deduced here: r0 == 0 */ \
+ if r0 == 0 goto l0_%=; /* always taken iff r0==0 known */ \
+ r0 /= 0; /* unreachable iff r0==0 deduced */ \
+l0_%=: \
+ r0 = 0; \
+ exit; \
+" :
+ : __imm(bpf_get_prandom_u32)
+ : __clobber_all);
+}
+
+/*
+ * Separate-dest sign-extension: r3 = (s32)r2 (dst != src). r2,r3 share a base
+ * id (r3 with BPF_FLAG_SUBREG_SEXT). On the w2 == 0 fall-through, r2's low 32 bits are
+ * 0, so r3 = sext32(0) = 0 and the guarded div-by-zero is unreachable.
+ *
+ * Runs with BPF_F_TEST_STATE_FREQ to force checkpointing between the sext and
+ * the branch: the sext linkage (BPF_FLAG_SUBREG_SEXT) must survive state
+ * cleaning so sync_linked_regs() can still reconstruct r3. bpf_clear_singular_ids()
+ * strips the link flags when counting base ids; otherwise r3's compound id looks
+ * singular and gets cleared, and r3 stays wide.
+ */
+SEC("socket")
+__success
+__flag(BPF_F_TEST_STATE_FREQ)
+__naked void sext_linked_separate_dest_narrow_to_zero(void)
+{
+ asm volatile (" \
+ call %[bpf_get_prandom_u32]; \
+ r2 = r0; /* r2,(r0) linked, id N */ \
+ r3 = (s32)r2; /* r3 = sext32(r2): SEXT link base N */ \
+ if w2 != 0 goto l0_%=; /* fall-through: w2 == 0 */ \
+ /* want deduced here: r3 == 0 */ \
+ if r3 == 0 goto l0_%=; /* always taken iff r3==0 known */ \
+ r0 /= 0; /* unreachable iff r3==0 deduced */ \
+l0_%=: \
+ r0 = 0; \
+ exit; \
+" :
+ : __imm(bpf_get_prandom_u32)
+ : __clobber_all);
+}
+
+/*
+ * Coverage derived from real "R0 ... should have been in [0, 1]" exit
+ * rejections. Each sign-extends a value, then a branch proves its low 32 bits
+ * are 0 so the sext result must be 0. Expressed with the div-by-zero idiom (same
+ * deduced range the return-code check reads): the div is unreachable iff the
+ * verifier deduces the sext register is 0.
+ */
+
+/* 1: branch on the SOURCE reg; separate dest (value stands in for a u32 load). */
+SEC("socket")
+__success
+__naked void sext_narrow_branch_on_source(void)
+{
+ asm volatile (" \
+ call %[bpf_get_prandom_u32]; \
+ r2 = r0; /* r2 = value (proxy for u32 load) */ \
+ r0 = (s32)r2; /* r0 = sext32(r2) */ \
+ if w2 != 0 goto l0_%=; /* w2 != 0: r0 unknown, skip */ \
+ if r0 == 0 goto l0_%=; /* w2 == 0: r0 must be 0 */ \
+ r0 /= 0; \
+l0_%=: \
+ r0 = 0; \
+ exit; \
+" :
+ : __imm(bpf_get_prandom_u32)
+ : __clobber_all);
+}
+
+/* 2: sext into r7, prove via w0, then copy r7 back into r0. */
+SEC("socket")
+__success
+__naked void sext_narrow_copied_back(void)
+{
+ asm volatile (" \
+ call %[bpf_get_prandom_u32]; \
+ r7 = (s32)r0; /* r7 = sext32(r0) */ \
+ if w0 != 0 goto l0_%=; /* w0 != 0: skip */ \
+ r0 = r7; /* w0 == 0: r0 = r7 (must be 0) */ \
+ if r0 == 0 goto l0_%=; \
+ r0 /= 0; \
+l0_%=: \
+ r0 = 0; \
+ exit; \
+" :
+ : __imm(bpf_get_prandom_u32)
+ : __clobber_all);
+}
+
+/* 3: in-place sext; branch on the pre-sext copy r1 (== direction). */
+SEC("socket")
+__success
+__naked void sext_narrow_inplace_pre_copy(void)
+{
+ asm volatile (" \
+ call %[bpf_get_prandom_u32]; \
+ r1 = r0; /* pre-sext copy, linked */ \
+ r0 = (s32)r0; /* in-place sext32 */ \
+ if w1 == 0 goto l_chk_%=;/* w1 == 0: r0 must be 0 */ \
+ goto l0_%=; /* w1 != 0: nothing to check */ \
+l_chk_%=: \
+ if r0 == 0 goto l0_%=; \
+ r0 /= 0; \
+l0_%=: \
+ r0 = 0; \
+ exit; \
+" :
+ : __imm(bpf_get_prandom_u32)
+ : __clobber_all);
+}
+
+/* 4: sext, prove via w0, spill to stack across a call, reload, use. */
+SEC("socket")
+__success
+__naked void sext_narrow_spill_fill(void)
+{
+ asm volatile (" \
+ call %[bpf_get_prandom_u32]; \
+ r9 = (s32)r0; /* r9 = sext32(r0) */ \
+ if w0 != 0 goto l0_%=; /* w0 != 0: skip */ \
+ /* w0 == 0: r9 must be 0 */ \
+ *(u64 *)(r10 - 8) = r9; /* spill r9 */ \
+ call %[bpf_get_prandom_u32];/* clobbers r0-r5 */ \
+ r5 = *(u64 *)(r10 - 8); /* reload -> must be 0 */ \
+ if r5 == 0 goto l0_%=; \
+ r0 /= 0; \
+l0_%=: \
+ r0 = 0; \
+ exit; \
+" :
+ : __imm(bpf_get_prandom_u32)
+ : __clobber_all);
+}
+
+/*
+ * A redundant 32-bit sign-extension of an already-narrowed value must preserve
+ * the range. This is the errno-or-zero return pattern (set_if_not_errno_or_zero()
+ * followed by "return ret" on an int): the value is clamped to [-4095, 0] and
+ * then sign-extended again, e.g. verify_pkcs7_sig / many lsm.s progs under
+ * bpf-gcc. coerce_reg_to_size_sx() bails to the full [S32_MIN, S32_MAX] range
+ * when the range straddles the sign boundary (smin<0, smax>=0), so without the
+ * sext-self reconstruction the final "r0 = (s32)r0" widens [-4095, 0] back to
+ * the full range and the program is rejected. Knowing the high half is the
+ * sign-extension of the low 32 bits lets the verifier rebuild the tight range.
+ */
+SEC("socket")
+__success
+__naked void sext_resext_preserves_range(void)
+{
+ asm volatile (" \
+ call %[bpf_get_prandom_u32]; \
+ r0 = (s32)r0; /* r0 = [S32_MIN, S32_MAX] */ \
+ if r0 s> 0 goto l_out_%=; /* r0 <= 0 */ \
+ if r0 s< -4095 goto l_out_%=; /* r0 in [-4095, 0] */ \
+ r0 = (s32)r0; /* redundant re-sext (pkcs7 pattern) */ \
+ if r0 s>= -4095 goto l_lo_ok_%=;/* must hold if range kept */ \
+ r0 /= 0; /* reached only if lower bound lost */ \
+l_lo_ok_%=: \
+ if r0 s<= 0 goto l_out_%=; /* must hold if range kept */ \
+ r0 /= 0; /* reached only if upper bound lost */ \
+l_out_%=: \
+ r0 = 0; \
+ exit; \
+" :
+ : __imm(bpf_get_prandom_u32)
+ : __clobber_all);
+}
+
+/*
+ * A 32-bit sign-extension INSIDE a loop must verify and converge. This is the
+ * bytecode pattern bpf-gcc emits for a cond_break loop (see cond_break4): a
+ * counter is incremented with an ALU32 add (which zero-extends the high half)
+ * and then sign-extended in place every iteration.
+ *
+ * The verifier links dst<->src on a sign-extension. Doing that for a sext on a
+ * register carried across the loop back-edge mints/refreshes the linked scalar
+ * id and its BPF_FLAG_SUBREG_SEXT metadata each iteration; combined with the
+ * ALU32 add's BPF_FLAG_ADD_CONST delta the loop-carried state never repeats, so state
+ * pruning can't converge and verification runs to the 1M instruction limit.
+ *
+ * The regsafe() guard on the low-32 link flags is what prevents this: it only demands a
+ * match when the OLD state already carries a link (rold->id), so a register that
+ * first picks up a sext link inside the loop can still match its pre-loop state.
+ * Without that guard the loop-carried r2 never matches and the load fails at
+ * 1,000,001 insns, i.e. this __success flips to a load failure -- so this is the
+ * regression test for it. (See sext_in_loop_separate_dest_index for the
+ * companion case, a fresh in-loop temp that keeps its link for precision.)
+ *
+ * The pattern is written in asm so the bytecode is identical regardless of the
+ * host BPF compiler.
+ */
+SEC("socket")
+__success
+__naked void sext_in_loop_converges(void)
+{
+ asm volatile (" \
+ call %[bpf_get_prandom_u32]; \
+ r2 = r0; /* r2 = 64-bit unknown (helper ret) */ \
+l_body_%=: \
+ .byte 0xe5; /* may_goto l_exit (loop bound) */ \
+ .byte 0; \
+ .short 3; \
+ .long 0; \
+ w2 += 1; /* ALU32 add: low += 1, high = 0 */ \
+ r2 = (s32)r2; /* in-place in-loop sign-extend */ \
+ goto l_body_%=; \
+l_exit_%=: \
+ r0 = 0; \
+ exit; \
+" :
+ : __imm(bpf_get_prandom_u32)
+ : __clobber_all);
+}
+
+/*
+ * A separate-destination 32-bit sign extension INSIDE a loop keeps its low-32
+ * link, so a later bounds check on the source narrows the sign-extended
+ * destination too. This is the bytecode a bpf-gcc build emits for array indexing
+ * in a bpf_for loop -- a fresh 32-bit index load, a separate "r1 = (s32)r0",
+ * then a bounds check on the index (verifier_global_subprogs' syscall_array_bpf_for).
+ *
+ * Both in-loop cases form the link -- subreg_link is just (sz == 4), with no
+ * liveness or loop-carried exclusion. What differs is what the link buys. Here
+ * the destination is a fresh temp, dead across the back-edge, so the link is
+ * pure precision: "if w0 > 99" narrows r1 to [0, 99] and the guarded
+ * div-by-zero is unreachable. In sext_in_loop_converges the target is the
+ * loop-carried counter, so the link is re-formed every iteration and the
+ * question is convergence instead -- answered by the regsafe() rold->id guard,
+ * not by declining to link.
+ *
+ * Written in asm so the bytecode is identical regardless of the host BPF
+ * compiler.
+ */
+SEC("socket")
+__success
+__naked void sext_in_loop_separate_dest_index(void)
+{
+ asm volatile (" \
+l_body_%=: \
+ .byte 0xe5; /* may_goto l_exit (loop bound) */ \
+ .byte 0; \
+ .short 7; \
+ .long 0; \
+ call %[bpf_get_prandom_u32];/* r0 = fresh u32 each iter */ \
+ r1 = (s32)r0; /* in-loop separate-dest sext */ \
+ if w0 > 0x63 goto l_body_%=;/* fall-through: w0 <= 99 */ \
+ /* want r1 = sext32(r0 low) == [0, 99] here (needs the link) */ \
+ if r1 > 0x63 goto l_err_%=;/* taken unless r1 narrowed */ \
+ goto l_body_%=; \
+l_err_%=: \
+ r0 /= 0; /* reachable iff r1 not narrowed */ \
+ goto l_body_%=; \
+l_exit_%=: \
+ r0 = 0; \
+ exit; \
+" :
+ : __imm(bpf_get_prandom_u32)
+ : __clobber_all);
+}
+
+/*
+ * A 32-bit zero-extending mov (w2 = w1) whose SOURCE is a sign-extended register
+ * must still zero-extend: dst's high bits are 0, not the sign-extension of the
+ * low field. Regression test for the zext link clearing BPF_FLAG_SUBREG_SEXT (otherwise
+ * dst would inherit SUBREG_SEXT from the sext'd source, and sync_linked_regs()
+ * would later rebuild it with reconstruct_sext32() -- computing a negative value
+ * for what is actually a large positive zero-extended one).
+ *
+ * r1 = (s32)r6 makes r1 a sext-linked wide source; w2 = w1 forms the zext link.
+ * After "if w6 s>= 0" falls through, r6's low 32 bits have bit 31 set, so the
+ * zero-extended r2 must be in [0x80000000, 0xffffffff]. Two guards assert that
+ * whole range, so the test needs the feature present, not merely the absence of
+ * the sext-leak bug: "r2 s< 0" catches the leak (r2 rebuilt negative), and
+ * "w2 s>= 0" catches the low-32 link being absent entirely (r2 not narrowed to
+ * the high half, so bit 31 is not known set). Either makes the div reachable.
+ */
+SEC("socket")
+__success
+__naked void zext_mov_from_sext_src_zero_extends(void)
+{
+ asm volatile (" \
+ call %[bpf_get_prandom_u32]; \
+ r6 = r0; /* r6 low = unknown u32 (callee-saved) */ \
+ call %[bpf_get_prandom_u32]; \
+ r0 <<= 32; \
+ r6 |= r0; /* r6 = full 64-bit unknown (width 64) */ \
+ r1 = (s32)r6; /* r1 = sext32(r6 low): SUBREG_SEXT, wide */ \
+ w2 = w1; /* zext mov from sext-linked wide src */ \
+ if w6 s>= 0 goto l_out_%=;/* fall-through: r6 low has bit 31 set */ \
+ /* r2 = zext32(r6 low) must be in [0x80000000, 0xffffffff]: */ \
+ if r2 s< 0 goto l_err_%=;/* sext leak: r2 wrongly negative */ \
+ if w2 s>= 0 goto l_err_%=;/* link absent: r2 low bit 31 not known set */ \
+ goto l_out_%=; \
+l_err_%=: \
+ r0 /= 0; /* r2 not proven in [0x80000000, 0xffffffff] */ \
+l_out_%=: \
+ r0 = 0; \
+ exit; \
+" :
+ : __imm(bpf_get_prandom_u32)
+ : __clobber_all);
+}
+
+/*
+ * Mirror of zext_mov_keeps_add_const_src for the sign-extending mov: a sext
+ * whose source carries an ADD_CONST delta must not destroy that link.
+ *
+ * Forming a low-32 link calls assign_scalar_id_before_mov(), which clears an
+ * ADD_CONST src, so the sext arm excludes such a source exactly as the zext
+ * arm does. Without that exclusion r5 loses its base+delta relationship to r6
+ * here, "if r6 > 10" no longer narrows r5, and the guarded div becomes
+ * reachable.
+ */
+SEC("socket")
+__success
+__naked void sext_mov_keeps_add_const_src(void)
+{
+ asm volatile (" \
+ call %[bpf_get_prandom_u32]; \
+ r6 = r0; /* r6 low = unknown u32 */ \
+ call %[bpf_get_prandom_u32]; \
+ r0 <<= 32; \
+ r6 |= r0; /* r6 = full 64-bit unknown (base) */ \
+ r5 = r6; /* r5, r6 linked (shared id) */ \
+ r5 += 3; /* r5 = base + 3: ADD_CONST, still wide */ \
+ r7 = (s32)r5; /* 32-bit sext mov, ADD_CONST src */ \
+ if r6 > 10 goto l_out_%=;/* r6 in [0, 10] */ \
+ /* r5 = r6 + 3 must be in [3, 13] here (needs the kept link) */ \
+ if r5 > 13 goto l_err_%=;/* taken only if r5 not narrowed */ \
+ goto l_out_%=; \
+l_err_%=: \
+ r0 /= 0; /* reachable iff r5's link was cleared */ \
+l_out_%=: \
+ r0 = 0; \
+ exit; \
+" :
+ : __imm(bpf_get_prandom_u32)
+ : __clobber_all);
+}
+
+/*
+ * Dest-driven direction, sign-extend flavour: narrowing the LINKED register
+ * must not narrow the wide base.
+ *
+ * r7 = (s32)r6 shares only r6's low 32 bits. Learning r7 == 0 says nothing
+ * about r6's high half, so sync_linked_regs() must leave r6 alone -- that is
+ * the "known_reg is subreg-linked" continue. If it ever propagated, r6 would
+ * be known 0 here and the div would be treated as unreachable, so the program
+ * must be REJECTED.
+ */
+SEC("socket")
+__failure __msg("div by zero")
+__flag(BPF_F_TEST_STATE_FREQ)
+__naked void sext_dest_driven_does_not_narrow_base(void)
+{
+ asm volatile (" \
+ call %[bpf_get_prandom_u32]; \
+ r6 = r0; /* r6 low = unknown u32 */ \
+ call %[bpf_get_prandom_u32]; \
+ r0 <<= 32; \
+ r6 |= r0; /* r6 = full 64-bit unknown (base) */ \
+ r7 = (s32)r6; /* low-32 SEXT link */ \
+ if r7 != 0 goto l_out_%=;/* r7 == 0: low 32 bits are 0 */ \
+ if r6 != 0 goto l_out_%=;/* r6 may still have high bits set */ \
+ r0 /= 0; /* must stay reachable */ \
+l_out_%=: \
+ r0 = 0; \
+ exit; \
+" :
+ : __imm(bpf_get_prandom_u32)
+ : __clobber_all);
+}
+
+#endif /* cpuv4 sign extension */
+
char _license[] SEC("license") = "GPL";
--
2.53.0-Meta
next prev parent reply other threads:[~2026-08-14 23:20 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-14 23:19 [RFC bpf-next 0/6] bpf: track scalar equality across the low 32 bits Vineet Gupta
2026-08-14 23:19 ` [RFC bpf-next 1/6] bpf: turn bpf_reg_state->precise into a flags field [NFC] Vineet Gupta
2026-08-14 23:19 ` [RFC bpf-next 2/6] bpf: move the linked-scalar flags into bpf_reg_state->flags [NFC] Vineet Gupta
2026-08-14 23:34 ` sashiko-bot
2026-08-14 23:19 ` [RFC bpf-next 3/6] bpf: support low-32 subreg scalar linking for zero-extending movs Vineet Gupta
2026-08-14 23:19 ` [RFC bpf-next 4/6] selftests/bpf: cover low-32 subreg-equal link " Vineet Gupta
2026-08-14 23:27 ` sashiko-bot
2026-08-14 23:19 ` [RFC bpf-next 5/6] bpf: support low-32 subreg scalar linking for sign-extending movs Vineet Gupta
2026-08-14 23:19 ` Vineet Gupta [this message]
2026-08-14 23:27 ` [RFC bpf-next 6/6] selftests/bpf: cover 32-bit sign-extension low-32 links sashiko-bot
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=20260814231945.3884596-7-vineet.gupta@linux.dev \
--to=vineet.gupta@linux.dev \
--cc=andrii@kernel.org \
--cc=ast@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@linux.dev \
--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 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.