bpf: move is_branch_taken() down
authorAndrii Nakryiko <andrii@kernel.org>
Thu, 2 Nov 2023 03:37:55 +0000 (20:37 -0700)
committerAlexei Starovoitov <ast@kernel.org>
Fri, 10 Nov 2023 02:58:39 +0000 (18:58 -0800)
Move is_branch_taken() slightly down. In subsequent patched we'll need
both flip_opcode() and is_pkt_ptr_branch_taken() for is_branch_taken(),
but instead of sprinkling forward declarations around, it makes more
sense to move is_branch_taken() lower below is_pkt_ptr_branch_taken(),
and also keep it closer to very tightly related reg_set_min_max(), as
they are two critical parts of the same SCALAR range tracking logic.

Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Link: https://lore.kernel.org/r/20231102033759.2541186-14-andrii@kernel.org
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
kernel/bpf/verifier.c

index 79d01445093bb6f52a5540a2baa87e066a126e8f..414a7c58b4a45345cd6372cf9ff779b4883dd2b6 100644 (file)
@@ -14358,48 +14358,6 @@ static int is_branch64_taken(struct bpf_reg_state *reg1, struct bpf_reg_state *r
        return -1;
 }
 
-/* compute branch direction of the expression "if (<reg1> opcode <reg2>) goto target;"
- * and return:
- *  1 - branch will be taken and "goto target" will be executed
- *  0 - branch will not be taken and fall-through to next insn
- * -1 - unknown. Example: "if (reg1 < 5)" is unknown when register value
- *      range [0,10]
- */
-static int is_branch_taken(struct bpf_reg_state *reg1, struct bpf_reg_state *reg2,
-                          u8 opcode, bool is_jmp32)
-{
-       struct tnum reg2_tnum = is_jmp32 ? tnum_subreg(reg2->var_off) : reg2->var_off;
-       u64 val;
-
-       if (!tnum_is_const(reg2_tnum))
-               return -1;
-       val = reg2_tnum.value;
-
-       if (__is_pointer_value(false, reg1)) {
-               if (!reg_not_null(reg1))
-                       return -1;
-
-               /* If pointer is valid tests against zero will fail so we can
-                * use this to direct branch taken.
-                */
-               if (val != 0)
-                       return -1;
-
-               switch (opcode) {
-               case BPF_JEQ:
-                       return 0;
-               case BPF_JNE:
-                       return 1;
-               default:
-                       return -1;
-               }
-       }
-
-       if (is_jmp32)
-               return is_branch32_taken(reg1, reg2, opcode);
-       return is_branch64_taken(reg1, reg2, opcode);
-}
-
 static int flip_opcode(u32 opcode)
 {
        /* How can we transform "a <op> b" into "b <op> a"? */
@@ -14461,6 +14419,48 @@ static int is_pkt_ptr_branch_taken(struct bpf_reg_state *dst_reg,
        return -1;
 }
 
+/* compute branch direction of the expression "if (<reg1> opcode <reg2>) goto target;"
+ * and return:
+ *  1 - branch will be taken and "goto target" will be executed
+ *  0 - branch will not be taken and fall-through to next insn
+ * -1 - unknown. Example: "if (reg1 < 5)" is unknown when register value
+ *      range [0,10]
+ */
+static int is_branch_taken(struct bpf_reg_state *reg1, struct bpf_reg_state *reg2,
+                          u8 opcode, bool is_jmp32)
+{
+       struct tnum reg2_tnum = is_jmp32 ? tnum_subreg(reg2->var_off) : reg2->var_off;
+       u64 val;
+
+       if (!tnum_is_const(reg2_tnum))
+               return -1;
+       val = reg2_tnum.value;
+
+       if (__is_pointer_value(false, reg1)) {
+               if (!reg_not_null(reg1))
+                       return -1;
+
+               /* If pointer is valid tests against zero will fail so we can
+                * use this to direct branch taken.
+                */
+               if (val != 0)
+                       return -1;
+
+               switch (opcode) {
+               case BPF_JEQ:
+                       return 0;
+               case BPF_JNE:
+                       return 1;
+               default:
+                       return -1;
+               }
+       }
+
+       if (is_jmp32)
+               return is_branch32_taken(reg1, reg2, opcode);
+       return is_branch64_taken(reg1, reg2, opcode);
+}
+
 /* Adjusts the register min/max values in the case that the dst_reg is the
  * variable register that we are working on, and src_reg is a constant or we're
  * simply doing a BPF_K check.