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
This commit is contained in:
parent
61bdbca855
commit
6511270911
|
@ -777,41 +777,42 @@ emit_clear:
|
|||
* BPF_STX ATOMIC (atomic ops)
|
||||
*/
|
||||
case BPF_STX | BPF_ATOMIC | BPF_W:
|
||||
if (imm != BPF_ADD) {
|
||||
pr_err_ratelimited(
|
||||
"eBPF filter atomic op code %02x (@%d) unsupported\n",
|
||||
code, i);
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
|
||||
/* *(u32 *)(dst + off) += src */
|
||||
|
||||
/* Get EA into TMP_REG_1 */
|
||||
EMIT(PPC_RAW_ADDI(tmp1_reg, dst_reg, off));
|
||||
case BPF_STX | BPF_ATOMIC | BPF_DW:
|
||||
/* Get offset into TMP_REG_1 */
|
||||
EMIT(PPC_RAW_LI(tmp1_reg, off));
|
||||
tmp_idx = ctx->idx * 4;
|
||||
/* load value from memory into TMP_REG_2 */
|
||||
EMIT(PPC_RAW_LWARX(tmp2_reg, 0, tmp1_reg, 0));
|
||||
/* add value from src_reg into this */
|
||||
EMIT(PPC_RAW_ADD(tmp2_reg, tmp2_reg, src_reg));
|
||||
/* store result back */
|
||||
EMIT(PPC_RAW_STWCX(tmp2_reg, 0, tmp1_reg));
|
||||
/* we're done if this succeeded */
|
||||
PPC_BCC_SHORT(COND_NE, tmp_idx);
|
||||
break;
|
||||
case BPF_STX | BPF_ATOMIC | BPF_DW:
|
||||
if (imm != BPF_ADD) {
|
||||
if (size == BPF_DW)
|
||||
EMIT(PPC_RAW_LDARX(tmp2_reg, tmp1_reg, dst_reg, 0));
|
||||
else
|
||||
EMIT(PPC_RAW_LWARX(tmp2_reg, tmp1_reg, dst_reg, 0));
|
||||
|
||||
switch (imm) {
|
||||
case BPF_ADD:
|
||||
EMIT(PPC_RAW_ADD(tmp2_reg, tmp2_reg, src_reg));
|
||||
break;
|
||||
case BPF_AND:
|
||||
EMIT(PPC_RAW_AND(tmp2_reg, tmp2_reg, src_reg));
|
||||
break;
|
||||
case BPF_OR:
|
||||
EMIT(PPC_RAW_OR(tmp2_reg, tmp2_reg, src_reg));
|
||||
break;
|
||||
case BPF_XOR:
|
||||
EMIT(PPC_RAW_XOR(tmp2_reg, tmp2_reg, src_reg));
|
||||
break;
|
||||
default:
|
||||
pr_err_ratelimited(
|
||||
"eBPF filter atomic op code %02x (@%d) unsupported\n",
|
||||
code, i);
|
||||
return -ENOTSUPP;
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
/* *(u64 *)(dst + off) += src */
|
||||
|
||||
EMIT(PPC_RAW_ADDI(tmp1_reg, dst_reg, off));
|
||||
tmp_idx = ctx->idx * 4;
|
||||
EMIT(PPC_RAW_LDARX(tmp2_reg, 0, tmp1_reg, 0));
|
||||
EMIT(PPC_RAW_ADD(tmp2_reg, tmp2_reg, src_reg));
|
||||
EMIT(PPC_RAW_STDCX(tmp2_reg, 0, tmp1_reg));
|
||||
/* store result back */
|
||||
if (size == BPF_DW)
|
||||
EMIT(PPC_RAW_STDCX(tmp2_reg, tmp1_reg, dst_reg));
|
||||
else
|
||||
EMIT(PPC_RAW_STWCX(tmp2_reg, tmp1_reg, dst_reg));
|
||||
/* we're done if this succeeded */
|
||||
PPC_BCC_SHORT(COND_NE, tmp_idx);
|
||||
break;
|
||||
|
||||
|
|
Loading…
Reference in New Issue