Skip to content

Commit 02fc01a

Browse files
Pu Lehuiborkmann
authored andcommitted
riscv, bpf: Extract emit_stx() helper
There's a lot of redundant code related to store from register operations, let's extract emit_stx() to make code more compact. Signed-off-by: Pu Lehui <[email protected]> Signed-off-by: Daniel Borkmann <[email protected]> Tested-by: Björn Töpel <[email protected]> Reviewed-by: Björn Töpel <[email protected]> Acked-by: Björn Töpel <[email protected]> Link: https://lore.kernel.org/bpf/[email protected]
1 parent 0786654 commit 02fc01a

File tree

1 file changed

+41
-131
lines changed

1 file changed

+41
-131
lines changed

arch/riscv/net/bpf_jit_comp64.c

Lines changed: 41 additions & 131 deletions
Original file line numberDiff line numberDiff line change
@@ -559,52 +559,39 @@ static int emit_load_64(bool sign_ext, u8 rd, s32 off, u8 rs, struct rv_jit_cont
559559
return ctx->ninsns - insns_start;
560560
}
561561

562-
static void emit_store_8(u8 rd, s32 off, u8 rs, struct rv_jit_context *ctx)
562+
static void emit_stx_insn(u8 rd, s16 off, u8 rs, u8 size, struct rv_jit_context *ctx)
563563
{
564-
if (is_12b_int(off)) {
564+
switch (size) {
565+
case BPF_B:
565566
emit(rv_sb(rd, off, rs), ctx);
566-
return;
567-
}
568-
569-
emit_imm(RV_REG_T1, off, ctx);
570-
emit_add(RV_REG_T1, RV_REG_T1, rd, ctx);
571-
emit(rv_sb(RV_REG_T1, 0, rs), ctx);
572-
}
573-
574-
static void emit_store_16(u8 rd, s32 off, u8 rs, struct rv_jit_context *ctx)
575-
{
576-
if (is_12b_int(off)) {
567+
break;
568+
case BPF_H:
577569
emit(rv_sh(rd, off, rs), ctx);
578-
return;
579-
}
580-
581-
emit_imm(RV_REG_T1, off, ctx);
582-
emit_add(RV_REG_T1, RV_REG_T1, rd, ctx);
583-
emit(rv_sh(RV_REG_T1, 0, rs), ctx);
584-
}
585-
586-
static void emit_store_32(u8 rd, s32 off, u8 rs, struct rv_jit_context *ctx)
587-
{
588-
if (is_12b_int(off)) {
570+
break;
571+
case BPF_W:
589572
emit_sw(rd, off, rs, ctx);
590-
return;
573+
break;
574+
case BPF_DW:
575+
emit_sd(rd, off, rs, ctx);
576+
break;
591577
}
592-
593-
emit_imm(RV_REG_T1, off, ctx);
594-
emit_add(RV_REG_T1, RV_REG_T1, rd, ctx);
595-
emit_sw(RV_REG_T1, 0, rs, ctx);
596578
}
597579

598-
static void emit_store_64(u8 rd, s32 off, u8 rs, struct rv_jit_context *ctx)
580+
static int emit_stx(u8 rd, s16 off, u8 rs, u8 size, struct rv_jit_context *ctx)
599581
{
582+
int insns_start;
583+
600584
if (is_12b_int(off)) {
601-
emit_sd(rd, off, rs, ctx);
602-
return;
585+
insns_start = ctx->ninsns;
586+
emit_stx_insn(rd, off, rs, size, ctx);
587+
return ctx->ninsns - insns_start;
603588
}
604589

605590
emit_imm(RV_REG_T1, off, ctx);
606591
emit_add(RV_REG_T1, RV_REG_T1, rd, ctx);
607-
emit_sd(RV_REG_T1, 0, rs, ctx);
592+
insns_start = ctx->ninsns;
593+
emit_stx_insn(RV_REG_T1, 0, rs, size, ctx);
594+
return ctx->ninsns - insns_start;
608595
}
609596

610597
static int emit_atomic_ld_st(u8 rd, u8 rs, const struct bpf_insn *insn,
@@ -642,20 +629,7 @@ static int emit_atomic_ld_st(u8 rd, u8 rs, const struct bpf_insn *insn,
642629
/* store_release(dst_reg + off16, src_reg) */
643630
case BPF_STORE_REL:
644631
emit_fence_rw_w(ctx);
645-
switch (BPF_SIZE(code)) {
646-
case BPF_B:
647-
emit_store_8(rd, off, rs, ctx);
648-
break;
649-
case BPF_H:
650-
emit_store_16(rd, off, rs, ctx);
651-
break;
652-
case BPF_W:
653-
emit_store_32(rd, off, rs, ctx);
654-
break;
655-
case BPF_DW:
656-
emit_store_64(rd, off, rs, ctx);
657-
break;
658-
}
632+
emit_stx(rd, off, rs, BPF_SIZE(code), ctx);
659633
break;
660634
default:
661635
pr_err_once("bpf-jit: invalid atomic load/store opcode %02x\n", imm);
@@ -2023,106 +1997,42 @@ int bpf_jit_emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx,
20231997

20241998
/* STX: *(size *)(dst + off) = src */
20251999
case BPF_STX | BPF_MEM | BPF_B:
2026-
emit_store_8(rd, off, rs, ctx);
2027-
break;
20282000
case BPF_STX | BPF_MEM | BPF_H:
2029-
emit_store_16(rd, off, rs, ctx);
2030-
break;
20312001
case BPF_STX | BPF_MEM | BPF_W:
2032-
emit_store_32(rd, off, rs, ctx);
2033-
break;
20342002
case BPF_STX | BPF_MEM | BPF_DW:
2035-
emit_store_64(rd, off, rs, ctx);
2036-
break;
2037-
case BPF_STX | BPF_ATOMIC | BPF_B:
2038-
case BPF_STX | BPF_ATOMIC | BPF_H:
2039-
case BPF_STX | BPF_ATOMIC | BPF_W:
2040-
case BPF_STX | BPF_ATOMIC | BPF_DW:
2041-
if (bpf_atomic_is_load_store(insn))
2042-
ret = emit_atomic_ld_st(rd, rs, insn, ctx);
2043-
else
2044-
ret = emit_atomic_rmw(rd, rs, insn, ctx);
2045-
if (ret)
2046-
return ret;
2047-
break;
2048-
2003+
/* STX | PROBE_MEM32: *(size *)(dst + RV_REG_ARENA + off) = src */
20492004
case BPF_STX | BPF_PROBE_MEM32 | BPF_B:
20502005
case BPF_STX | BPF_PROBE_MEM32 | BPF_H:
20512006
case BPF_STX | BPF_PROBE_MEM32 | BPF_W:
20522007
case BPF_STX | BPF_PROBE_MEM32 | BPF_DW:
20532008
{
2054-
int insn_len, insns_start;
2055-
2056-
emit_add(RV_REG_T2, rd, RV_REG_ARENA, ctx);
2057-
rd = RV_REG_T2;
2058-
2059-
switch (BPF_SIZE(code)) {
2060-
case BPF_B:
2061-
if (is_12b_int(off)) {
2062-
insns_start = ctx->ninsns;
2063-
emit(rv_sb(rd, off, rs), ctx);
2064-
insn_len = ctx->ninsns - insns_start;
2065-
break;
2066-
}
2067-
2068-
emit_imm(RV_REG_T1, off, ctx);
2069-
emit_add(RV_REG_T1, RV_REG_T1, rd, ctx);
2070-
insns_start = ctx->ninsns;
2071-
emit(rv_sb(RV_REG_T1, 0, rs), ctx);
2072-
insn_len = ctx->ninsns - insns_start;
2073-
break;
2074-
case BPF_H:
2075-
if (is_12b_int(off)) {
2076-
insns_start = ctx->ninsns;
2077-
emit(rv_sh(rd, off, rs), ctx);
2078-
insn_len = ctx->ninsns - insns_start;
2079-
break;
2080-
}
2081-
2082-
emit_imm(RV_REG_T1, off, ctx);
2083-
emit_add(RV_REG_T1, RV_REG_T1, rd, ctx);
2084-
insns_start = ctx->ninsns;
2085-
emit(rv_sh(RV_REG_T1, 0, rs), ctx);
2086-
insn_len = ctx->ninsns - insns_start;
2087-
break;
2088-
case BPF_W:
2089-
if (is_12b_int(off)) {
2090-
insns_start = ctx->ninsns;
2091-
emit_sw(rd, off, rs, ctx);
2092-
insn_len = ctx->ninsns - insns_start;
2093-
break;
2094-
}
2095-
2096-
emit_imm(RV_REG_T1, off, ctx);
2097-
emit_add(RV_REG_T1, RV_REG_T1, rd, ctx);
2098-
insns_start = ctx->ninsns;
2099-
emit_sw(RV_REG_T1, 0, rs, ctx);
2100-
insn_len = ctx->ninsns - insns_start;
2101-
break;
2102-
case BPF_DW:
2103-
if (is_12b_int(off)) {
2104-
insns_start = ctx->ninsns;
2105-
emit_sd(rd, off, rs, ctx);
2106-
insn_len = ctx->ninsns - insns_start;
2107-
break;
2108-
}
2009+
int insn_len;
21092010

2110-
emit_imm(RV_REG_T1, off, ctx);
2111-
emit_add(RV_REG_T1, RV_REG_T1, rd, ctx);
2112-
insns_start = ctx->ninsns;
2113-
emit_sd(RV_REG_T1, 0, rs, ctx);
2114-
insn_len = ctx->ninsns - insns_start;
2115-
break;
2011+
if (BPF_MODE(insn->code) == BPF_PROBE_MEM32) {
2012+
emit_add(RV_REG_T2, rd, RV_REG_ARENA, ctx);
2013+
rd = RV_REG_T2;
21162014
}
21172015

2118-
ret = add_exception_handler(insn, ctx, REG_DONT_CLEAR_MARKER,
2119-
insn_len);
2016+
insn_len = emit_stx(rd, off, rs, BPF_SIZE(code), ctx);
2017+
2018+
ret = add_exception_handler(insn, ctx, REG_DONT_CLEAR_MARKER, insn_len);
21202019
if (ret)
21212020
return ret;
2122-
21232021
break;
21242022
}
21252023

2024+
case BPF_STX | BPF_ATOMIC | BPF_B:
2025+
case BPF_STX | BPF_ATOMIC | BPF_H:
2026+
case BPF_STX | BPF_ATOMIC | BPF_W:
2027+
case BPF_STX | BPF_ATOMIC | BPF_DW:
2028+
if (bpf_atomic_is_load_store(insn))
2029+
ret = emit_atomic_ld_st(rd, rs, insn, ctx);
2030+
else
2031+
ret = emit_atomic_rmw(rd, rs, insn, ctx);
2032+
if (ret)
2033+
return ret;
2034+
break;
2035+
21262036
default:
21272037
pr_err("bpf-jit: unknown opcode %02x\n", code);
21282038
return -EINVAL;

0 commit comments

Comments
 (0)