Skip to content

Commit 118ae46

Browse files
andrea-parriAlexei Starovoitov
authored andcommitted
bpf, riscv64: Introduce emit_load_*() and emit_store_*()
We're planning to add support for the load-acquire and store-release BPF instructions. Define emit_load_<size>() and emit_store_<size>() to enable/facilitate the (re)use of their code. Acked-by: Björn Töpel <[email protected]> Reviewed-by: Pu Lehui <[email protected]> Tested-by: Björn Töpel <[email protected]> # QEMU/RVA23 Tested-by: Peilin Ye <[email protected]> Signed-off-by: Andrea Parri <[email protected]> [[email protected]: cosmetic change to commit title] Signed-off-by: Peilin Ye <[email protected]> Link: https://lore.kernel.org/r/fce89473a5748e1631d18a5917d953460d1ae0d0.1746588351.git.yepeilin@google.com Signed-off-by: Alexei Starovoitov <[email protected]>
1 parent fce7bd8 commit 118ae46

File tree

1 file changed

+143
-99
lines changed

1 file changed

+143
-99
lines changed

arch/riscv/net/bpf_jit_comp64.c

Lines changed: 143 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -473,6 +473,140 @@ static inline void emit_kcfi(u32 hash, struct rv_jit_context *ctx)
473473
emit(hash, ctx);
474474
}
475475

