diff options
Diffstat (limited to 'arch/arm/net/bpf_jit_32.c')
-rw-r--r-- | arch/arm/net/bpf_jit_32.c | 42 |
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 | ||
1856 | bool bpf_jit_needs_zext(void) | ||
1857 | { | ||
1858 | return true; | ||
1859 | } | ||
1860 | |||
1841 | struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) | 1861 | struct 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; |