Skip to content

Commit c5eae69

Browse files
Russell Kingborkmann
Russell King
authored andcommitted
ARM: net: bpf: improve 64-bit store implementation
Improve the 64-bit store implementation from: ldr r6, [fp, #-8] str r8, [r6] ldr r6, [fp, #-8] mov r7, #4 add r7, r6, r7 str r9, [r7] to: ldr r6, [fp, #-8] str r8, [r6] str r9, [r6, #4] We leave the store as two separate STR instructions rather than using STRD as the store may not be aligned, and STR can handle misalignment. Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
1 parent 077513b commit c5eae69

File tree

1 file changed

+26
-26
lines changed

1 file changed

+26
-26
lines changed

arch/arm/net/bpf_jit_32.c

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -975,29 +975,42 @@ static inline void emit_a32_mul_r64(const s8 dst[], const s8 src[],
975975
}
976976

977977
/* *(size *)(dst + off) = src */
978-
static inline void emit_str_r(const s8 dst, const s8 src,
979-
const s32 off, struct jit_ctx *ctx, const u8 sz){
978+
static inline void emit_str_r(const s8 dst, const s8 src[],
979+
s32 off, struct jit_ctx *ctx, const u8 sz){
980980
const s8 *tmp = bpf2a32[TMP_REG_1];
981+
s32 off_max;
981982
s8 rd;
982983

983984
rd = arm_bpf_get_reg32(dst, tmp[1], ctx);
984-
if (off) {
985+
986+
if (sz == BPF_H)
987+
off_max = 0xff;
988+
else
989+
off_max = 0xfff;
990+
991+
if (off < 0 || off > off_max) {
985992
emit_a32_mov_i(tmp[0], off, ctx);
986-
emit(ARM_ADD_R(tmp[0], rd, tmp[0]), ctx);
993+
emit(ARM_ADD_R(tmp[0], tmp[0], rd), ctx);
987994
rd = tmp[0];
995+
off = 0;
988996
}
989997
switch (sz) {
990-
case BPF_W:
991-
/* Store a Word */
992-
emit(ARM_STR_I(src, rd, 0), ctx);
998+
case BPF_B:
999+
/* Store a Byte */
1000+
emit(ARM_STRB_I(src_lo, rd, off), ctx);
9931001
break;
9941002
case BPF_H:
9951003
/* Store a HalfWord */
996-
emit(ARM_STRH_I(src, rd, 0), ctx);
1004+
emit(ARM_STRH_I(src_lo, rd, off), ctx);
9971005
break;
998-
case BPF_B:
999-
/* Store a Byte */
1000-
emit(ARM_STRB_I(src, rd, 0), ctx);
1006+
case BPF_W:
1007+
/* Store a Word */
1008+
emit(ARM_STR_I(src_lo, rd, off), ctx);
1009+
break;
1010+
case BPF_DW:
1011+
/* Store a Double Word */
1012+
emit(ARM_STR_I(src_lo, rd, off), ctx);
1013+
emit(ARM_STR_I(src_hi, rd, off + 4), ctx);
10011014
break;
10021015
}
10031016
}
@@ -1539,16 +1552,14 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
15391552
case BPF_DW:
15401553
/* Sign-extend immediate value into temp reg */
15411554
emit_a32_mov_se_i64(true, tmp2, imm, ctx);
1542-
emit_str_r(dst_lo, tmp2[1], off, ctx, BPF_W);
1543-
emit_str_r(dst_lo, tmp2[0], off+4, ctx, BPF_W);
15441555
break;
15451556
case BPF_W:
15461557
case BPF_H:
15471558
case BPF_B:
15481559
emit_a32_mov_i(tmp2[1], imm, ctx);
1549-
emit_str_r(dst_lo, tmp2[1], off, ctx, BPF_SIZE(code));
15501560
break;
15511561
}
1562+
emit_str_r(dst_lo, tmp2, off, ctx, BPF_SIZE(code));
15521563
break;
15531564
/* STX XADD: lock *(u32 *)(dst + off) += src */
15541565
case BPF_STX | BPF_XADD | BPF_W:
@@ -1560,20 +1571,9 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
15601571
case BPF_STX | BPF_MEM | BPF_H:
15611572
case BPF_STX | BPF_MEM | BPF_B:
15621573
case BPF_STX | BPF_MEM | BPF_DW:
1563-
{
1564-
u8 sz = BPF_SIZE(code);
1565-
15661574
rs = arm_bpf_get_reg64(src, tmp2, ctx);
1567-
1568-
/* Store the value */
1569-
if (BPF_SIZE(code) == BPF_DW) {
1570-
emit_str_r(dst_lo, rs[1], off, ctx, BPF_W);
1571-
emit_str_r(dst_lo, rs[0], off+4, ctx, BPF_W);
1572-
} else {
1573-
emit_str_r(dst_lo, rs[1], off, ctx, sz);
1574-
}
1575+
emit_str_r(dst_lo, rs, off, ctx, BPF_SIZE(code));
15751576
break;
1576-
}
15771577
/* PC += off if dst == src */
15781578
/* PC += off if dst > src */
15791579
/* PC += off if dst >= src */

0 commit comments

Comments
 (0)