476+
static int emit_load_8(bool sign_ext, u8 rd, s32 off, u8 rs, struct rv_jit_context *ctx)
477+
{
478+
int insns_start;
479+
480+
if (is_12b_int(off)) {
481+
insns_start = ctx->ninsns;
482+
if (sign_ext)
483+
emit(rv_lb(rd, off, rs), ctx);
484+
else
485+
emit(rv_lbu(rd, off, rs), ctx);
486+
return ctx->ninsns - insns_start;
487+
}
488+
489+
emit_imm(RV_REG_T1, off, ctx);
490+
emit_add(RV_REG_T1, RV_REG_T1, rs, ctx);
491+
insns_start = ctx->ninsns;
492+
if (sign_ext)
493+
emit(rv_lb(rd, 0, RV_REG_T1), ctx);
494+
else
495+
emit(rv_lbu(rd, 0, RV_REG_T1), ctx);
496+
return ctx->ninsns - insns_start;
497+
}
498+
499+
static int emit_load_16(bool sign_ext, u8 rd, s32 off, u8 rs, struct rv_jit_context *ctx)
500+
{
501+
int insns_start;
502+
503+
if (is_12b_int(off)) {
504+
insns_start = ctx->ninsns;
505+
if (sign_ext)
506+
emit(rv_lh(rd, off, rs), ctx);
507+
else
508+
emit(rv_lhu(rd, off, rs), ctx);
509+
return ctx->ninsns - insns_start;
510+
}
511+
512+
emit_imm(RV_REG_T1, off, ctx);
513+
emit_add(RV_REG_T1, RV_REG_T1, rs, ctx);
514+
insns_start = ctx->ninsns;
515+
if (sign_ext)
516+
emit(rv_lh(rd, 0, RV_REG_T1), ctx);
517+
else
518+
emit(rv_lhu(rd, 0, RV_REG_T1), ctx);
519+
return ctx->ninsns - insns_start;
520+
}
521+
522+
static int emit_load_32(bool sign_ext, u8 rd, s32 off, u8 rs, struct rv_jit_context *ctx)
523+
{
524+
int insns_start;
525+
526+
if (is_12b_int(off)) {
527+
insns_start = ctx->ninsns;
528+
if (sign_ext)
529+
emit(rv_lw(rd, off, rs), ctx);
530+
else
531+
emit(rv_lwu(rd, off, rs), ctx);
532+
return ctx->ninsns - insns_start;
533+
}
534+
535+
emit_imm(RV_REG_T1, off, ctx);
536+
emit_add(RV_REG_T1, RV_REG_T1, rs, ctx);
537+
insns_start = ctx->ninsns;
538+
if (sign_ext)
539+
emit(rv_lw(rd, 0, RV_REG_T1), ctx);
540+
else
541+
emit(rv_lwu(rd, 0, RV_REG_T1), ctx);
542+
return ctx->ninsns - insns_start;
543+
}
544+
545+
static int emit_load_64(bool sign_ext, u8 rd, s32 off, u8 rs, struct rv_jit_context *ctx)
546+
{
547+
int insns_start;
548+
549+
if (is_12b_int(off)) {
550+
insns_start = ctx->ninsns;
551+
emit_ld(rd, off, rs, ctx);
552+
return ctx->ninsns - insns_start;
553+
}
554+
555+
emit_imm(RV_REG_T1, off, ctx);
556+
emit_add(RV_REG_T1, RV_REG_T1, rs, ctx);
557+
insns_start = ctx->ninsns;
558+
emit_ld(rd, 0, RV_REG_T1, ctx);
559+
return ctx->ninsns - insns_start;
560+
}
561+
562+
static void emit_store_8(u8 rd, s32 off, u8 rs, struct rv_jit_context *ctx)
563+
{
564+
if (is_12b_int(off)) {
565+
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)) {
577+
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)) {
589+
emit_sw(rd, off, rs, ctx);
590+
return;
591+
}
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);
596+
}
597+
598+
static void emit_store_64(u8 rd, s32 off, u8 rs, struct rv_jit_context *ctx)
599+
{
600+
if (is_12b_int(off)) {
601+
emit_sd(rd, off, rs, ctx);
602+
return;
603+
}
604+
605+
emit_imm(RV_REG_T1, off, ctx);
606+
emit_add(RV_REG_T1, RV_REG_T1, rd, ctx);
607+
emit_sd(RV_REG_T1, 0, rs, ctx);
608+
}
609+
476610
static void emit_atomic(u8 rd, u8 rs, s16 off, s32 imm, bool is64,
477611
struct rv_jit_context *ctx)
478612
{
@@ -1650,8 +1784,8 @@ int bpf_jit_emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx,
16501784
case BPF_LDX | BPF_PROBE_MEM32 | BPF_W:
16511785
case BPF_LDX | BPF_PROBE_MEM32 | BPF_DW:
16521786
{
1653-
int insn_len, insns_start;
16541787
bool sign_ext;
1788+
int insn_len;
16551789

16561790
sign_ext = BPF_MODE(insn->code) == BPF_MEMSX ||
16571791
BPF_MODE(insn->code) == BPF_PROBE_MEMSX;
@@ -1663,78 +1797,16 @@ int bpf_jit_emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx,
16631797

16641798
switch (BPF_SIZE(code)) {
16651799
case BPF_B:
1666-
if (is_12b_int(off)) {
1667-
insns_start = ctx->ninsns;
1668-
if (sign_ext)
1669-
emit(rv_lb(rd, off, rs), ctx);
1670-
else
1671-
emit(rv_lbu(rd, off, rs), ctx);
1672-
insn_len = ctx->ninsns - insns_start;
1673-
break;
1674-
}
1675-
1676-
emit_imm(RV_REG_T1, off, ctx);
1677-
emit_add(RV_REG_T1, RV_REG_T1, rs, ctx);
1678-
insns_start = ctx->ninsns;
1679-
if (sign_ext)
1680-
emit(rv_lb(rd, 0, RV_REG_T1), ctx);
1681-
else
1682-
emit(rv_lbu(rd, 0, RV_REG_T1), ctx);
1683-
insn_len = ctx->ninsns - insns_start;
1800+
insn_len = emit_load_8(sign_ext, rd, off, rs, ctx);
16841801
break;
16851802
case BPF_H:
1686-
if (is_12b_int(off)) {
1687-
insns_start = ctx->ninsns;
1688-
if (sign_ext)
1689-
emit(rv_lh(rd, off, rs), ctx);
1690-
else
1691-
emit(rv_lhu(rd, off, rs), ctx);
1692-
insn_len = ctx->ninsns - insns_start;
1693-
break;
1694-
}
1695-
1696-
emit_imm(RV_REG_T1, off, ctx);
1697-
emit_add(RV_REG_T1, RV_REG_T1, rs, ctx);
1698-
insns_start = ctx->ninsns;
1699-
if (sign_ext)
1700-
emit(rv_lh(rd, 0, RV_REG_T1), ctx);
1701-
else
1702-
emit(rv_lhu(rd, 0, RV_REG_T1), ctx);
1703-
insn_len = ctx->ninsns - insns_start;
1803+
insn_len = emit_load_16(sign_ext, rd, off, rs, ctx);
17041804
break;
17051805
case BPF_W:
1706-
if (is_12b_int(off)) {
1707-
insns_start = ctx->ninsns;
1708-
if (sign_ext)
1709-
emit(rv_lw(rd, off, rs), ctx);
1710-
else
1711-
emit(rv_lwu(rd, off, rs), ctx);
1712-
insn_len = ctx->ninsns - insns_start;
1713-
break;
1714-
}
1715-
1716-
emit_imm(RV_REG_T1, off, ctx);
1717-
emit_add(RV_REG_T1, RV_REG_T1, rs, ctx);
1718-
insns_start = ctx->ninsns;
1719-
if (sign_ext)
1720-
emit(rv_lw(rd, 0, RV_REG_T1), ctx);
1721-
else
1722-
emit(rv_lwu(rd, 0, RV_REG_T1), ctx);
1723-
insn_len = ctx->ninsns - insns_start;
1806+
insn_len = emit_load_32(sign_ext, rd, off, rs, ctx);
17241807
break;
17251808
case BPF_DW:
1726-
if (is_12b_int(off)) {
1727-
insns_start = ctx->ninsns;
1728-
emit_ld(rd, off, rs, ctx);
1729-
insn_len = ctx->ninsns - insns_start;
1730-
break;
1731-
}
1732-
1733-
emit_imm(RV_REG_T1, off, ctx);
1734-
emit_add(RV_REG_T1, RV_REG_T1, rs, ctx);
1735-
insns_start = ctx->ninsns;
1736-
emit_ld(rd, 0, RV_REG_T1, ctx);
1737-
insn_len = ctx->ninsns - insns_start;
1809+
insn_len = emit_load_64(sign_ext, rd, off, rs, ctx);
17381810
break;
17391811
}
17401812

@@ -1879,44 +1951,16 @@ int bpf_jit_emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx,
18791951

18801952
/* STX: *(size *)(dst + off) = src */
18811953
case BPF_STX | BPF_MEM | BPF_B:
1882-
if (is_12b_int(off)) {
1883-
emit(rv_sb(rd, off, rs), ctx);
1884-
break;
1885-
}
1886-
1887-
emit_imm(RV_REG_T1, off, ctx);
1888-
emit_add(RV_REG_T1, RV_REG_T1, rd, ctx);
1889-
emit(rv_sb(RV_REG_T1, 0, rs), ctx);
1954+
emit_store_8(rd, off, rs, ctx);
18901955
break;
18911956
case BPF_STX | BPF_MEM | BPF_H:
1892-
if (is_12b_int(off)) {
1893-
emit(rv_sh(rd, off, rs), ctx);
1894-
break;
1895-
}
1896-
1897-
emit_imm(RV_REG_T1, off, ctx);
1898-
emit_add(RV_REG_T1, RV_REG_T1, rd, ctx);
1899-
emit(rv_sh(RV_REG_T1, 0, rs), ctx);
1957+
emit_store_16(rd, off, rs, ctx);
19001958
break;
19011959
case BPF_STX | BPF_MEM | BPF_W:
1902-
if (is_12b_int(off)) {
1903-
emit_sw(rd, off, rs, ctx);
1904-
break;
1905-
}
1906-
1907-
emit_imm(RV_REG_T1, off, ctx);
1908-
emit_add(RV_REG_T1, RV_REG_T1, rd, ctx);
1909-
emit_sw(RV_REG_T1, 0, rs, ctx);
1960+
emit_store_32(rd, off, rs, ctx);
19101961
break;
19111962
case BPF_STX | BPF_MEM | BPF_DW:
1912-
if (is_12b_int(off)) {
1913-
emit_sd(rd, off, rs, ctx);
1914-
break;
1915-
}
1916-
1917-
emit_imm(RV_REG_T1, off, ctx);
1918-
emit_add(RV_REG_T1, RV_REG_T1, rd, ctx);
1919-
emit_sd(RV_REG_T1, 0, rs, ctx);
1963+
emit_store_64(rd, off, rs, ctx);
19201964
break;
19211965
case BPF_STX | BPF_ATOMIC | BPF_W:
19221966
case BPF_STX | BPF_ATOMIC | BPF_DW:

0 commit comments

Comments
 (0)