Skip to content

Commit 6511270

Browse files
hbathinimpe
authored andcommitted
powerpc/bpf/64: add support for BPF_ATOMIC bitwise operations
Adding instructions for ppc64 for atomic[64]_and atomic[64]_or atomic[64]_xor Signed-off-by: Hari Bathini <hbathini@linux.ibm.com> Tested-by: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com> (ppc64le) Reviewed-by: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> Link: https://lore.kernel.org/r/20220610155552.25892-2-hbathini@linux.ibm.com
1 parent 61bdbca commit 6511270

File tree

1 file changed

+29
-28
lines changed

1 file changed

+29
-28
lines changed

arch/powerpc/net/bpf_jit_comp64.c

Lines changed: 29 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -777,41 +777,42 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, struct codegen_context *
777777
* BPF_STX ATOMIC (atomic ops)
778778
*/
779779
case BPF_STX | BPF_ATOMIC | BPF_W:
780-
if (imm != BPF_ADD) {
781-
pr_err_ratelimited(
782-
"eBPF filter atomic op code %02x (@%d) unsupported\n",
783-
code, i);
784-
return -ENOTSUPP;
785-
}
786-
787-
/* *(u32 *)(dst + off) += src */
788-
789-
/* Get EA into TMP_REG_1 */
790-
EMIT(PPC_RAW_ADDI(tmp1_reg, dst_reg, off));
780+
case BPF_STX | BPF_ATOMIC | BPF_DW:
781+
/* Get offset into TMP_REG_1 */
782+
EMIT(PPC_RAW_LI(tmp1_reg, off));
791783
tmp_idx = ctx->idx * 4;
792784
/* load value from memory into TMP_REG_2 */
793-
EMIT(PPC_RAW_LWARX(tmp2_reg, 0, tmp1_reg, 0));
794-
/* add value from src_reg into this */
795-
EMIT(PPC_RAW_ADD(tmp2_reg, tmp2_reg, src_reg));
796-
/* store result back */
797-
EMIT(PPC_RAW_STWCX(tmp2_reg, 0, tmp1_reg));
798-
/* we're done if this succeeded */
799-
PPC_BCC_SHORT(COND_NE, tmp_idx);
800-
break;
801-
case BPF_STX | BPF_ATOMIC | BPF_DW:
802-
if (imm != BPF_ADD) {
785+
if (size == BPF_DW)
786+
EMIT(PPC_RAW_LDARX(tmp2_reg, tmp1_reg, dst_reg, 0));
787+
else
788+
EMIT(PPC_RAW_LWARX(tmp2_reg, tmp1_reg, dst_reg, 0));
789+
790+
switch (imm) {
791+
case BPF_ADD:
792+
EMIT(PPC_RAW_ADD(tmp2_reg, tmp2_reg, src_reg));
793+
break;
794+
case BPF_AND:
795+
EMIT(PPC_RAW_AND(tmp2_reg, tmp2_reg, src_reg));
796+
break;
797+
case BPF_OR:
798+
EMIT(PPC_RAW_OR(tmp2_reg, tmp2_reg, src_reg));
799+
break;
800+
case BPF_XOR:
801+
EMIT(PPC_RAW_XOR(tmp2_reg, tmp2_reg, src_reg));
802+
break;
803+
default:
803804
pr_err_ratelimited(
804805
"eBPF filter atomic op code %02x (@%d) unsupported\n",
805806
code, i);
806-
return -ENOTSUPP;
807+
return -EOPNOTSUPP;
807808
}
808-
/* *(u64 *)(dst + off) += src */
809809

810-
EMIT(PPC_RAW_ADDI(tmp1_reg, dst_reg, off));
811-
tmp_idx = ctx->idx * 4;
812-
EMIT(PPC_RAW_LDARX(tmp2_reg, 0, tmp1_reg, 0));
813-
EMIT(PPC_RAW_ADD(tmp2_reg, tmp2_reg, src_reg));
814-
EMIT(PPC_RAW_STDCX(tmp2_reg, 0, tmp1_reg));
810+
/* store result back */
811+
if (size == BPF_DW)
812+
EMIT(PPC_RAW_STDCX(tmp2_reg, tmp1_reg, dst_reg));
813+
else
814+
EMIT(PPC_RAW_STWCX(tmp2_reg, tmp1_reg, dst_reg));
815+
/* we're done if this succeeded */
815816
PPC_BCC_SHORT(COND_NE, tmp_idx);
816817
break;
817818

0 commit comments

Comments
 (0)