Skip to content

Commit 3ad6950

Browse files
Saket Kumar BhaskarKernel Patches Daemon
authored andcommitted
powerpc64/bpf: Implement PROBE_ATOMIC instructions
powerpc supports BPF atomic operations using a loop around Load-And-Reserve(LDARX/LWARX) and Store-Conditional(STDCX/STWCX) instructions gated by sync instructions to enforce full ordering. To implement arena_atomics, arena vm start address is added to the dst_reg to be used for both the LDARX/LWARX and STDCX/STWCX instructions. Further, an exception table entry is added for LDARX/LWARX instruction to land after the loop on fault. At the end of sequence, dst_reg is restored by subtracting arena vm start address. bpf_jit_supports_insn() is introduced to selectively enable instruction support as in other architectures like x86 and arm64. Reviewed-by: Hari Bathini <[email protected]> Tested-by: Venkat Rao Bagalkote <[email protected]> Signed-off-by: Saket Kumar Bhaskar <[email protected]>
1 parent 14c3e44 commit 3ad6950

File tree

2 files changed

+42
-0
lines changed

2 files changed

+42
-0
lines changed

arch/powerpc/net/bpf_jit_comp.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,22 @@ bool bpf_jit_supports_far_kfunc_call(void)
450450
return IS_ENABLED(CONFIG_PPC64);
451451
}
452452

453+
bool bpf_jit_supports_insn(struct bpf_insn *insn, bool in_arena)
454+
{
455+
if (!in_arena)
456+
return true;
457+
switch (insn->code) {
458+
case BPF_STX | BPF_ATOMIC | BPF_H:
459+
case BPF_STX | BPF_ATOMIC | BPF_B:
460+
case BPF_STX | BPF_ATOMIC | BPF_W:
461+
case BPF_STX | BPF_ATOMIC | BPF_DW:
462+
if (bpf_atomic_is_load_store(insn))
463+
return false;
464+
return IS_ENABLED(CONFIG_PPC64);
465+
}
466+
return true;
467+
}
468+
453469
void *arch_alloc_bpf_trampoline(unsigned int size)
454470
{
455471
return bpf_prog_pack_alloc(size, bpf_jit_fill_ill_insns);

arch/powerpc/net/bpf_jit_comp64.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1163,6 +1163,32 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, u32 *fimage, struct code
11631163

11641164
break;
11651165

1166+
/*
1167+
* BPF_STX PROBE_ATOMIC (arena atomic ops)
1168+
*/
1169+
case BPF_STX | BPF_PROBE_ATOMIC | BPF_W:
1170+
case BPF_STX | BPF_PROBE_ATOMIC | BPF_DW:
1171+
EMIT(PPC_RAW_ADD(dst_reg, dst_reg, bpf_to_ppc(ARENA_VM_START)));
1172+
ret = bpf_jit_emit_atomic_ops(image, ctx, &insn[i],
1173+
&jmp_off, &tmp_idx, &addrs[i + 1]);
1174+
if (ret) {
1175+
if (ret == -EOPNOTSUPP) {
1176+
pr_err_ratelimited(
1177+
"eBPF filter atomic op code %02x (@%d) unsupported\n",
1178+
code, i);
1179+
}
1180+
return ret;
1181+
}
1182+
/* LDARX/LWARX should land here on exception. */
1183+
ret = bpf_add_extable_entry(fp, image, fimage, pass, ctx,
1184+
tmp_idx, jmp_off, dst_reg, code);
1185+
if (ret)
1186+
return ret;
1187+
1188+
/* Retrieve the dst_reg */
1189+
EMIT(PPC_RAW_SUB(dst_reg, dst_reg, bpf_to_ppc(ARENA_VM_START)));
1190+
break;
1191+
11661192
/*
11671193
* BPF_STX ATOMIC (atomic ops)
11681194
*/

0 commit comments

Comments
 (0)