From: Eduard Zingerman <eddyz87@gmail.com>
To: bpf@vger.kernel.org, ast@kernel.org, andrii@kernel.org
Cc: daniel@iogearbox.net, martin.lau@linux.dev, kernel-team@fb.com,
yonghong.song@linux.dev, eddyz87@gmail.com, memxor@gmail.com,
iii@linux.ibm.com, gimm78064@gmail.com
Subject: [PATCH bpf-next v2 4/5] bpf: simplify the bpf_is_reg64()
Date: Fri, 31 Jul 2026 18:09:52 -0700 [thread overview]
Message-ID: <20260731-static-zext-v2-4-da4aa161e8c5@gmail.com> (raw)
In-Reply-To: <20260731-static-zext-v2-0-da4aa161e8c5@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 | 40 +++++++++++++++++++-
kernel/bpf/verifier.c | 90 --------------------------------------------
3 files changed, 38 insertions(+), 93 deletions(-)
diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h
index 66f506535cbd..2dbbd51cb923 100644
--- a/include/linux/bpf_verifier.h
+++ b/include/linux/bpf_verifier.h
@@ -1628,7 +1628,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..ac0a388b4021 100644
--- a/kernel/bpf/fixups.c
+++ b/kernel/bpf/fixups.c
@@ -44,6 +44,42 @@ 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);
+
+ /* 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;
+
+ /* non 64-bit loads */
+ if (class == BPF_LDX && mode == BPF_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 +88,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;
@@ -623,7 +659,7 @@ int bpf_opt_subreg_zext_lo32_rnd_hi32(struct bpf_verifier_env *env,
* 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 0709dded013e..c3cddaec953b 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.55.0
next prev parent reply other threads:[~2026-08-01 1:10 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-01 1:09 [PATCH bpf-next v2 0/5] bpf: infer zext_dst based on static register liveness analysis Eduard Zingerman
2026-08-01 1:09 ` [PATCH bpf-next v2 1/5] bpf: do not print a newline after disassembly in bpf_verbose_insn() Eduard Zingerman
2026-08-01 1:09 ` [PATCH bpf-next v2 2/5] bpf: track upper 32-bit register halves' liveness in compute_live_registers() Eduard Zingerman
2026-08-01 1:35 ` sashiko-bot
2026-08-01 4:40 ` Eduard Zingerman
2026-08-01 1:09 ` [PATCH bpf-next v2 3/5] bpf: infer zext_dst based on static register liveness analysis Eduard Zingerman
2026-08-01 1:42 ` sashiko-bot
2026-08-01 5:41 ` Eduard Zingerman
2026-08-01 1:09 ` Eduard Zingerman [this message]
2026-08-01 1:34 ` [PATCH bpf-next v2 4/5] bpf: simplify the bpf_is_reg64() sashiko-bot
2026-08-01 1:09 ` [PATCH bpf-next v2 5/5] selftests/bpf: verify zext_dst annotations for various instructions Eduard Zingerman
2026-08-01 1:33 ` sashiko-bot
2026-08-01 4:24 ` 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=20260731-static-zext-v2-4-da4aa161e8c5@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=memxor@gmail.com \
--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