From: Eduard Zingerman <eddyz87@gmail.com>
To: bpf@vger.kernel.org, ast@kernel.org
Cc: andrii@kernel.org, daniel@iogearbox.net, martin.lau@linux.dev,
kernel-team@fb.com, yonghong.song@linux.dev, iii@linux.ibm.com,
gimm78064@gmail.com, Eduard Zingerman <eddyz87@gmail.com>
Subject: [PATCH bpf-next v3 4/5] bpf: simplify the bpf_is_reg64()
Date: Sun, 2 Aug 2026 13:24:20 -0700 [thread overview]
Message-ID: <20260802-static-zext-v3-4-3456b2604574@gmail.com> (raw)
In-Reply-To: <20260802-static-zext-v3-0-3456b2604574@gmail.com>
After the previous commit bpf_is_reg64() is only used in a context
where destination register's property is queried, and only for
instructions for which insn_def_regno() >= 0.
Hence, simplify the function by:
- removing unused parameters;
- removing code paths considering BPF_JMP{,32} instructions;
- streamlining the condition expressions.
Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
---
include/linux/bpf_verifier.h | 1 -
kernel/bpf/fixups.c | 51 ++++++++++++++++++++++---
kernel/bpf/verifier.c | 90 --------------------------------------------
3 files changed, 45 insertions(+), 97 deletions(-)
diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h
index 956243547446..39b0db2a4f17 100644
--- a/include/linux/bpf_verifier.h
+++ b/include/linux/bpf_verifier.h
@@ -1626,7 +1626,6 @@ struct bpf_kfunc_desc_tab {
};
/* Functions exported from verifier.c, used by fixups.c */
-bool bpf_is_reg64(struct bpf_insn *insn, u32 regno, struct bpf_reg_state *reg, enum bpf_reg_arg_type t);
void bpf_clear_insn_aux_data(struct bpf_verifier_env *env, int start, int len);
void bpf_mark_subprog_exc_cb(struct bpf_verifier_env *env, int subprog);
bool bpf_allow_tail_call_in_subprogs(struct bpf_verifier_env *env);
diff --git a/kernel/bpf/fixups.c b/kernel/bpf/fixups.c
index 6125598d16a8..7b3510d46b37 100644
--- a/kernel/bpf/fixups.c
+++ b/kernel/bpf/fixups.c
@@ -44,6 +44,49 @@ static int insn_def_regno(const struct bpf_insn *insn)
}
}
+/*
+ * For use only in combination with insn_def_regno() >= 0.
+ * Returns TRUE if the destination register operates on 64-bit,
+ * otherwise return FALSE.
+ */
+static bool bpf_is_reg64(struct bpf_insn *insn)
+{
+ u8 class = BPF_CLASS(insn->code);
+ u8 mode = BPF_MODE(insn->code);
+ u8 size = BPF_SIZE(insn->code);
+ u8 op = BPF_OP(insn->code);
+ bool mode_mem;
+
+ /* subregister endiness swap */
+ if ((class == BPF_ALU || class == BPF_ALU64) && op == BPF_END && insn->imm != 64)
+ return false;
+
+ /* w0 += 1 */
+ if (class == BPF_ALU && op != BPF_END)
+ return false;
+
+ /* cast from as(1) to as(0), PTR_TO_ARENA is 32-bit */
+ if (insn->code == (BPF_ALU64 | BPF_MOV | BPF_X) &&
+ insn->off == BPF_ADDR_SPACE_CAST && insn->imm == 1)
+ return false;
+
+ /* non 64-bit, non signed extended loads */
+ mode_mem = mode == BPF_MEM || mode == BPF_PROBE_MEM || mode == BPF_PROBE_MEM32;
+ if (class == BPF_LDX && mode_mem && size != BPF_DW)
+ return false;
+
+ /* atomics, see insn_def_regno() */
+ if (class == BPF_STX && size != BPF_DW)
+ return false;
+
+ /* both LD_IND and LD_ABS return 32-bit data. */
+ if (class == BPF_LD && (mode == BPF_IND || mode == BPF_ABS))
+ return false;
+
+ /* Conservatively return true at default. */
+ return true;
+}
+
/*
* Return the 32-bit subregister defined by INSN, or -1 if INSN does not
* explicitly define a 32-bit value.
@@ -52,7 +95,7 @@ int bpf_insn_def32(struct bpf_insn *insn)
{
int dst_reg = insn_def_regno(insn);
- if (dst_reg < 0 || bpf_is_reg64(insn, dst_reg, NULL, DST_OP))
+ if (dst_reg < 0 || bpf_is_reg64(insn))
return -1;
return dst_reg;
@@ -619,11 +662,7 @@ int bpf_opt_subreg_zext_lo32_rnd_hi32(struct bpf_verifier_env *env,
if (load_reg == -1)
continue;
- /* NOTE: arg "reg" (the fourth one) is only used for
- * BPF_STX + SRC_OP, so it is safe to pass NULL
- * here.
- */
- if (bpf_is_reg64(&insn, load_reg, NULL, DST_OP)) {
+ if (bpf_is_reg64(&insn)) {
if (class == BPF_LD &&
BPF_MODE(code) == BPF_IMM)
i++;
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index e51cf5238f60..45d4c0a00a5d 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -3027,96 +3027,6 @@ static void mark_stack_slots_scratched(struct bpf_verifier_env *env,
mark_stack_slot_scratched(env, spi - i);
}
-/* This function is supposed to be used by the following 32-bit optimization
- * code only. It returns TRUE if the source or destination register operates
- * on 64-bit, otherwise return FALSE.
- */
-bool bpf_is_reg64(struct bpf_insn *insn,
- u32 regno, struct bpf_reg_state *reg, enum bpf_reg_arg_type t)
-{
- u8 code, class, op;
-
- code = insn->code;
- class = BPF_CLASS(code);
- op = BPF_OP(code);
- if (class == BPF_JMP) {
- /* BPF_EXIT for "main" will reach here. Return TRUE
- * conservatively.
- */
- if (op == BPF_EXIT)
- return true;
- if (op == BPF_CALL) {
- /* BPF to BPF call will reach here because of marking
- * caller saved clobber with DST_OP_NO_MARK for which we
- * don't care the register def because they are anyway
- * marked as NOT_INIT already.
- */
- if (insn->src_reg == BPF_PSEUDO_CALL)
- return false;
- /* Helper call will reach here because of arg type
- * check, conservatively return TRUE.
- */
- if (t == SRC_OP)
- return true;
-
- return false;
- }
- }
-
- if (class == BPF_ALU64 && op == BPF_END && (insn->imm == 16 || insn->imm == 32))
- return false;
-
- if (class == BPF_ALU64 || class == BPF_JMP ||
- (class == BPF_ALU && op == BPF_END && insn->imm == 64))
- return true;
-
- if (class == BPF_ALU || class == BPF_JMP32)
- return false;
-
- if (class == BPF_LDX) {
- if (t != SRC_OP)
- return BPF_SIZE(code) == BPF_DW || BPF_MODE(code) == BPF_MEMSX;
- /* LDX source must be ptr. */
- return true;
- }
-
- if (class == BPF_STX) {
- /* BPF_STX (including atomic variants) has one or more source
- * operands, one of which is a ptr. Check whether the caller is
- * asking about it.
- */
- if (t == SRC_OP && reg->type != SCALAR_VALUE)
- return true;
- return BPF_SIZE(code) == BPF_DW;
- }
-
- if (class == BPF_LD) {
- u8 mode = BPF_MODE(code);
-
- /* LD_IMM64 */
- if (mode == BPF_IMM)
- return true;
-
- /* Both LD_IND and LD_ABS return 32-bit data. */
- if (t != SRC_OP)
- return false;
-
- /* Implicit ctx ptr. */
- if (regno == BPF_REG_6)
- return true;
-
- /* Explicit source could be any width. */
- return true;
- }
-
- if (class == BPF_ST)
- /* The only source register for BPF_ST is a ptr. */
- return true;
-
- /* Conservatively return true at default. */
- return true;
-}
-
static int __check_reg_arg(struct bpf_verifier_env *env, struct bpf_reg_state *regs, u32 regno,
enum bpf_reg_arg_type t)
{
--
2.53.0
next prev parent reply other threads:[~2026-08-02 20:24 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-02 20:24 [PATCH bpf-next v3 0/5] bpf: infer zext_dst based on static register liveness analysis Eduard Zingerman
2026-08-02 20:24 ` [PATCH bpf-next v3 1/5] bpf: do not print a newline after disassembly in bpf_verbose_insn() Eduard Zingerman
2026-08-03 0:22 ` Quentin Monnet
2026-08-02 20:24 ` [PATCH bpf-next v3 2/5] bpf: track upper 32-bit register halves' liveness in compute_live_registers() Eduard Zingerman
2026-08-02 20:24 ` [PATCH bpf-next v3 3/5] bpf: infer zext_dst based on static register liveness analysis Eduard Zingerman
2026-08-02 21:07 ` sashiko-bot
2026-08-02 21:14 ` Eduard Zingerman
2026-08-02 20:24 ` Eduard Zingerman [this message]
2026-08-02 21:26 ` [PATCH bpf-next v3 4/5] bpf: simplify the bpf_is_reg64() sashiko-bot
2026-08-02 21:40 ` Eduard Zingerman
2026-08-02 20:24 ` [PATCH bpf-next v3 5/5] selftests/bpf: verify zext_dst annotations for various instructions Eduard Zingerman
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=20260802-static-zext-v3-4-3456b2604574@gmail.com \
--to=eddyz87@gmail.com \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=gimm78064@gmail.com \
--cc=iii@linux.ibm.com \
--cc=kernel-team@fb.com \
--cc=martin.lau@linux.dev \
--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.