]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
riscv, bpf: Extract emit_ldx() helper
authorPu Lehui <pulehui@huawei.com>
Sat, 19 Jul 2025 09:17:23 +0000 (09:17 +0000)
committerDaniel Borkmann <daniel@iogearbox.net>
Fri, 15 Aug 2025 08:46:51 +0000 (10:46 +0200)
There's a lot of redundant code related to load into register
operations, let's extract emit_ldx() to make code more compact.

Signed-off-by: Pu Lehui <pulehui@huawei.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Tested-by: Björn Töpel <bjorn@rivosinc.com>
Reviewed-by: Björn Töpel <bjorn@rivosinc.com>
Acked-by: Björn Töpel <bjorn@kernel.org>
Link: https://lore.kernel.org/bpf/20250719091730.2660197-4-pulehui@huaweicloud.com
arch/riscv/net/bpf_jit_comp64.c

index 5e354f686ea3b3741148fea7d208ea1f21551e05..a6a9fd9193e5e42833f8999767092c1214880ed5 100644 (file)
@@ -473,90 +473,24 @@ static inline void emit_kcfi(u32 hash, struct rv_jit_context *ctx)
                emit(hash, ctx);
 }
 
-static int emit_load_8(bool sign_ext, u8 rd, s32 off, u8 rs, struct rv_jit_context *ctx)
+static void emit_ldx_insn(u8 rd, s16 off, u8 rs, u8 size, bool sign_ext,
+                         struct rv_jit_context *ctx)
 {
-       int insns_start;
-
-       if (is_12b_int(off)) {
-               insns_start = ctx->ninsns;
-               if (sign_ext)
-                       emit(rv_lb(rd, off, rs), ctx);
-               else
-                       emit(rv_lbu(rd, off, rs), ctx);
-               return ctx->ninsns - insns_start;
-       }
-
-       emit_imm(RV_REG_T1, off, ctx);
-       emit_add(RV_REG_T1, RV_REG_T1, rs, ctx);
-       insns_start = ctx->ninsns;
-       if (sign_ext)
-               emit(rv_lb(rd, 0, RV_REG_T1), ctx);
-       else
-               emit(rv_lbu(rd, 0, RV_REG_T1), ctx);
-       return ctx->ninsns - insns_start;
-}
-
-static int emit_load_16(bool sign_ext, u8 rd, s32 off, u8 rs, struct rv_jit_context *ctx)
-{
-       int insns_start;
-
-       if (is_12b_int(off)) {
-               insns_start = ctx->ninsns;
-               if (sign_ext)
-                       emit(rv_lh(rd, off, rs), ctx);
-               else
-                       emit(rv_lhu(rd, off, rs), ctx);
-               return ctx->ninsns - insns_start;
-       }
-
-       emit_imm(RV_REG_T1, off, ctx);
-       emit_add(RV_REG_T1, RV_REG_T1, rs, ctx);
-       insns_start = ctx->ninsns;
-       if (sign_ext)
-               emit(rv_lh(rd, 0, RV_REG_T1), ctx);
-       else
-               emit(rv_lhu(rd, 0, RV_REG_T1), ctx);
-       return ctx->ninsns - insns_start;
-}
-
-static int emit_load_32(bool sign_ext, u8 rd, s32 off, u8 rs, struct rv_jit_context *ctx)
-{
-       int insns_start;
-
-       if (is_12b_int(off)) {
-               insns_start = ctx->ninsns;
-               if (sign_ext)
-                       emit(rv_lw(rd, off, rs), ctx);
-               else
-                       emit(rv_lwu(rd, off, rs), ctx);
-               return ctx->ninsns - insns_start;
-       }
-
-       emit_imm(RV_REG_T1, off, ctx);
-       emit_add(RV_REG_T1, RV_REG_T1, rs, ctx);
-       insns_start = ctx->ninsns;
-       if (sign_ext)
-               emit(rv_lw(rd, 0, RV_REG_T1), ctx);
-       else
-               emit(rv_lwu(rd, 0, RV_REG_T1), ctx);
-       return ctx->ninsns - insns_start;
-}
-
-static int emit_load_64(bool sign_ext, u8 rd, s32 off, u8 rs, struct rv_jit_context *ctx)
-{
-       int insns_start;
-
-       if (is_12b_int(off)) {
-               insns_start = ctx->ninsns;
+       switch (size) {
+       case BPF_B:
+               emit(sign_ext ? rv_lb(rd, off, rs) : rv_lbu(rd, off, rs), ctx);
+               break;
+       case BPF_H:
+               emit(sign_ext ? rv_lh(rd, off, rs) : rv_lhu(rd, off, rs), ctx);
+               break;
+       case BPF_W:
+               emit(sign_ext ? rv_lw(rd, off, rs) : rv_lwu(rd, off, rs), ctx);
+               break;
+       case BPF_DW:
                emit_ld(rd, off, rs, ctx);
-               return ctx->ninsns - insns_start;
+               break;
        }
 
-       emit_imm(RV_REG_T1, off, ctx);
-       emit_add(RV_REG_T1, RV_REG_T1, rs, ctx);
-       insns_start = ctx->ninsns;
-       emit_ld(rd, 0, RV_REG_T1, ctx);
-       return ctx->ninsns - insns_start;
 }
 
 static void emit_stx_insn(u8 rd, s16 off, u8 rs, u8 size, struct rv_jit_context *ctx)
@@ -577,6 +511,24 @@ static void emit_stx_insn(u8 rd, s16 off, u8 rs, u8 size, struct rv_jit_context
        }
 }
 
