diff options
author | Neil Armstrong <neil.armstrong@linaro.org> | 2024-06-06 11:19:47 +0200 |
---|---|---|
committer | Neil Armstrong <neil.armstrong@linaro.org> | 2024-06-06 11:19:47 +0200 |
commit | 4c607a73300b756ad1c8001abcfe37bf53b5a5f1 (patch) | |
tree | 81b36e4b324925478fe58ddd3cebfd78e1428d11 /arch/powerpc/net/bpf_jit_comp32.c | |
parent | 1d1239a1b0e502faffe43b97d530232285b9f061 (diff) | |
parent | 5bbe5872fed4497a192556426d75fd9223c5bfeb (diff) |
Merge branch 'dt' of https://git.kernel.org/pub/scm/linux/kernel/git/ulfh/linux-pm into v6.11/arm64-dt
Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
Diffstat (limited to 'arch/powerpc/net/bpf_jit_comp32.c')
-rw-r--r-- | arch/powerpc/net/bpf_jit_comp32.c | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/arch/powerpc/net/bpf_jit_comp32.c b/arch/powerpc/net/bpf_jit_comp32.c index 43b97032a91c..a0c4f1bde83e 100644 --- a/arch/powerpc/net/bpf_jit_comp32.c +++ b/arch/powerpc/net/bpf_jit_comp32.c @@ -900,6 +900,15 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, u32 *fimage, struct code /* Get offset into TMP_REG */ EMIT(PPC_RAW_LI(tmp_reg, off)); + /* + * Enforce full ordering for operations with BPF_FETCH by emitting a 'sync' + * before and after the operation. + * + * This is a requirement in the Linux Kernel Memory Model. + * See __cmpxchg_u32() in asm/cmpxchg.h as an example. + */ + if ((imm & BPF_FETCH) && IS_ENABLED(CONFIG_SMP)) + EMIT(PPC_RAW_SYNC()); tmp_idx = ctx->idx * 4; /* load value from memory into r0 */ EMIT(PPC_RAW_LWARX(_R0, tmp_reg, dst_reg, 0)); @@ -953,6 +962,9 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, u32 *fimage, struct code /* For the BPF_FETCH variant, get old data into src_reg */ if (imm & BPF_FETCH) { + /* Emit 'sync' to enforce full ordering */ + if (IS_ENABLED(CONFIG_SMP)) + EMIT(PPC_RAW_SYNC()); EMIT(PPC_RAW_MR(ret_reg, ax_reg)); if (!fp->aux->verifier_zext) EMIT(PPC_RAW_LI(ret_reg - 1, 0)); /* higher 32-bit */ |