Skip to content

Commit 6fee7a7

Browse files
author
Alexei Starovoitov
committed
Merge branch 'bpf-follow-up-on-gen_epilogue'
Martin KaFai Lau says: ==================== bpf: Follow up on gen_epilogue From: Martin KaFai Lau <[email protected]> The set addresses some follow ups on the earlier gen_epilogue patch set. ==================== Acked-by: Eduard Zingerman <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Alexei Starovoitov <[email protected]>
2 parents 46f4ea0 + 0075078 commit 6fee7a7

File tree

2 files changed

+44
-43
lines changed

2 files changed

+44
-43
lines changed

include/linux/bpf_verifier.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
*/
2525
#define TMP_STR_BUF_LEN 320
2626
/* Patch buffer size */
27-
#define INSN_BUF_SIZE 16
27+
#define INSN_BUF_SIZE 32
2828

2929
/* Liveness marks, used for registers and spilled-regs (in stack slots).
3030
* Read marks propagate upwards until they find a write mark; they record that

kernel/bpf/verifier.c

Lines changed: 43 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -19800,7 +19800,7 @@ static int convert_ctx_accesses(struct bpf_verifier_env *env)
1980019800
* least one ctx ptr saving insn before the
1980119801
* epilogue.
1980219802
*/
19803-
epilogue_idx = i + delta;
19803+
epilogue_idx = i + delta;
1980419804
}
1980519805
goto patch_insn_buf;
1980619806
} else {
@@ -21232,7 +21232,7 @@ static struct bpf_prog *inline_bpf_loop(struct bpf_verifier_env *env,
2123221232
int position,
2123321233
s32 stack_base,
2123421234
u32 callback_subprogno,
21235-
u32 *cnt)
21235+
u32 *total_cnt)
2123621236
{
2123721237
s32 r6_offset = stack_base + 0 * BPF_REG_SIZE;
2123821238
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,
2124121241
int reg_loop_cnt = BPF_REG_7;
2124221242
int reg_loop_ctx = BPF_REG_8;
2124321243

21244+
struct bpf_insn *insn_buf = env->insn_buf;
2124421245
struct bpf_prog *new_prog;
2124521246
u32 callback_start;
2124621247
u32 call_insn_offset;
2124721248
s32 callback_offset;
21249+
u32 cnt = 0;
2124821250

2124921251
/* This represents an inlined version of bpf_iter.c:bpf_loop,
2125021252
* be careful to modify this code in sync.
2125121253
*/
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-
};
2129021254

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);
2129321294
if (!new_prog)
2129421295
return new_prog;
2129521296

0 commit comments

Comments
 (0)