ARM: net: bpf: improve 64-bit ALU implementation
authorRussell King <rmk+kernel@armlinux.org.uk>
Thu, 12 Jul 2018 20:50:56 +0000 (21:50 +0100)
committerDaniel Borkmann <daniel@iogearbox.net>
Fri, 13 Jul 2018 13:26:42 +0000 (15:26 +0200)
Improbe the 64-bit ALU implementation from:

  movw    r8, #65532
  movt    r8, #65535
  movw    r9, #65535
  movt    r9, #65535
  ldr     r7, [fp, #-44]
  adds    r7, r7, r8
  str     r7, [fp, #-44]
  ldr     r7, [fp, #-40]
  adc     r7, r7, r9
  str     r7, [fp, #-40]

to:

  movw    r8, #65532
  movt    r8, #65535
  movw    r9, #65535
  movt    r9, #65535
  ldrd    r6, [fp, #-44]
  adds    r6, r6, r8
  adc     r7, r7, r9
  strd    r6, [fp, #-44]

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
arch/arm/net/bpf_jit_32.c

index 026612ee8151a3e0e745f0a7cbe5a760f20c5025..25b3ee85066e16e95652b9963645dab61bcb7bbd 100644 (file)
@@ -716,11 +716,30 @@ static inline void emit_a32_alu_r(const s8 dst, const s8 src,
 static inline void emit_a32_alu_r64(const bool is64, const s8 dst[],
                                  const s8 src[], struct jit_ctx *ctx,
                                  const u8 op) {
-       emit_a32_alu_r(dst_lo, src_lo, ctx, is64, false, op);
-       if (is64)
-               emit_a32_alu_r(dst_hi, src_hi, ctx, is64, true, op);
-       else
-               emit_a32_mov_i(dst_hi, 0, ctx);
+       const s8 *tmp = bpf2a32[TMP_REG_1];
+       const s8 *tmp2 = bpf2a32[TMP_REG_2];
+       const s8 *rd;
+
+       rd = arm_bpf_get_reg64(dst, tmp, ctx);
+       if (is64) {
+               const s8 *rs;
+
+               rs = arm_bpf_get_reg64(src, tmp2, ctx);
+
+               /* ALU operation */
+               emit_alu_r(rd[1], rs[1], true, false, op, ctx);
+               emit_alu_r(rd[0], rs[0], true, true, op, ctx);
+       } else {
+               s8 rs;
+
+               rs = arm_bpf_get_reg32(src_lo, tmp2[1], ctx);
+
+               /* ALU operation */
+               emit_alu_r(rd[1], rs, true, false, op, ctx);
+               emit_a32_mov_i(rd[0], 0, ctx);
+       }
+
+       arm_bpf_put_reg64(dst, rd, ctx);
 }
 
 /* dst = src (4 bytes)*/