}
 }
 
-static int __mark_chain_precision(struct bpf_verifier_env *env, int regno,
+static int __mark_chain_precision(struct bpf_verifier_env *env, int frame, int regno,
                                  int spi)
 {
        struct bpf_verifier_state *st = env->cur_state;
        if (!env->bpf_capable)
                return 0;
 
-       func = st->frame[st->curframe];
+       func = st->frame[frame];
        if (regno >= 0) {
                reg = &func->regs[regno];
                if (reg->type != SCALAR_VALUE) {
                        break;
 
                new_marks = false;
-               func = st->frame[st->curframe];
+               func = st->frame[frame];
                bitmap_from_u64(mask, reg_mask);
                for_each_set_bit(i, mask, 32) {
                        reg = &func->regs[i];
 
 int mark_chain_precision(struct bpf_verifier_env *env, int regno)
 {
-       return __mark_chain_precision(env, regno, -1);
+       return __mark_chain_precision(env, env->cur_state->curframe, regno, -1);
 }
 
-static int mark_chain_precision_stack(struct bpf_verifier_env *env, int spi)
+static int mark_chain_precision_frame(struct bpf_verifier_env *env, int frame, int regno)
 {
-       return __mark_chain_precision(env, -1, spi);
+       return __mark_chain_precision(env, frame, regno, -1);
+}
+
+static int mark_chain_precision_stack_frame(struct bpf_verifier_env *env, int frame, int spi)
+{
+       return __mark_chain_precision(env, frame, -1, spi);
 }
 
 static bool is_spillable_regtype(enum bpf_reg_type type)
 {
        struct bpf_reg_state *state_reg;
        struct bpf_func_state *state;
-       int i, err = 0;
+       int i, err = 0, fr;
 
-       state = old->frame[old->curframe];
-       state_reg = state->regs;
-       for (i = 0; i < BPF_REG_FP; i++, state_reg++) {
-               if (state_reg->type != SCALAR_VALUE ||
-                   !state_reg->precise)
-                       continue;
-               if (env->log.level & BPF_LOG_LEVEL2)
-                       verbose(env, "propagating r%d\n", i);
-               err = mark_chain_precision(env, i);
-               if (err < 0)
-                       return err;
-       }
+       for (fr = old->curframe; fr >= 0; fr--) {
+               state = old->frame[fr];
+               state_reg = state->regs;
+               for (i = 0; i < BPF_REG_FP; i++, state_reg++) {
+                       if (state_reg->type != SCALAR_VALUE ||
+                           !state_reg->precise)
+                               continue;
+                       if (env->log.level & BPF_LOG_LEVEL2)
+                               verbose(env, "frame %d: propagating r%d\n", i, fr);
+                       err = mark_chain_precision_frame(env, fr, i);
+                       if (err < 0)
+                               return err;
+               }
 
-       for (i = 0; i < state->allocated_stack / BPF_REG_SIZE; i++) {
-               if (!is_spilled_reg(&state->stack[i]))
-                       continue;
-               state_reg = &state->stack[i].spilled_ptr;
-               if (state_reg->type != SCALAR_VALUE ||
-                   !state_reg->precise)
-                       continue;
-               if (env->log.level & BPF_LOG_LEVEL2)
-                       verbose(env, "propagating fp%d\n",
-                               (-i - 1) * BPF_REG_SIZE);
-               err = mark_chain_precision_stack(env, i);
-               if (err < 0)
-                       return err;
+               for (i = 0; i < state->allocated_stack / BPF_REG_SIZE; i++) {
+                       if (!is_spilled_reg(&state->stack[i]))
+                               continue;
+                       state_reg = &state->stack[i].spilled_ptr;
+                       if (state_reg->type != SCALAR_VALUE ||
+                           !state_reg->precise)
+                               continue;
+                       if (env->log.level & BPF_LOG_LEVEL2)
+                               verbose(env, "frame %d: propagating fp%d\n",
+                                       (-i - 1) * BPF_REG_SIZE, fr);
+                       err = mark_chain_precision_stack_frame(env, fr, i);
+                       if (err < 0)
+                               return err;
+               }
        }
        return 0;
 }