Skip to content

Commit f9ff501

Browse files
Russell Kingborkmann
Russell King
authored andcommitted
ARM: net: bpf: improve 64-bit load immediate implementation
Rather than writing each 32-bit half of the 64-bit immediate value separately when the register is on the stack: movw r6, #45056 ; 0xb000 movt r6, #60979 ; 0xee33 str r6, [fp, #-44] ; 0xffffffd4 mov r6, #0 str r6, [fp, #-40] ; 0xffffffd8 arrange to use the double-word store when available instead: movw r6, #45056 ; 0xb000 movt r6, #60979 ; 0xee33 mov r7, #0 strd r6, [fp, #-44] ; 0xffffffd4 Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
1 parent 6fd0666 commit f9ff501

File tree

1 file changed

+20
-12
lines changed

1 file changed

+20
-12
lines changed

arch/arm/net/bpf_jit_32.c

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -599,9 +599,20 @@ static inline void emit_a32_mov_i(const s8 dst, const u32 val,
599599
}
600600
}
601601

602+
static void emit_a32_mov_i64(const s8 dst[], u64 val, struct jit_ctx *ctx)
603+
{
604+
const s8 *tmp = bpf2a32[TMP_REG_1];
605+
const s8 *rd = is_stacked(dst_lo) ? tmp : dst;
606+
607+
emit_mov_i(rd[1], (u32)val, ctx);
608+
emit_mov_i(rd[0], val >> 32, ctx);
609+
610+
arm_bpf_put_reg64(dst, rd, ctx);
611+
}
612+
602613
/* Sign extended move */
603-
static inline void emit_a32_mov_i64(const bool is64, const s8 dst[],
604-
const u32 val, struct jit_ctx *ctx) {
614+
static inline void emit_a32_mov_se_i64(const bool is64, const s8 dst[],
615+
const u32 val, struct jit_ctx *ctx) {
605616
u32 hi = 0;
606617

607618
if (is64 && (val & (1<<31)))
@@ -1309,7 +1320,7 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
13091320
break;
13101321
case BPF_K:
13111322
/* Sign-extend immediate value to destination reg */
1312-
emit_a32_mov_i64(is64, dst, imm, ctx);
1323+
emit_a32_mov_se_i64(is64, dst, imm, ctx);
13131324
break;
13141325
}
13151326
break;
@@ -1358,7 +1369,7 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
13581369
* value into temporary reg and then it would be
13591370
* safe to do the operation on it.
13601371
*/
1361-
emit_a32_mov_i64(is64, tmp2, imm, ctx);
1372+
emit_a32_mov_se_i64(is64, tmp2, imm, ctx);
13621373
emit_a32_alu_r64(is64, dst, tmp2, ctx, BPF_OP(code));
13631374
break;
13641375
}
@@ -1454,7 +1465,7 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
14541465
* reg then it would be safe to do the operation
14551466
* on it.
14561467
*/
1457-
emit_a32_mov_i64(is64, tmp2, imm, ctx);
1468+
emit_a32_mov_se_i64(is64, tmp2, imm, ctx);
14581469
emit_a32_mul_r64(dst, tmp2, ctx);
14591470
break;
14601471
}
@@ -1506,12 +1517,9 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
15061517
/* dst = imm64 */
15071518
case BPF_LD | BPF_IMM | BPF_DW:
15081519
{
1509-
const struct bpf_insn insn1 = insn[1];
1510-
u32 hi, lo = imm;
1520+
u64 val = (u32)imm | (u64)insn[1].imm << 32;
15111521

1512-
hi = insn1.imm;
1513-
emit_a32_mov_i(dst_lo, lo, ctx);
1514-
emit_a32_mov_i(dst_hi, hi, ctx);
1522+
emit_a32_mov_i64(dst, val, ctx);
15151523

15161524
return 1;
15171525
}
@@ -1531,7 +1539,7 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
15311539
switch (BPF_SIZE(code)) {
15321540
case BPF_DW:
15331541
/* Sign-extend immediate value into temp reg */
1534-
emit_a32_mov_i64(true, tmp2, imm, ctx);
1542+
emit_a32_mov_se_i64(true, tmp2, imm, ctx);
15351543
emit_str_r(dst_lo, tmp2[1], off, ctx, BPF_W);
15361544
emit_str_r(dst_lo, tmp2[0], off+4, ctx, BPF_W);
15371545
break;
@@ -1620,7 +1628,7 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
16201628
rm = tmp2[0];
16211629
rn = tmp2[1];
16221630
/* Sign-extend immediate value */
1623-
emit_a32_mov_i64(true, tmp2, imm, ctx);
1631+
emit_a32_mov_se_i64(true, tmp2, imm, ctx);
16241632
go_jmp:
16251633
/* Setup destination register */
16261634
rd = arm_bpf_get_reg64(dst, tmp, ctx);

0 commit comments

Comments
 (0)