+static int emit_ldx(u8 rd, s16 off, u8 rs, u8 size, bool sign_ext,
+                   struct rv_jit_context *ctx)
+{
+       int insns_start;
+
+       if (is_12b_int(off)) {
+               insns_start = ctx->ninsns;
+               emit_ldx_insn(rd, off, rs, size, sign_ext, ctx);
+               return ctx->ninsns - insns_start;
+       }
+
+       emit_imm(RV_REG_T1, off, ctx);
+       emit_add(RV_REG_T1, RV_REG_T1, rs, ctx);
+       insns_start = ctx->ninsns;
+       emit_ldx_insn(rd, 0, RV_REG_T1, size, sign_ext, ctx);
+       return ctx->ninsns - insns_start;
+}
+
 static int emit_st(u8 rd, s16 off, s32 imm, u8 size, struct rv_jit_context *ctx)
 {
        int insns_start;
@@ -622,20 +574,7 @@ static int emit_atomic_ld_st(u8 rd, u8 rs, const struct bpf_insn *insn,
        switch (imm) {
        /* dst_reg = load_acquire(src_reg + off16) */
        case BPF_LOAD_ACQ:
-               switch (BPF_SIZE(code)) {
-               case BPF_B:
-                       emit_load_8(false, rd, off, rs, ctx);
-                       break;
-               case BPF_H:
-                       emit_load_16(false, rd, off, rs, ctx);
-                       break;
-               case BPF_W:
-                       emit_load_32(false, rd, off, rs, ctx);
-                       break;
-               case BPF_DW:
-                       emit_load_64(false, rd, off, rs, ctx);
-                       break;
-               }
+               emit_ldx(rd, off, rs, BPF_SIZE(code), false, ctx);
                emit_fence_r_rw(ctx);
 
                /* If our next insn is a redundant zext, return 1 to tell
@@ -1859,20 +1798,7 @@ int bpf_jit_emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx,
                        rs = RV_REG_T2;
                }
 
-               switch (BPF_SIZE(code)) {
-               case BPF_B:
-                       insn_len = emit_load_8(sign_ext, rd, off, rs, ctx);
-                       break;
-               case BPF_H:
-                       insn_len = emit_load_16(sign_ext, rd, off, rs, ctx);
-                       break;
-               case BPF_W:
-                       insn_len = emit_load_32(sign_ext, rd, off, rs, ctx);
-                       break;
-               case BPF_DW:
-                       insn_len = emit_load_64(sign_ext, rd, off, rs, ctx);
-                       break;
-               }
+               insn_len = emit_ldx(rd, off, rs, BPF_SIZE(code), sign_ext, ctx);
 
                ret = add_exception_handler(insn, ctx, rd, insn_len);
                if (ret)
@@ -1882,6 +1808,7 @@ int bpf_jit_emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx,
                        return 1;
                break;
        }
+
        /* speculation barrier */
        case BPF_ST | BPF_NOSPEC:
                break;