aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/net/bpf_jit_32.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/net/bpf_jit_32.c')
-rw-r--r--arch/arm/net/bpf_jit_32.c42
1 files changed, 31 insertions, 11 deletions
diff --git a/arch/arm/net/bpf_jit_32.c b/arch/arm/net/bpf_jit_32.c
index c8bfbbfdfcc3..97a6b4b2a115 100644
--- a/arch/arm/net/bpf_jit_32.c
+++ b/arch/arm/net/bpf_jit_32.c
@@ -736,7 +736,8 @@ static inline void emit_a32_alu_r64(const bool is64, const s8 dst[],
736 736
737 /* ALU operation */ 737 /* ALU operation */
738 emit_alu_r(rd[1], rs, true, false, op, ctx); 738 emit_alu_r(rd[1], rs, true, false, op, ctx);
739 emit_a32_mov_i(rd[0], 0, ctx); 739 if (!ctx->prog->aux->verifier_zext)
740 emit_a32_mov_i(rd[0], 0, ctx);
740 } 741 }
741 742
742 arm_bpf_put_reg64(dst, rd, ctx); 743 arm_bpf_put_reg64(dst, rd, ctx);
@@ -758,8 +759,9 @@ static inline void emit_a32_mov_r64(const bool is64, const s8 dst[],
758 struct jit_ctx *ctx) { 759 struct jit_ctx *ctx) {
759 if (!is64) { 760 if (!is64) {
760 emit_a32_mov_r(dst_lo, src_lo, ctx); 761 emit_a32_mov_r(dst_lo, src_lo, ctx);
761 /* Zero out high 4 bytes */ 762 if (!ctx->prog->aux->verifier_zext)
762 emit_a32_mov_i(dst_hi, 0, ctx); 763 /* Zero out high 4 bytes */
764 emit_a32_mov_i(dst_hi, 0, ctx);
763 } else if (__LINUX_ARM_ARCH__ < 6 && 765 } else if (__LINUX_ARM_ARCH__ < 6 &&
764 ctx->cpu_architecture < CPU_ARCH_ARMv5TE) { 766 ctx->cpu_architecture < CPU_ARCH_ARMv5TE) {
765 /* complete 8 byte move */ 767 /* complete 8 byte move */
@@ -1060,17 +1062,20 @@ static inline void emit_ldx_r(const s8 dst[], const s8 src,
1060 case BPF_B: 1062 case BPF_B:
1061 /* Load a Byte */ 1063 /* Load a Byte */
1062 emit(ARM_LDRB_I(rd[1], rm, off), ctx); 1064 emit(ARM_LDRB_I(rd[1], rm, off), ctx);
1063 emit_a32_mov_i(rd[0], 0, ctx); 1065 if (!ctx->prog->aux->verifier_zext)
1066 emit_a32_mov_i(rd[0], 0, ctx);
1064 break; 1067 break;
1065 case BPF_H: 1068 case BPF_H:
1066 /* Load a HalfWord */ 1069 /* Load a HalfWord */
1067 emit(ARM_LDRH_I(rd[1], rm, off), ctx); 1070 emit(ARM_LDRH_I(rd[1], rm, off), ctx);
1068 emit_a32_mov_i(rd[0], 0, ctx); 1071 if (!ctx->prog->aux->verifier_zext)
1072 emit_a32_mov_i(rd[0], 0, ctx);
1069 break; 1073 break;
1070 case BPF_W: 1074 case BPF_W:
1071 /* Load a Word */ 1075 /* Load a Word */
1072 emit(ARM_LDR_I(rd[1], rm, off), ctx); 1076 emit(ARM_LDR_I(rd[1], rm, off), ctx);
1073 emit_a32_mov_i(rd[0], 0, ctx); 1077 if (!ctx->prog->aux->verifier_zext)
1078 emit_a32_mov_i(rd[0], 0, ctx);
1074 break; 1079 break;
1075 case BPF_DW: 1080 case BPF_DW:
1076 /* Load a Double Word */ 1081 /* Load a Double Word */
@@ -1359,6 +1364,11 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
1359 case BPF_ALU64 | BPF_MOV | BPF_X: 1364 case BPF_ALU64 | BPF_MOV | BPF_X:
1360 switch (BPF_SRC(code)) { 1365 switch (BPF_SRC(code)) {
1361 case BPF_X: 1366 case BPF_X:
1367 if (imm == 1) {
1368 /* Special mov32 for zext */
1369 emit_a32_mov_i(dst_hi, 0, ctx);
1370 break;
1371 }
1362 emit_a32_mov_r64(is64, dst, src, ctx); 1372 emit_a32_mov_r64(is64, dst, src, ctx);
1363 break; 1373 break;
1364 case BPF_K: 1374 case BPF_K:
@@ -1438,7 +1448,8 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
1438 } 1448 }
1439 emit_udivmod(rd_lo, rd_lo, rt, ctx, BPF_OP(code)); 1449 emit_udivmod(rd_lo, rd_lo, rt, ctx, BPF_OP(code));
1440 arm_bpf_put_reg32(dst_lo, rd_lo, ctx); 1450 arm_bpf_put_reg32(dst_lo, rd_lo, ctx);
1441 emit_a32_mov_i(dst_hi, 0, ctx); 1451 if (!ctx->prog->aux->verifier_zext)
1452 emit_a32_mov_i(dst_hi, 0, ctx);
1442 break; 1453 break;
1443 case BPF_ALU64 | BPF_DIV | BPF_K: 1454 case BPF_ALU64 | BPF_DIV | BPF_K:
1444 case BPF_ALU64 | BPF_DIV | BPF_X: 1455 case BPF_ALU64 | BPF_DIV | BPF_X:
@@ -1453,7 +1464,8 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
1453 return -EINVAL; 1464 return -EINVAL;
1454 if (imm) 1465 if (imm)
1455 emit_a32_alu_i(dst_lo, imm, ctx, BPF_OP(code)); 1466 emit_a32_alu_i(dst_lo, imm, ctx, BPF_OP(code));
1456 emit_a32_mov_i(dst_hi, 0, ctx); 1467 if (!ctx->prog->aux->verifier_zext)
1468 emit_a32_mov_i(dst_hi, 0, ctx);
1457 break; 1469 break;
1458 /* dst = dst << imm */ 1470 /* dst = dst << imm */
1459 case BPF_ALU64 | BPF_LSH | BPF_K: 1471 case BPF_ALU64 | BPF_LSH | BPF_K:
@@ -1488,7 +1500,8 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
1488 /* dst = ~dst */ 1500 /* dst = ~dst */
1489 case BPF_ALU | BPF_NEG: 1501 case BPF_ALU | BPF_NEG:
1490 emit_a32_alu_i(dst_lo, 0, ctx, BPF_OP(code)); 1502 emit_a32_alu_i(dst_lo, 0, ctx, BPF_OP(code));
1491 emit_a32_mov_i(dst_hi, 0, ctx); 1503 if (!ctx->prog->aux->verifier_zext)
1504 emit_a32_mov_i(dst_hi, 0, ctx);
1492 break; 1505 break;
1493 /* dst = ~dst (64 bit) */ 1506 /* dst = ~dst (64 bit) */
1494 case BPF_ALU64 | BPF_NEG: 1507 case BPF_ALU64 | BPF_NEG:
@@ -1544,11 +1557,13 @@ emit_bswap_uxt:
1544#else /* ARMv6+ */ 1557#else /* ARMv6+ */
1545 emit(ARM_UXTH(rd[1], rd[1]), ctx); 1558 emit(ARM_UXTH(rd[1], rd[1]), ctx);
1546#endif 1559#endif
1547 emit(ARM_EOR_R(rd[0], rd[0], rd[0]), ctx); 1560 if (!ctx->prog->aux->verifier_zext)
1561 emit(ARM_EOR_R(rd[0], rd[0], rd[0]), ctx);
1548 break; 1562 break;
1549 case 32: 1563 case 32:
1550 /* zero-extend 32 bits into 64 bits */ 1564 /* zero-extend 32 bits into 64 bits */
1551 emit(ARM_EOR_R(rd[0], rd[0], rd[0]), ctx); 1565 if (!ctx->prog->aux->verifier_zext)
1566 emit(ARM_EOR_R(rd[0], rd[0], rd[0]), ctx);
1552 break; 1567 break;
1553 case 64: 1568 case 64:
1554 /* nop */ 1569 /* nop */
@@ -1838,6 +1853,11 @@ void bpf_jit_compile(struct bpf_prog *prog)
1838 /* Nothing to do here. We support Internal BPF. */ 1853 /* Nothing to do here. We support Internal BPF. */
1839} 1854}
1840 1855
1856bool bpf_jit_needs_zext(void)
1857{
1858 return true;
1859}
1860
1841struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) 1861struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
1842{ 1862{
1843 struct bpf_prog *tmp, *orig_prog = prog; 1863 struct bpf_prog *tmp, *orig_prog = prog;