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 <hbath...@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;
/*

Reply via email to