@@ -19800,7 +19800,7 @@ static int convert_ctx_accesses(struct bpf_verifier_env *env)
19800
19800
* least one ctx ptr saving insn before the
19801
19801
* epilogue.
19802
19802
*/
19803
- epilogue_idx = i + delta;
19803
+ epilogue_idx = i + delta;
19804
19804
}
19805
19805
goto patch_insn_buf;
19806
19806
} else {
@@ -21232,7 +21232,7 @@ static struct bpf_prog *inline_bpf_loop(struct bpf_verifier_env *env,
21232
21232
int position,
21233
21233
s32 stack_base,
21234
21234
u32 callback_subprogno,
21235
- u32 *cnt )
21235
+ u32 *total_cnt )
21236
21236
{
21237
21237
s32 r6_offset = stack_base + 0 * BPF_REG_SIZE;
21238
21238
s32 r7_offset = stack_base + 1 * BPF_REG_SIZE;
@@ -21241,55 +21241,56 @@ static struct bpf_prog *inline_bpf_loop(struct bpf_verifier_env *env,
21241
21241
int reg_loop_cnt = BPF_REG_7;
21242
21242
int reg_loop_ctx = BPF_REG_8;
21243
21243
21244
+ struct bpf_insn *insn_buf = env->insn_buf;
21244
21245
struct bpf_prog *new_prog;
21245
21246
u32 callback_start;
21246
21247
u32 call_insn_offset;
21247
21248
s32 callback_offset;
21249
+ u32 cnt = 0;
21248
21250
21249
21251
/* This represents an inlined version of bpf_iter.c:bpf_loop,
21250
21252
* be careful to modify this code in sync.
21251
21253
*/
21252
- struct bpf_insn insn_buf[] = {
21253
- /* Return error and jump to the end of the patch if
21254
- * expected number of iterations is too big.
21255
- */
21256
- BPF_JMP_IMM(BPF_JLE, BPF_REG_1, BPF_MAX_LOOPS, 2),
21257
- BPF_MOV32_IMM(BPF_REG_0, -E2BIG),
21258
- BPF_JMP_IMM(BPF_JA, 0, 0, 16),
21259
- /* spill R6, R7, R8 to use these as loop vars */
21260
- BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_6, r6_offset),
21261
- BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_7, r7_offset),
21262
- BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_8, r8_offset),
21263
- /* initialize loop vars */
21264
- BPF_MOV64_REG(reg_loop_max, BPF_REG_1),
21265
- BPF_MOV32_IMM(reg_loop_cnt, 0),
21266
- BPF_MOV64_REG(reg_loop_ctx, BPF_REG_3),
21267
- /* loop header,
21268
- * if reg_loop_cnt >= reg_loop_max skip the loop body
21269
- */
21270
- BPF_JMP_REG(BPF_JGE, reg_loop_cnt, reg_loop_max, 5),
21271
- /* callback call,
21272
- * correct callback offset would be set after patching
21273
- */
21274
- BPF_MOV64_REG(BPF_REG_1, reg_loop_cnt),
21275
- BPF_MOV64_REG(BPF_REG_2, reg_loop_ctx),
21276
- BPF_CALL_REL(0),
21277
- /* increment loop counter */
21278
- BPF_ALU64_IMM(BPF_ADD, reg_loop_cnt, 1),
21279
- /* jump to loop header if callback returned 0 */
21280
- BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, -6),
21281
- /* return value of bpf_loop,
21282
- * set R0 to the number of iterations
21283
- */
21284
- BPF_MOV64_REG(BPF_REG_0, reg_loop_cnt),
21285
- /* restore original values of R6, R7, R8 */
21286
- BPF_LDX_MEM(BPF_DW, BPF_REG_6, BPF_REG_10, r6_offset),
21287
- BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_10, r7_offset),
21288
- BPF_LDX_MEM(BPF_DW, BPF_REG_8, BPF_REG_10, r8_offset),
21289
- };
21290
21254
21291
- *cnt = ARRAY_SIZE(insn_buf);
21292
- new_prog = bpf_patch_insn_data(env, position, insn_buf, *cnt);
21255
+ /* Return error and jump to the end of the patch if
21256
+ * expected number of iterations is too big.
21257
+ */
21258
+ insn_buf[cnt++] = BPF_JMP_IMM(BPF_JLE, BPF_REG_1, BPF_MAX_LOOPS, 2);
21259
+ insn_buf[cnt++] = BPF_MOV32_IMM(BPF_REG_0, -E2BIG);
21260
+ insn_buf[cnt++] = BPF_JMP_IMM(BPF_JA, 0, 0, 16);
21261
+ /* spill R6, R7, R8 to use these as loop vars */
21262
+ insn_buf[cnt++] = BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_6, r6_offset);
21263
+ insn_buf[cnt++] = BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_7, r7_offset);
21264
+ insn_buf[cnt++] = BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_8, r8_offset);
21265
+ /* initialize loop vars */
21266
+ insn_buf[cnt++] = BPF_MOV64_REG(reg_loop_max, BPF_REG_1);
21267
+ insn_buf[cnt++] = BPF_MOV32_IMM(reg_loop_cnt, 0);
21268
+ insn_buf[cnt++] = BPF_MOV64_REG(reg_loop_ctx, BPF_REG_3);
21269
+ /* loop header,
21270
+ * if reg_loop_cnt >= reg_loop_max skip the loop body
21271
+ */
21272
+ insn_buf[cnt++] = BPF_JMP_REG(BPF_JGE, reg_loop_cnt, reg_loop_max, 5);
21273
+ /* callback call,
21274
+ * correct callback offset would be set after patching
21275
+ */
21276
+ insn_buf[cnt++] = BPF_MOV64_REG(BPF_REG_1, reg_loop_cnt);
21277
+ insn_buf[cnt++] = BPF_MOV64_REG(BPF_REG_2, reg_loop_ctx);
21278
+ insn_buf[cnt++] = BPF_CALL_REL(0);
21279
+ /* increment loop counter */
21280
+ insn_buf[cnt++] = BPF_ALU64_IMM(BPF_ADD, reg_loop_cnt, 1);
21281
+ /* jump to loop header if callback returned 0 */
21282
+ insn_buf[cnt++] = BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, -6);
21283
+ /* return value of bpf_loop,
21284
+ * set R0 to the number of iterations
21285
+ */
21286
+ insn_buf[cnt++] = BPF_MOV64_REG(BPF_REG_0, reg_loop_cnt);
21287
+ /* restore original values of R6, R7, R8 */
21288
+ insn_buf[cnt++] = BPF_LDX_MEM(BPF_DW, BPF_REG_6, BPF_REG_10, r6_offset);
21289
+ insn_buf[cnt++] = BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_10, r7_offset);
21290
+ insn_buf[cnt++] = BPF_LDX_MEM(BPF_DW, BPF_REG_8, BPF_REG_10, r8_offset);
21291
+
21292
+ *total_cnt = cnt;
21293
+ new_prog = bpf_patch_insn_data(env, position, insn_buf, cnt);
21293
21294
if (!new_prog)
21294
21295
return new_prog;
21295
21296
0 commit comments