[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20191209173136.29615-4-bjorn.topel@gmail.com>
Date: Mon, 9 Dec 2019 18:31:31 +0100
From: Björn Töpel <bjorn.topel@...il.com>
To: daniel@...earbox.net, ast@...nel.org, netdev@...r.kernel.org
Cc: Björn Töpel <bjorn.topel@...il.com>,
linux-riscv@...ts.infradead.org, bpf@...r.kernel.org
Subject: [PATCH bpf-next 3/8] riscv, bpf: add support for far jumps and exits
This commit add support for far (offset > 21b) jumps and exits.
Signed-off-by: Björn Töpel <bjorn.topel@...il.com>
---
arch/riscv/net/bpf_jit_comp.c | 37 ++++++++++++++++-------------------
1 file changed, 17 insertions(+), 20 deletions(-)
diff --git a/arch/riscv/net/bpf_jit_comp.c b/arch/riscv/net/bpf_jit_comp.c
index e2f6724b64f7..e9cc9832ac2c 100644
--- a/arch/riscv/net/bpf_jit_comp.c
+++ b/arch/riscv/net/bpf_jit_comp.c
@@ -506,16 +506,6 @@ static int is_13b_check(int off, int insn)
return 0;
}
-static int is_21b_check(int off, int insn)
-{
- if (!is_21b_int(off)) {
- pr_err("bpf-jit: insn=%d 21b < offset=%d not supported yet!\n",
- insn, (int)off);
- return -1;
- }
- return 0;
-}
-
static void emit_imm(u8 rd, s64 val, struct rv_jit_context *ctx)
{
/* Note that the immediate from the add is sign-extended,
@@ -733,6 +723,21 @@ static void emit_sext_32_rd(u8 *rd, struct rv_jit_context *ctx)
*rd = RV_REG_T2;
}
+static void emit_jump_and_link(u8 rd, int rvoff, struct rv_jit_context *ctx)
+{
+ s64 upper, lower;
+
+ if (is_21b_int(rvoff)) {
+ emit(rv_jal(rd, rvoff >> 1), ctx);
+ return;
+ }
+
+ upper = (rvoff + (1 << 11)) >> 12;
+ lower = rvoff & 0xfff;
+ emit(rv_auipc(RV_REG_T1, upper), ctx);
+ emit(rv_jalr(rd, RV_REG_T1, lower), ctx);
+}
+
/* return -1 or inverted cond */
static int invert_bpf_cond(u8 cond)
{
@@ -1117,13 +1122,7 @@ static int emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx,
/* JUMP off */
case BPF_JMP | BPF_JA:
rvoff = rv_offset(i, off, ctx);
- if (!is_21b_int(rvoff)) {
- pr_err("bpf-jit: insn=%d offset=%d not supported yet!\n",
- i, rvoff);
- return -1;
- }
-
- emit(rv_jal(RV_REG_ZERO, rvoff >> 1), ctx);
+ emit_jump_and_link(RV_REG_ZERO, rvoff, ctx);
break;
/* IF (dst COND src) JUMP off */
@@ -1261,9 +1260,7 @@ static int emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx,
break;
rvoff = epilogue_offset(ctx);
- if (is_21b_check(rvoff, i))
- return -1;
- emit(rv_jal(RV_REG_ZERO, rvoff >> 1), ctx);
+ emit_jump_and_link(RV_REG_ZERO, rvoff, ctx);
break;
/* dst = imm64 */
--
2.20.1
Powered by blists - more mailing lists