Skip to content

Commit f9320c4

Browse files
rnavmpe
authored andcommitted
powerpc/bpf: Update ldimm64 instructions during extra pass
These instructions are updated after the initial JIT, so redo codegen during the extra pass. Rename bpf_jit_fixup_subprog_calls() to clarify that this is more than just subprog calls. Fixes: 69c087b ("bpf: Add bpf_for_each_map_elem() helper") Cc: [email protected] # v5.15 Signed-off-by: Naveen N. Rao <[email protected]> Tested-by: Jiri Olsa <[email protected]> Signed-off-by: Michael Ellerman <[email protected]> Link: https://lore.kernel.org/r/7cc162af77ba918eb3ecd26ec9e7824bc44b1fae.1641468127.git.naveen.n.rao@linux.vnet.ibm.com
1 parent fab0761 commit f9320c4

File tree

3 files changed

+35
-7
lines changed

3 files changed

+35
-7
lines changed

arch/powerpc/net/bpf_jit_comp.c

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,15 @@ static void bpf_jit_fill_ill_insns(void *area, unsigned int size)
2323
memset32(area, BREAKPOINT_INSTRUCTION, size / 4);
2424
}
2525

26-
/* Fix the branch target addresses for subprog calls */
27-
static int bpf_jit_fixup_subprog_calls(struct bpf_prog *fp, u32 *image,
28-
struct codegen_context *ctx, u32 *addrs)
26+
/* Fix updated addresses (for subprog calls, ldimm64, et al) during extra pass */
27+
static int bpf_jit_fixup_addresses(struct bpf_prog *fp, u32 *image,
28+
struct codegen_context *ctx, u32 *addrs)
2929
{
3030
const struct bpf_insn *insn = fp->insnsi;
3131
bool func_addr_fixed;
3232
u64 func_addr;
3333
u32 tmp_idx;
34-
int i, ret;
34+
int i, j, ret;
3535

3636
for (i = 0; i < fp->len; i++) {
3737
/*
@@ -66,6 +66,23 @@ static int bpf_jit_fixup_subprog_calls(struct bpf_prog *fp, u32 *image,
6666
* of the JITed sequence remains unchanged.
6767
*/
6868
ctx->idx = tmp_idx;
69+
} else if (insn[i].code == (BPF_LD | BPF_IMM | BPF_DW)) {
70+
tmp_idx = ctx->idx;
71+
ctx->idx = addrs[i] / 4;
72+
#ifdef CONFIG_PPC32
73+
PPC_LI32(ctx->b2p[insn[i].dst_reg] - 1, (u32)insn[i + 1].imm);
74+
PPC_LI32(ctx->b2p[insn[i].dst_reg], (u32)insn[i].imm);
75+
for (j = ctx->idx - addrs[i] / 4; j < 4; j++)
76+
EMIT(PPC_RAW_NOP());
77+
#else
78+
func_addr = ((u64)(u32)insn[i].imm) | (((u64)(u32)insn[i + 1].imm) << 32);
79+
PPC_LI64(b2p[insn[i].dst_reg], func_addr);
80+
/* overwrite rest with nops */
81+
for (j = ctx->idx - addrs[i] / 4; j < 5; j++)
82+
EMIT(PPC_RAW_NOP());
83+
#endif
84+
ctx->idx = tmp_idx;
85+
i++;
6986
}
7087
}
7188

@@ -200,13 +217,13 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp)
200217
/*
201218
* Do not touch the prologue and epilogue as they will remain
202219
* unchanged. Only fix the branch target address for subprog
203-
* calls in the body.
220+
* calls in the body, and ldimm64 instructions.
204221
*
205222
* This does not change the offsets and lengths of the subprog
206223
* call instruction sequences and hence, the size of the JITed
207224
* image as well.
208225
*/
209-
bpf_jit_fixup_subprog_calls(fp, code_base, &cgctx, addrs);
226+
bpf_jit_fixup_addresses(fp, code_base, &cgctx, addrs);
210227

211228
/* There is no need to perform the usual passes. */
212229
goto skip_codegen_passes;

arch/powerpc/net/bpf_jit_comp32.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,8 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, struct codegen_context *
293293
bool func_addr_fixed;
294294
u64 func_addr;
295295
u32 true_cond;
296+
u32 tmp_idx;
297+
int j;
296298

297299
/*
298300
* addrs[] maps a BPF bytecode address into a real offset from
@@ -908,8 +910,12 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, struct codegen_context *
908910
* 16 byte instruction that uses two 'struct bpf_insn'
909911
*/
910912
case BPF_LD | BPF_IMM | BPF_DW: /* dst = (u64) imm */
913+
tmp_idx = ctx->idx;
911914
PPC_LI32(dst_reg_h, (u32)insn[i + 1].imm);
912915
PPC_LI32(dst_reg, (u32)insn[i].imm);
916+
/* padding to allow full 4 instructions for later patching */
917+
for (j = ctx->idx - tmp_idx; j < 4; j++)
918+
EMIT(PPC_RAW_NOP());
913919
/* Adjust for two bpf instructions */
914920
addrs[++i] = ctx->idx * 4;
915921
break;

arch/powerpc/net/bpf_jit_comp64.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,7 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, struct codegen_context *
319319
u64 imm64;
320320
u32 true_cond;
321321
u32 tmp_idx;
322+
int j;
322323

323324
/*
324325
* addrs[] maps a BPF bytecode address into a real offset from
@@ -848,9 +849,13 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, struct codegen_context *
848849
case BPF_LD | BPF_IMM | BPF_DW: /* dst = (u64) imm */
849850
imm64 = ((u64)(u32) insn[i].imm) |
850851
(((u64)(u32) insn[i+1].imm) << 32);
852+
tmp_idx = ctx->idx;
853+
PPC_LI64(dst_reg, imm64);
854+
/* padding to allow full 5 instructions for later patching */
855+
for (j = ctx->idx - tmp_idx; j < 5; j++)
856+
EMIT(PPC_RAW_NOP());
851857
/* Adjust for two bpf instructions */
852858
addrs[++i] = ctx->idx * 4;
853-
PPC_LI64(dst_reg, imm64);
854859
break;
855860

856861
/*

0 commit comments

Comments
 (0)