From: Alexei Starovoitov Removal of dead code, the rest of it. Nothing sets the id of a scalar. No prog is verified differently, no line of a log changes. Remove BPF_ADD_CONST*, what prints 'id=N+M', clear_scalar_id(), struct bpf_idset, idset_scratch, tmp_id_gen and the declaration of bpf_clear_singular_ids(). 'delta' was the constant between two scalars with the same id. For a pointer it is always 0, and log.c printed it for pointers only if it was not. Its four bytes stay, as 'unused': they lie between 'type' and a union that is aligned to 8 bytes, and regsafe() and the join compare the bytes before var_off with memcmp(). Padding there has no defined content. Signed-off-by: Alexei Starovoitov --- include/linux/bpf_verifier.h | 46 +++++++----------------------------- kernel/bpf/log.c | 10 ++------ 2 files changed, 10 insertions(+), 46 deletions(-) diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h index 651174144f5f..cee25ec87403 100644 --- a/include/linux/bpf_verifier.h +++ b/include/linux/bpf_verifier.h @@ -60,10 +60,8 @@ struct bpf_stack_range { struct bpf_reg_state { /* Ordering of fields matters. See regsafe() */ enum bpf_reg_type type; - /* - * Constant delta between "linked" scalars with the same ID. - */ - s32 delta; + /* 0. regsafe() compares the bytes before var_off: there is no hole among them. */ + u32 unused; union { /* valid when type == PTR_TO_PACKET */ int range; @@ -179,18 +177,9 @@ struct bpf_reg_state { * the dynptr to determine proper reference freeing. * Similarly to dynptrs, we use ID to track "belonging" of a reference * to a specific instance of bpf_iter. + * A scalar has no id. The scalars that it is linked to are static: computed before the + * main pass, see bpf_scev_next_linked_reg(). */ - /* - * Upper bit of ID is used to remember relationship between "linked" - * registers. Example: - * r1 = r2; both will have r1->id == r2->id == N - * r1 += 10; r1->id == N | BPF_ADD_CONST and r1->delta == 10 - * r3 = r2; both will have r3->id == r2->id == N - * w3 += 10; r3->id == N | BPF_ADD_CONST32 and r3->delta == 10 - */ -#define BPF_ADD_CONST64 (1U << 31) -#define BPF_ADD_CONST32 (1U << 30) -#define BPF_ADD_CONST (BPF_ADD_CONST64 | BPF_ADD_CONST32) u32 id; /* * Tracks the parent object this register was derived from. @@ -1112,27 +1101,18 @@ struct bpf_id_pair { * comes out for it, only if the same places have the same names. * - bpf_flow_return() puts the ids of the call that waits back. All other ids get new values. * - What comes out has the ranges of all calls that share the state at the entry. So a name is good - * for what holds whatever the ranges are: the same object. Other ids have no name: a number - * loses its id, any other argument keeps the frames of the caller, see arg_needs_caller(). - * - env->id_gen stays below BPF_MAX_ID. So no id is a name or has a bit of BPF_ADD_CONST. + * for what holds whatever the ranges are: the same object. Other ids have no name: such an + * argument keeps the frames of the caller, see arg_needs_caller(). + * - env->id_gen stays below BPF_MAX_ID. So no id is a name. */ #define BPF_INHERITED_ID 0x20000000 #define BPF_MAX_ID (BPF_INHERITED_ID / 2) struct bpf_idmap { - u32 tmp_id_gen; u32 cnt; struct bpf_id_pair map[BPF_ID_MAP_SIZE]; }; -struct bpf_idset { - u32 num_ids; - struct { - u32 id; - u32 cnt; - } entries[BPF_ID_MAP_SIZE]; -}; - struct bpf_liveness; struct scev; @@ -1278,10 +1258,7 @@ struct bpf_verifier_env { * via callx. Allocated when the first such edge is recorded. */ unsigned long *callx_edges; - union { - struct bpf_idmap idmap_scratch; - struct bpf_idset idset_scratch; - }; + struct bpf_idmap idmap_scratch; struct { int *insn_state; int *insn_stack; @@ -1447,12 +1424,6 @@ void bpf_verbose_snum32(struct bpf_verifier_env *env, s32 num); bpf_log(&env->log, "verifier bug: " fmt "\n", ##args); \ }) -static inline void clear_scalar_id(struct bpf_reg_state *reg) -{ - reg->id = 0; - reg->delta = 0; -} - static inline void mark_calls_callback(struct bpf_verifier_env *env, int idx) { env->insn_aux_data[idx].calls_callback = true; @@ -1589,7 +1560,6 @@ void bpf_mark_reg_not_init(const struct bpf_verifier_env *env, void bpf_mark_reg_known_scalar(struct bpf_reg_state *reg, u64 imm); void bpf_mark_reg_unknown(struct bpf_reg_state *reg); int bpf_grow_stack_state(struct bpf_verifier_env *env, struct bpf_func_state *state, int size); -void bpf_clear_singular_ids(struct bpf_verifier_env *env, struct bpf_verifier_state *st); static inline int bpf_get_spi(s32 off) { diff --git a/kernel/bpf/log.c b/kernel/bpf/log.c index 84659a757b43..ffbec587a916 100644 --- a/kernel/bpf/log.c +++ b/kernel/bpf/log.c @@ -696,7 +696,7 @@ static void print_reg_state(struct bpf_verifier_env *env, if (state->frameno != reg->frameno) verbose(env, "[%d]", reg->frameno); if (tnum_is_const(reg->var_off)) { - bpf_verbose_snum(env, reg->var_off.value + reg->delta); + bpf_verbose_snum(env, reg->var_off.value); return; } } @@ -704,9 +704,7 @@ static void print_reg_state(struct bpf_verifier_env *env, verbose(env, "%s", btf_type_name(reg->btf, reg->btf_id)); verbose(env, "("); if (reg->id) - verbose_a("id=%d", reg->id & ~BPF_ADD_CONST); - if (reg->id & BPF_ADD_CONST) - verbose(env, "%+d", reg->delta); + verbose_a("id=%d", reg->id); if (reg->parent_id) verbose_a("parent_id=%d", reg->parent_id); if (type_is_non_owning_ref(reg->type)) @@ -720,10 +718,6 @@ static void print_reg_state(struct bpf_verifier_env *env, reg->map_ptr->key_size, reg->map_ptr->value_size); } - if (t != SCALAR_VALUE && reg->delta) { - verbose_a("off="); - bpf_verbose_snum(env, reg->delta); - } if (type_is_pkt_pointer(t)) { verbose_a("r="); verbose_unum(env, reg->range); -- 2.55.0