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.
Unified · Split
| @@ -64,95 +64,43 @@ static int insn_def_regno(const struct bpf_insn *insn) · 63 unmodified lines | ||
| 64 | 64 | } |
| 65 | 65 | } |
| 66 | 66 | |
| 67 | −/* This function is supposed to be used by the zero extension optimization | |
| 68 | − * code only. It returns TRUE if the source or destination register operates | |
| 69 | − * on 64-bit, otherwise return FALSE. | |
| 67 | +/* | |
| 68 | + * For use only in combination with insn_def_regno() >= 0. | |
| 69 | + * Returns TRUE if the destination register operates on 64-bit, | |
| 70 | + * otherwise return FALSE. | |
| 70 | 71 | */ |
| 71 | −static bool bpf_is_reg64(struct bpf_prog *prog, struct bpf_insn *insn, | |
| 72 | − u32 regno, struct bpf_reg_state *reg, enum bpf_reg_arg_type t) | |
| 72 | +static bool bpf_is_reg64(struct bpf_prog *prog, struct bpf_insn *insn) | |
| 73 | 73 | { |
| 74 | − u8 code, class, op; | |
| 75 | − | |
| 76 | − code = insn->code; | |
| 77 | − class = BPF_CLASS(code); | |
| 78 | − op = BPF_OP(code); | |
| 79 | − if (class == BPF_JMP) { | |
| 80 | − /* BPF_EXIT for "main" will reach here. Return TRUE | |
| 81 | − * conservatively. | |
| 82 | − */ | |
| 83 | − if (op == BPF_EXIT) | |
| 84 | − return true; | |
| 85 | − if (op == BPF_CALL) { | |
| 86 | − /* BPF to BPF call will reach here because of marking | |
| 87 | − * caller saved clobber with DST_OP_NO_MARK for which we | |
| 88 | − * don't care the register def because they are anyway | |
| 89 | − * marked as NOT_INIT already. | |
| 90 | − */ | |
| 91 | − if (insn->src_reg == BPF_PSEUDO_CALL) | |
| 92 | − return false; | |
| 93 | − /* Helper call will reach here because of arg type | |
| 94 | − * check, conservatively return TRUE. | |
| 95 | − */ | |
| 96 | − if (t == SRC_OP) | |
| 97 | − return true; | |
| 98 | − | |
| 99 | − return false; | |
| 100 | − } | |
| 101 | − } | |
| 74 | + u8 class = BPF_CLASS(insn->code); | |
| 75 | + u8 mode = BPF_MODE(insn->code); | |
| 76 | + u8 size = BPF_SIZE(insn->code); | |
| 77 | + u8 op = BPF_OP(insn->code); | |
| 78 | + bool mode_mem; | |
| 79 | + | |
| 80 | + /* subregister endiness swap */ | |
| 81 | + if ((class == BPF_ALU || class == BPF_ALU64) && op == BPF_END && insn->imm != 64) | |
| 82 | + return false; | |
| 102 | 83 | |
| 103 | − if (class == BPF_ALU64 && op == BPF_END && (insn->imm == 16 || insn->imm == 32)) | |
| 84 | + /* w0 += 1 */ | |
| 85 | + if (class == BPF_ALU && op != BPF_END) | |
| 104 | 86 | return false; |
| 105 | 87 | |
| 106 | 88 | /* address space casts converted to BPF_ALU, see bpf_do_misc_fixups() */ |
| 107 | 89 | if (is_addr_space_cast32(prog, insn)) |
| 108 | 90 | return false; |
| 109 | 91 | |
| 110 | − if (class == BPF_ALU64 || class == BPF_JMP || | |
| 111 | − (class == BPF_ALU && op == BPF_END && insn->imm == 64)) | |
| 112 | − return true; | |
| 113 | − | |
| 114 | − if (class == BPF_ALU || class == BPF_JMP32) | |
| 92 | + /* non 64-bit, non signed extended loads */ | |
| 93 | + mode_mem = mode == BPF_MEM || mode == BPF_PROBE_MEM || mode == BPF_PROBE_MEM32; | |
| 94 | + if (class == BPF_LDX && mode_mem && size != BPF_DW) | |
| 115 | 95 | return false; |
| 116 | 96 | |
| 117 | − if (class == BPF_LDX) { | |
| 118 | − if (t != SRC_OP) | |
| 119 | − return BPF_SIZE(code) == BPF_DW || BPF_MODE(code) == BPF_MEMSX; | |
| 120 | − /* LDX source must be ptr. */ | |
| 121 | − return true; | |
| 122 | − } | |
| 123 | − | |
| 124 | − if (class == BPF_STX) { | |
| 125 | − /* BPF_STX (including atomic variants) has one or more source | |
| 126 | − * operands, one of which is a ptr. Check whether the caller is | |
| 127 | − * asking about it. | |
| 128 | − */ | |
| 129 | − if (t == SRC_OP && reg->type != SCALAR_VALUE) | |
| 130 | − return true; | |
| 131 | − return BPF_SIZE(code) == BPF_DW; | |
| 132 | − } | |
| 133 | − | |
| 134 | − if (class == BPF_LD) { | |
| 135 | − u8 mode = BPF_MODE(code); | |
| 136 | − | |
| 137 | − /* LD_IMM64 */ | |
| 138 | − if (mode == BPF_IMM) | |
| 139 | − return true; | |
| 140 | − | |
| 141 | − /* Both LD_IND and LD_ABS return 32-bit data. */ | |
| 142 | − if (t != SRC_OP) | |
| 143 | − return false; | |
| 144 | − | |
| 145 | − /* Implicit ctx ptr. */ | |
| 146 | − if (regno == BPF_REG_6) | |
| 147 | − return true; | |
| 148 | − | |
| 149 | − /* Explicit source could be any width. */ | |
| 150 | − return true; | |
| 151 | − } | |
| 97 | + /* atomics, see insn_def_regno() */ | |
| 98 | + if (class == BPF_STX && size != BPF_DW) | |
| 99 | + return false; | |
| 152 | 100 | |
| 153 | − if (class == BPF_ST) | |
| 154 | − /* The only source register for BPF_ST is a ptr. */ | |
| 155 | − return true; | |
| 101 | + /* both LD_IND and LD_ABS return 32-bit data. */ | |
| 102 | + if (class == BPF_LD && (mode == BPF_IND || mode == BPF_ABS)) | |
| 103 | + return false; | |
| 156 | 104 | |
| 157 | 105 | /* Conservatively return true at default. */ |
| 158 | 106 | return true; |
| @@ -166,7 +114,7 @@ int bpf_insn_def32(struct bpf_prog *prog, struct bpf_insn *insn) · 7 unmodified lines | ||
| 166 | 114 | { |
| 167 | 115 | int dst_reg = insn_def_regno(insn); |
| 168 | 116 | |
| 169 | − if (dst_reg < 0 || bpf_is_reg64(prog, insn, dst_reg, NULL, DST_OP)) | |
| 117 | + if (dst_reg < 0 || bpf_is_reg64(prog, insn)) | |
| 170 | 118 | return -1; |
| 171 | 119 | |
| 172 | 120 | return dst_reg; |
| @@ -733,11 +681,7 @@ int bpf_opt_subreg_zext_lo32_rnd_hi32(struct bpf_verifier_env *env, · 560 unmodified lines | ||
| 733 | 681 | if (load_reg == -1) |
| 734 | 682 | continue; |
| 735 | 683 | |
| 736 | − /* NOTE: arg "reg" (the fourth one) is only used for | |
| 737 | − * BPF_STX + SRC_OP, so it is safe to pass NULL | |
| 738 | − * here. | |
| 739 | − */ | |
| 740 | − if (bpf_is_reg64(env->prog, &insn, load_reg, NULL, DST_OP)) { | |
| 684 | + if (bpf_is_reg64(env->prog, &insn)) { | |
| 741 | 685 | if (class == BPF_LD && |
| 742 | 686 | BPF_MODE(code) == BPF_IMM) |
| 743 | 687 | i++; |