Skip to content
This repository has been archived by the owner on Sep 24, 2020. It is now read-only.

Commit

Permalink
ARM: net: bpf: avoid 'bx' instruction on non-Thumb capable CPUs
Browse files Browse the repository at this point in the history
Avoid the 'bx' instruction on CPUs that have no support for Thumb and
thus do not implement this instruction by moving the generation of this
opcode to a separate function that selects between:

	bx	reg

and

	mov	pc, reg

according to the capabilities of the CPU.

Fixes: 39c13c2 ("arm: eBPF JIT compiler")
Signed-off-by: Russell King <[email protected]>
  • Loading branch information
Russell King committed Jan 17, 2018
1 parent 36b0cb8 commit e906248
Showing 1 changed file with 11 additions and 7 deletions.
18 changes: 11 additions & 7 deletions arch/arm/net/bpf_jit_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -285,16 +285,20 @@ static inline void emit_mov_i(const u8 rd, u32 val, struct jit_ctx *ctx)
emit_mov_i_no8m(rd, val, ctx);
}

static inline void emit_blx_r(u8 tgt_reg, struct jit_ctx *ctx)
static void emit_bx_r(u8 tgt_reg, struct jit_ctx *ctx)
{
ctx->seen |= SEEN_CALL;
#if __LINUX_ARM_ARCH__ < 5
emit(ARM_MOV_R(ARM_LR, ARM_PC), ctx);

if (elf_hwcap & HWCAP_THUMB)
emit(ARM_BX(tgt_reg), ctx);
else
emit(ARM_MOV_R(ARM_PC, tgt_reg), ctx);
}

static inline void emit_blx_r(u8 tgt_reg, struct jit_ctx *ctx)
{
ctx->seen |= SEEN_CALL;
#if __LINUX_ARM_ARCH__ < 5
emit(ARM_MOV_R(ARM_LR, ARM_PC), ctx);
emit_bx_r(tgt_reg, ctx);
#else
emit(ARM_BLX_R(tgt_reg), ctx);
#endif
Expand Down Expand Up @@ -997,7 +1001,7 @@ static int emit_bpf_tail_call(struct jit_ctx *ctx)
emit_a32_mov_i(tmp2[1], off, false, ctx);
emit(ARM_LDR_R(tmp[1], tmp[1], tmp2[1]), ctx);
emit(ARM_ADD_I(tmp[1], tmp[1], ctx->prologue_bytes), ctx);
emit(ARM_BX(tmp[1]), ctx);
emit_bx_r(tmp[1], ctx);

/* out: */
if (out_offset == -1)
Expand Down Expand Up @@ -1166,7 +1170,7 @@ static void build_epilogue(struct jit_ctx *ctx)
emit(ARM_POP(reg_set), ctx);
/* Return back to the callee function */
if (!(ctx->seen & SEEN_CALL))
emit(ARM_BX(ARM_LR), ctx);
emit_bx_r(ARM_LR, ctx);
#endif
}

Expand Down

0 comments on commit e906248

Please sign in to comment.