[PATCH v2 3/8] bpf powerpc: refactor JIT compiler code
Christophe Leroy
christophe.leroy at csgroup.eu
Sat Sep 18 02:22:45 AEST 2021
Le 17/09/2021 à 17:30, Hari Bathini a écrit :
> Refactor powerpc JITing. This simplifies adding BPF_PROBE_MEM support.
>
> Signed-off-by: Hari Bathini <hbathini at linux.ibm.com>
> ---
>
> Changes in v2:
> * New patch to refactor a bit of JITing code.
>
>
> arch/powerpc/net/bpf_jit_comp32.c | 50 +++++++++++---------
> arch/powerpc/net/bpf_jit_comp64.c | 76 ++++++++++++++++---------------
> 2 files changed, 68 insertions(+), 58 deletions(-)
>
> diff --git a/arch/powerpc/net/bpf_jit_comp32.c b/arch/powerpc/net/bpf_jit_comp32.c
> index b60b59426a24..c8ae14c316e3 100644
> --- a/arch/powerpc/net/bpf_jit_comp32.c
> +++ b/arch/powerpc/net/bpf_jit_comp32.c
> @@ -276,17 +276,17 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, struct codegen_context *
> u32 exit_addr = addrs[flen];
>
> for (i = 0; i < flen; i++) {
> - u32 code = insn[i].code;
> u32 dst_reg = bpf_to_ppc(ctx, insn[i].dst_reg);
> - u32 dst_reg_h = dst_reg - 1;
> u32 src_reg = bpf_to_ppc(ctx, insn[i].src_reg);
> - u32 src_reg_h = src_reg - 1;
> u32 tmp_reg = bpf_to_ppc(ctx, TMP_REG);
> + u32 true_cond, code = insn[i].code;
> + u32 dst_reg_h = dst_reg - 1;
> + u32 src_reg_h = src_reg - 1;
> + u32 size = BPF_SIZE(code);
> s16 off = insn[i].off;
> s32 imm = insn[i].imm;
> bool func_addr_fixed;
> u64 func_addr;
> - u32 true_cond;
>
> /*
> * addrs[] maps a BPF bytecode address into a real offset from
> @@ -809,25 +809,33 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, struct codegen_context *
> /*
> * BPF_LDX
> */
> - case BPF_LDX | BPF_MEM | BPF_B: /* dst = *(u8 *)(ul) (src + off) */
> - EMIT(PPC_RAW_LBZ(dst_reg, src_reg, off));
> - if (!fp->aux->verifier_zext)
> - EMIT(PPC_RAW_LI(dst_reg_h, 0));
> - break;
> - case BPF_LDX | BPF_MEM | BPF_H: /* dst = *(u16 *)(ul) (src + off) */
> - EMIT(PPC_RAW_LHZ(dst_reg, src_reg, off));
> - if (!fp->aux->verifier_zext)
> - EMIT(PPC_RAW_LI(dst_reg_h, 0));
> - break;
> - case BPF_LDX | BPF_MEM | BPF_W: /* dst = *(u32 *)(ul) (src + off) */
> - EMIT(PPC_RAW_LWZ(dst_reg, src_reg, off));
> - if (!fp->aux->verifier_zext)
> + /* dst = *(u8 *)(ul) (src + off) */
> + case BPF_LDX | BPF_MEM | BPF_B:
> + /* dst = *(u16 *)(ul) (src + off) */
> + case BPF_LDX | BPF_MEM | BPF_H:
> + /* dst = *(u32 *)(ul) (src + off) */
> + case BPF_LDX | BPF_MEM | BPF_W:
> + /* dst = *(u64 *)(ul) (src + off) */
> + case BPF_LDX | BPF_MEM | BPF_DW:
You have to add the 'fallthrough;' keyword to avoid build failure with
later versions of GCC.
> + switch (size) {
> + case BPF_B:
> + EMIT(PPC_RAW_LBZ(dst_reg, src_reg, off));
> + break;
> + case BPF_H:
> + EMIT(PPC_RAW_LHZ(dst_reg, src_reg, off));
> + break;
> + case BPF_W:
> + EMIT(PPC_RAW_LWZ(dst_reg, src_reg, off));
> + break;
> + case BPF_DW:
> + EMIT(PPC_RAW_LWZ(dst_reg_h, src_reg, off));
> + EMIT(PPC_RAW_LWZ(dst_reg, src_reg, off + 4));
> + break;
> + }
> +
> + if ((size != BPF_DW) && !fp->aux->verifier_zext)
> EMIT(PPC_RAW_LI(dst_reg_h, 0));
> break;
> - case BPF_LDX | BPF_MEM | BPF_DW: /* dst = *(u64 *)(ul) (src + off) */
> - EMIT(PPC_RAW_LWZ(dst_reg_h, src_reg, off));
> - EMIT(PPC_RAW_LWZ(dst_reg, src_reg, off + 4));
> - break;
>
> /*
> * Doubleword load
> diff --git a/arch/powerpc/net/bpf_jit_comp64.c b/arch/powerpc/net/bpf_jit_comp64.c
> index 2a87da50d9a4..78b28f25555c 100644
> --- a/arch/powerpc/net/bpf_jit_comp64.c
> +++ b/arch/powerpc/net/bpf_jit_comp64.c
> @@ -282,16 +282,15 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, struct codegen_context *
> u32 exit_addr = addrs[flen];
>
> for (i = 0; i < flen; i++) {
> - u32 code = insn[i].code;
> u32 dst_reg = b2p[insn[i].dst_reg];
> u32 src_reg = b2p[insn[i].src_reg];
> + u32 tmp_idx, code = insn[i].code;
> + u32 size = BPF_SIZE(code);
> s16 off = insn[i].off;
> s32 imm = insn[i].imm;
> bool func_addr_fixed;
> - u64 func_addr;
> - u64 imm64;
> + u64 func_addr, imm64;
> u32 true_cond;
> - u32 tmp_idx;
>
> /*
> * addrs[] maps a BPF bytecode address into a real offset from
> @@ -638,35 +637,34 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, struct codegen_context *
> */
> case BPF_STX | BPF_MEM | BPF_B: /* *(u8 *)(dst + off) = src */
> case BPF_ST | BPF_MEM | BPF_B: /* *(u8 *)(dst + off) = imm */
> - if (BPF_CLASS(code) == BPF_ST) {
> - EMIT(PPC_RAW_LI(b2p[TMP_REG_1], imm));
> - src_reg = b2p[TMP_REG_1];
> - }
> - EMIT(PPC_RAW_STB(src_reg, dst_reg, off));
> - break;
> case BPF_STX | BPF_MEM | BPF_H: /* (u16 *)(dst + off) = src */
> case BPF_ST | BPF_MEM | BPF_H: /* (u16 *)(dst + off) = imm */
> - if (BPF_CLASS(code) == BPF_ST) {
> - EMIT(PPC_RAW_LI(b2p[TMP_REG_1], imm));
> - src_reg = b2p[TMP_REG_1];
> - }
> - EMIT(PPC_RAW_STH(src_reg, dst_reg, off));
> - break;
> case BPF_STX | BPF_MEM | BPF_W: /* *(u32 *)(dst + off) = src */
> case BPF_ST | BPF_MEM | BPF_W: /* *(u32 *)(dst + off) = imm */
> - if (BPF_CLASS(code) == BPF_ST) {
> - PPC_LI32(b2p[TMP_REG_1], imm);
> - src_reg = b2p[TMP_REG_1];
> - }
> - EMIT(PPC_RAW_STW(src_reg, dst_reg, off));
> - break;
You have to add the 'fallthrough;' keyword to avoid build failure with
later versions of GCC.
> case BPF_STX | BPF_MEM | BPF_DW: /* (u64 *)(dst + off) = src */
> case BPF_ST | BPF_MEM | BPF_DW: /* *(u64 *)(dst + off) = imm */
> if (BPF_CLASS(code) == BPF_ST) {
> - PPC_LI32(b2p[TMP_REG_1], imm);
> + if ((size == BPF_B) || (size == BPF_H))
> + EMIT(PPC_RAW_LI(b2p[TMP_REG_1], imm));
> + else /* size == BPF_W || size == BPF_DW */
> + PPC_LI32(b2p[TMP_REG_1], imm);
> src_reg = b2p[TMP_REG_1];
> }
> - PPC_BPF_STL(src_reg, dst_reg, off);
> +
> + switch (size) {
> + case BPF_B:
> + EMIT(PPC_RAW_STB(src_reg, dst_reg, off));
> + break;
> + case BPF_H:
> + EMIT(PPC_RAW_STH(src_reg, dst_reg, off));
> + break;
> + case BPF_W:
> + EMIT(PPC_RAW_STW(src_reg, dst_reg, off));
> + break;
> + case BPF_DW:
> + PPC_BPF_STL(src_reg, dst_reg, off);
> + break;
> + }
> break;
>
> /*
> @@ -716,25 +714,29 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, struct codegen_context *
> */
> /* dst = *(u8 *)(ul) (src + off) */
> case BPF_LDX | BPF_MEM | BPF_B:
> - EMIT(PPC_RAW_LBZ(dst_reg, src_reg, off));
> - if (insn_is_zext(&insn[i + 1]))
> - addrs[++i] = ctx->idx * 4;
> - break;
> /* dst = *(u16 *)(ul) (src + off) */
> case BPF_LDX | BPF_MEM | BPF_H:
> - EMIT(PPC_RAW_LHZ(dst_reg, src_reg, off));
> - if (insn_is_zext(&insn[i + 1]))
> - addrs[++i] = ctx->idx * 4;
> - break;
> /* dst = *(u32 *)(ul) (src + off) */
> case BPF_LDX | BPF_MEM | BPF_W:
> - EMIT(PPC_RAW_LWZ(dst_reg, src_reg, off));
> - if (insn_is_zext(&insn[i + 1]))
> - addrs[++i] = ctx->idx * 4;
> - break;
> /* dst = *(u64 *)(ul) (src + off) */
> case BPF_LDX | BPF_MEM | BPF_DW:
> - PPC_BPF_LL(dst_reg, src_reg, off);
> + switch (size) {
> + case BPF_B:
> + EMIT(PPC_RAW_LBZ(dst_reg, src_reg, off));
> + break;
> + case BPF_H:
> + EMIT(PPC_RAW_LHZ(dst_reg, src_reg, off));
> + break;
> + case BPF_W:
> + EMIT(PPC_RAW_LWZ(dst_reg, src_reg, off));
> + break;
> + case BPF_DW:
> + PPC_BPF_LL(dst_reg, src_reg, off);
> + break;
> + }
> +
> + if ((size != BPF_DW) && insn_is_zext(&insn[i + 1]))
> + addrs[++i] = ctx->idx * 4;
> break;
>
> /*
>
More information about the Linuxppc-dev
mailing list