On Fri, 12 Apr 2019 22:59:38 +0100, Jiong Wang wrote: > diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c > index c722015..3c5ca00 100644 > --- a/kernel/bpf/verifier.c > +++ b/kernel/bpf/verifier.c > @@ -1135,7 +1135,7 @@ static int check_subprogs(struct bpf_verifier_env *env) > */ > static int mark_reg_read(struct bpf_verifier_env *env, > const struct bpf_reg_state *state, > - struct bpf_reg_state *parent) > + struct bpf_reg_state *parent, u8 flags) > { > bool writes = parent == state->parent; /* Observe write marks */ > int cnt = 0; > @@ -1150,17 +1150,17 @@ static int mark_reg_read(struct bpf_verifier_env *env, > parent->var_off.value, parent->off); > return -EFAULT; > } > - if (parent->live & REG_LIVE_READ) > + if ((parent->live & REG_LIVE_READ) == flags) > /* The parentage chain never changes and > - * this parent was already marked as LIVE_READ. > + * this parent was already marked with all read bits. No big deal, but I though said you'd modify this patch here... > * There is no need to keep walking the chain again and > - * keep re-marking all parents as LIVE_READ. > + * keep re-marking all parents with reads bits in flags. > * This case happens when the same register is read > * multiple times without writes into it in-between. > */ > break; > /* ... then we depend on parent's value */ > - parent->live |= REG_LIVE_READ; > + parent->live |= flags; > state = parent; > parent = state->parent; > writes = true; > @@ -6227,12 +6317,19 @@ static int propagate_liveness_reg(struct bpf_verifier_env *env, > struct bpf_reg_state *reg, > struct bpf_reg_state *parent_reg) > { > + u8 parent_bits = parent_reg->live & REG_LIVE_READ; > + u8 bits = reg->live & REG_LIVE_READ; > + u8 bits_diff = parent_bits ^ bits; > + u8 bits_prop = bits_diff & bits; > int err; > > - if (parent_reg->live & REG_LIVE_READ || !(reg->live & REG_LIVE_READ)) > + /* "reg" and "parent_reg" has the same read bits, or the bit doesn't > + * belong to "reg". > + */ > + if (!bits_diff || !bits_prop) > return 0; .. and here?