Skip to content

Commit 30651cf

Browse files
chenhengqigregkh
authored andcommitted
LoongArch, bpf: Use 4 instructions for function address in JIT
[ Upstream commit 64f50f6 ] This patch fixes the following issue of function calls in JIT, like: [ 29.346981] multi-func JIT bug 105 != 103 The issus can be reproduced by running the "inline simple bpf_loop call" verifier test. This is because we are emiting 2-4 instructions for 64-bit immediate moves. During the first pass of JIT, the placeholder address is zero, emiting two instructions for it. In the extra pass, the function address is in XKVRANGE, emiting four instructions for it. This change the instruction index in JIT context. Let's always use 4 instructions for function address in JIT. So that the instruction sequences don't change between the first pass and the extra pass for function calls. Fixes: 5dc6155 ("LoongArch: Add BPF JIT support") Signed-off-by: Hengqi Chen <hengqi.chen@gmail.com> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Tested-by: Tiezhu Yang <yangtiezhu@loongson.cn> Link: https://lore.kernel.org/bpf/20230214152633.2265699-1-hengqi.chen@gmail.com Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent cecc685 commit 30651cf

2 files changed

Lines changed: 22 additions & 1 deletion

File tree

arch/loongarch/net/bpf_jit.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -782,7 +782,7 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, bool ext
782782
if (ret < 0)
783783
return ret;
784784

785-
move_imm(ctx, t1, func_addr, is32);
785+
move_addr(ctx, t1, func_addr);
786786
emit_insn(ctx, jirl, t1, LOONGARCH_GPR_RA, 0);
787787
move_reg(ctx, regmap[BPF_REG_0], LOONGARCH_GPR_A0);
788788
break;

arch/loongarch/net/bpf_jit.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,27 @@ static inline void emit_sext_32(struct jit_ctx *ctx, enum loongarch_gpr reg, boo
8080
emit_insn(ctx, addiw, reg, reg, 0);
8181
}
8282

83+
static inline void move_addr(struct jit_ctx *ctx, enum loongarch_gpr rd, u64 addr)
84+
{
85+
u64 imm_11_0, imm_31_12, imm_51_32, imm_63_52;
86+
87+
/* lu12iw rd, imm_31_12 */
88+
imm_31_12 = (addr >> 12) & 0xfffff;
89+
emit_insn(ctx, lu12iw, rd, imm_31_12);
90+
91+
/* ori rd, rd, imm_11_0 */
92+
imm_11_0 = addr & 0xfff;
93+
emit_insn(ctx, ori, rd, rd, imm_11_0);
94+
95+
/* lu32id rd, imm_51_32 */
96+
imm_51_32 = (addr >> 32) & 0xfffff;
97+
emit_insn(ctx, lu32id, rd, imm_51_32);
98+
99+
/* lu52id rd, rd, imm_63_52 */
100+
imm_63_52 = (addr >> 52) & 0xfff;
101+
emit_insn(ctx, lu52id, rd, rd, imm_63_52);
102+
}
103+
83104
static inline void move_imm(struct jit_ctx *ctx, enum loongarch_gpr rd, long imm, bool is32)
84105
{
85106
long imm_11_0, imm_31_12, imm_51_32, imm_63_52, imm_51_0, imm_51_31;

0 commit comments

Comments
 (0)