forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-11 6778948f9de86c3cfaf36725a7c87dcff9ba247f
kernel/arch/arm/net/bpf_jit_32.c
....@@ -1,12 +1,9 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Just-In-Time compiler for eBPF filters on 32bit ARM
34 *
45 * Copyright (c) 2017 Shubham Bansal <illusionist.neo@gmail.com>
56 * Copyright (c) 2011 Mircea Gherzan <mgherzan@gmail.com>
6
- *
7
- * This program is free software; you can redistribute it and/or modify it
8
- * under the terms of the GNU General Public License as published by the
9
- * Free Software Foundation; version 2 of the License.
107 */
118
129 #include <linux/bpf.h>
....@@ -755,7 +752,8 @@
755752
756753 /* ALU operation */
757754 emit_alu_r(rd[1], rs, true, false, op, ctx);
758
- emit_a32_mov_i(rd[0], 0, ctx);
755
+ if (!ctx->prog->aux->verifier_zext)
756
+ emit_a32_mov_i(rd[0], 0, ctx);
759757 }
760758
761759 arm_bpf_put_reg64(dst, rd, ctx);
....@@ -777,8 +775,9 @@
777775 struct jit_ctx *ctx) {
778776 if (!is64) {
779777 emit_a32_mov_r(dst_lo, src_lo, ctx);
780
- /* Zero out high 4 bytes */
781
- emit_a32_mov_i(dst_hi, 0, ctx);
778
+ if (!ctx->prog->aux->verifier_zext)
779
+ /* Zero out high 4 bytes */
780
+ emit_a32_mov_i(dst_hi, 0, ctx);
782781 } else if (__LINUX_ARM_ARCH__ < 6 &&
783782 ctx->cpu_architecture < CPU_ARCH_ARMv5TE) {
784783 /* complete 8 byte move */
....@@ -814,6 +813,9 @@
814813 break;
815814 case BPF_RSH:
816815 emit(ARM_LSR_I(rd, rd, val), ctx);
816
+ break;
817
+ case BPF_ARSH:
818
+ emit(ARM_ASR_I(rd, rd, val), ctx);
817819 break;
818820 case BPF_NEG:
819821 emit(ARM_RSB_I(rd, rd, val), ctx);
....@@ -880,8 +882,8 @@
880882 emit(ARM_SUBS_I(tmp2[0], rt, 32), ctx);
881883 emit(ARM_MOV_SR(ARM_LR, rd[1], SRTYPE_LSR, rt), ctx);
882884 emit(ARM_ORR_SR(ARM_LR, ARM_LR, rd[0], SRTYPE_ASL, ARM_IP), ctx);
883
- _emit(ARM_COND_MI, ARM_B(0), ctx);
884
- emit(ARM_ORR_SR(ARM_LR, ARM_LR, rd[0], SRTYPE_ASR, tmp2[0]), ctx);
885
+ _emit(ARM_COND_PL,
886
+ ARM_ORR_SR(ARM_LR, ARM_LR, rd[0], SRTYPE_ASR, tmp2[0]), ctx);
885887 emit(ARM_MOV_SR(ARM_IP, rd[0], SRTYPE_ASR, rt), ctx);
886888
887889 arm_bpf_put_reg32(dst_lo, ARM_LR, ctx);
....@@ -1095,17 +1097,20 @@
10951097 case BPF_B:
10961098 /* Load a Byte */
10971099 emit(ARM_LDRB_I(rd[1], rm, off), ctx);
1098
- emit_a32_mov_i(rd[0], 0, ctx);
1100
+ if (!ctx->prog->aux->verifier_zext)
1101
+ emit_a32_mov_i(rd[0], 0, ctx);
10991102 break;
11001103 case BPF_H:
11011104 /* Load a HalfWord */
11021105 emit(ARM_LDRH_I(rd[1], rm, off), ctx);
1103
- emit_a32_mov_i(rd[0], 0, ctx);
1106
+ if (!ctx->prog->aux->verifier_zext)
1107
+ emit_a32_mov_i(rd[0], 0, ctx);
11041108 break;
11051109 case BPF_W:
11061110 /* Load a Word */
11071111 emit(ARM_LDR_I(rd[1], rm, off), ctx);
1108
- emit_a32_mov_i(rd[0], 0, ctx);
1112
+ if (!ctx->prog->aux->verifier_zext)
1113
+ emit_a32_mov_i(rd[0], 0, ctx);
11091114 break;
11101115 case BPF_DW:
11111116 /* Load a Double Word */
....@@ -1118,12 +1123,17 @@
11181123
11191124 /* Arithmatic Operation */
11201125 static inline void emit_ar_r(const u8 rd, const u8 rt, const u8 rm,
1121
- const u8 rn, struct jit_ctx *ctx, u8 op) {
1126
+ const u8 rn, struct jit_ctx *ctx, u8 op,
1127
+ bool is_jmp64) {
11221128 switch (op) {
11231129 case BPF_JSET:
1124
- emit(ARM_AND_R(ARM_IP, rt, rn), ctx);
1125
- emit(ARM_AND_R(ARM_LR, rd, rm), ctx);
1126
- emit(ARM_ORRS_R(ARM_IP, ARM_LR, ARM_IP), ctx);
1130
+ if (is_jmp64) {
1131
+ emit(ARM_AND_R(ARM_IP, rt, rn), ctx);
1132
+ emit(ARM_AND_R(ARM_LR, rd, rm), ctx);
1133
+ emit(ARM_ORRS_R(ARM_IP, ARM_LR, ARM_IP), ctx);
1134
+ } else {
1135
+ emit(ARM_ANDS_R(ARM_IP, rt, rn), ctx);
1136
+ }
11271137 break;
11281138 case BPF_JEQ:
11291139 case BPF_JNE:
....@@ -1131,18 +1141,25 @@
11311141 case BPF_JGE:
11321142 case BPF_JLE:
11331143 case BPF_JLT:
1134
- emit(ARM_CMP_R(rd, rm), ctx);
1135
- _emit(ARM_COND_EQ, ARM_CMP_R(rt, rn), ctx);
1144
+ if (is_jmp64) {
1145
+ emit(ARM_CMP_R(rd, rm), ctx);
1146
+ /* Only compare low halve if high halve are equal. */
1147
+ _emit(ARM_COND_EQ, ARM_CMP_R(rt, rn), ctx);
1148
+ } else {
1149
+ emit(ARM_CMP_R(rt, rn), ctx);
1150
+ }
11361151 break;
11371152 case BPF_JSLE:
11381153 case BPF_JSGT:
11391154 emit(ARM_CMP_R(rn, rt), ctx);
1140
- emit(ARM_SBCS_R(ARM_IP, rm, rd), ctx);
1155
+ if (is_jmp64)
1156
+ emit(ARM_SBCS_R(ARM_IP, rm, rd), ctx);
11411157 break;
11421158 case BPF_JSLT:
11431159 case BPF_JSGE:
11441160 emit(ARM_CMP_R(rt, rn), ctx);
1145
- emit(ARM_SBCS_R(ARM_IP, rd, rm), ctx);
1161
+ if (is_jmp64)
1162
+ emit(ARM_SBCS_R(ARM_IP, rd, rm), ctx);
11461163 break;
11471164 }
11481165 }
....@@ -1281,12 +1298,9 @@
12811298
12821299 static void build_prologue(struct jit_ctx *ctx)
12831300 {
1284
- const s8 r0 = bpf2a32[BPF_REG_0][1];
1285
- const s8 r2 = bpf2a32[BPF_REG_1][1];
1286
- const s8 r3 = bpf2a32[BPF_REG_1][0];
1287
- const s8 r4 = bpf2a32[BPF_REG_6][1];
1288
- const s8 fplo = bpf2a32[BPF_REG_FP][1];
1289
- const s8 fphi = bpf2a32[BPF_REG_FP][0];
1301
+ const s8 arm_r0 = bpf2a32[BPF_REG_0][1];
1302
+ const s8 *bpf_r1 = bpf2a32[BPF_REG_1];
1303
+ const s8 *bpf_fp = bpf2a32[BPF_REG_FP];
12901304 const s8 *tcc = bpf2a32[TCALL_CNT];
12911305
12921306 /* Save callee saved registers. */
....@@ -1299,8 +1313,10 @@
12991313 emit(ARM_PUSH(CALLEE_PUSH_MASK), ctx);
13001314 emit(ARM_MOV_R(ARM_FP, ARM_SP), ctx);
13011315 #endif
1302
- /* Save frame pointer for later */
1303
- emit(ARM_SUB_I(ARM_IP, ARM_SP, SCRATCH_SIZE), ctx);
1316
+ /* mov r3, #0 */
1317
+ /* sub r2, sp, #SCRATCH_SIZE */
1318
+ emit(ARM_MOV_I(bpf_r1[0], 0), ctx);
1319
+ emit(ARM_SUB_I(bpf_r1[1], ARM_SP, SCRATCH_SIZE), ctx);
13041320
13051321 ctx->stack_size = imm8m(STACK_SIZE);
13061322
....@@ -1308,18 +1324,15 @@
13081324 emit(ARM_SUB_I(ARM_SP, ARM_SP, ctx->stack_size), ctx);
13091325
13101326 /* Set up BPF prog stack base register */
1311
- emit_a32_mov_r(fplo, ARM_IP, ctx);
1312
- emit_a32_mov_i(fphi, 0, ctx);
1327
+ emit_a32_mov_r64(true, bpf_fp, bpf_r1, ctx);
13131328
1314
- /* mov r4, 0 */
1315
- emit(ARM_MOV_I(r4, 0), ctx);
1329
+ /* Initialize Tail Count */
1330
+ emit(ARM_MOV_I(bpf_r1[1], 0), ctx);
1331
+ emit_a32_mov_r64(true, tcc, bpf_r1, ctx);
13161332
13171333 /* Move BPF_CTX to BPF_R1 */
1318
- emit(ARM_MOV_R(r3, r4), ctx);
1319
- emit(ARM_MOV_R(r2, r0), ctx);
1320
- /* Initialize Tail Count */
1321
- emit(ARM_STR_I(r4, ARM_FP, EBPF_SCRATCH_TO_ARM_FP(tcc[0])), ctx);
1322
- emit(ARM_STR_I(r4, ARM_FP, EBPF_SCRATCH_TO_ARM_FP(tcc[1])), ctx);
1334
+ emit(ARM_MOV_R(bpf_r1[1], arm_r0), ctx);
1335
+
13231336 /* end of prologue */
13241337 }
13251338
....@@ -1382,6 +1395,11 @@
13821395 case BPF_ALU64 | BPF_MOV | BPF_X:
13831396 switch (BPF_SRC(code)) {
13841397 case BPF_X:
1398
+ if (imm == 1) {
1399
+ /* Special mov32 for zext */
1400
+ emit_a32_mov_i(dst_hi, 0, ctx);
1401
+ break;
1402
+ }
13851403 emit_a32_mov_r64(is64, dst, src, ctx);
13861404 break;
13871405 case BPF_K:
....@@ -1412,7 +1430,6 @@
14121430 case BPF_ALU | BPF_MUL | BPF_X:
14131431 case BPF_ALU | BPF_LSH | BPF_X:
14141432 case BPF_ALU | BPF_RSH | BPF_X:
1415
- case BPF_ALU | BPF_ARSH | BPF_K:
14161433 case BPF_ALU | BPF_ARSH | BPF_X:
14171434 case BPF_ALU64 | BPF_ADD | BPF_K:
14181435 case BPF_ALU64 | BPF_ADD | BPF_X:
....@@ -1461,22 +1478,26 @@
14611478 }
14621479 emit_udivmod(rd_lo, rd_lo, rt, ctx, BPF_OP(code));
14631480 arm_bpf_put_reg32(dst_lo, rd_lo, ctx);
1464
- emit_a32_mov_i(dst_hi, 0, ctx);
1481
+ if (!ctx->prog->aux->verifier_zext)
1482
+ emit_a32_mov_i(dst_hi, 0, ctx);
14651483 break;
14661484 case BPF_ALU64 | BPF_DIV | BPF_K:
14671485 case BPF_ALU64 | BPF_DIV | BPF_X:
14681486 case BPF_ALU64 | BPF_MOD | BPF_K:
14691487 case BPF_ALU64 | BPF_MOD | BPF_X:
14701488 goto notyet;
1471
- /* dst = dst >> imm */
14721489 /* dst = dst << imm */
1473
- case BPF_ALU | BPF_RSH | BPF_K:
1490
+ /* dst = dst >> imm */
1491
+ /* dst = dst >> imm (signed) */
14741492 case BPF_ALU | BPF_LSH | BPF_K:
1493
+ case BPF_ALU | BPF_RSH | BPF_K:
1494
+ case BPF_ALU | BPF_ARSH | BPF_K:
14751495 if (unlikely(imm > 31))
14761496 return -EINVAL;
14771497 if (imm)
14781498 emit_a32_alu_i(dst_lo, imm, ctx, BPF_OP(code));
1479
- emit_a32_mov_i(dst_hi, 0, ctx);
1499
+ if (!ctx->prog->aux->verifier_zext)
1500
+ emit_a32_mov_i(dst_hi, 0, ctx);
14801501 break;
14811502 /* dst = dst << imm */
14821503 case BPF_ALU64 | BPF_LSH | BPF_K:
....@@ -1511,7 +1532,8 @@
15111532 /* dst = ~dst */
15121533 case BPF_ALU | BPF_NEG:
15131534 emit_a32_alu_i(dst_lo, 0, ctx, BPF_OP(code));
1514
- emit_a32_mov_i(dst_hi, 0, ctx);
1535
+ if (!ctx->prog->aux->verifier_zext)
1536
+ emit_a32_mov_i(dst_hi, 0, ctx);
15151537 break;
15161538 /* dst = ~dst (64 bit) */
15171539 case BPF_ALU64 | BPF_NEG:
....@@ -1567,11 +1589,13 @@
15671589 #else /* ARMv6+ */
15681590 emit(ARM_UXTH(rd[1], rd[1]), ctx);
15691591 #endif
1570
- emit(ARM_EOR_R(rd[0], rd[0], rd[0]), ctx);
1592
+ if (!ctx->prog->aux->verifier_zext)
1593
+ emit(ARM_EOR_R(rd[0], rd[0], rd[0]), ctx);
15711594 break;
15721595 case 32:
15731596 /* zero-extend 32 bits into 64 bits */
1574
- emit(ARM_EOR_R(rd[0], rd[0], rd[0]), ctx);
1597
+ if (!ctx->prog->aux->verifier_zext)
1598
+ emit(ARM_EOR_R(rd[0], rd[0], rd[0]), ctx);
15751599 break;
15761600 case 64:
15771601 /* nop */
....@@ -1653,6 +1677,17 @@
16531677 case BPF_JMP | BPF_JLT | BPF_X:
16541678 case BPF_JMP | BPF_JSLT | BPF_X:
16551679 case BPF_JMP | BPF_JSLE | BPF_X:
1680
+ case BPF_JMP32 | BPF_JEQ | BPF_X:
1681
+ case BPF_JMP32 | BPF_JGT | BPF_X:
1682
+ case BPF_JMP32 | BPF_JGE | BPF_X:
1683
+ case BPF_JMP32 | BPF_JNE | BPF_X:
1684
+ case BPF_JMP32 | BPF_JSGT | BPF_X:
1685
+ case BPF_JMP32 | BPF_JSGE | BPF_X:
1686
+ case BPF_JMP32 | BPF_JSET | BPF_X:
1687
+ case BPF_JMP32 | BPF_JLE | BPF_X:
1688
+ case BPF_JMP32 | BPF_JLT | BPF_X:
1689
+ case BPF_JMP32 | BPF_JSLT | BPF_X:
1690
+ case BPF_JMP32 | BPF_JSLE | BPF_X:
16561691 /* Setup source registers */
16571692 rm = arm_bpf_get_reg32(src_hi, tmp2[0], ctx);
16581693 rn = arm_bpf_get_reg32(src_lo, tmp2[1], ctx);
....@@ -1679,6 +1714,17 @@
16791714 case BPF_JMP | BPF_JLE | BPF_K:
16801715 case BPF_JMP | BPF_JSLT | BPF_K:
16811716 case BPF_JMP | BPF_JSLE | BPF_K:
1717
+ case BPF_JMP32 | BPF_JEQ | BPF_K:
1718
+ case BPF_JMP32 | BPF_JGT | BPF_K:
1719
+ case BPF_JMP32 | BPF_JGE | BPF_K:
1720
+ case BPF_JMP32 | BPF_JNE | BPF_K:
1721
+ case BPF_JMP32 | BPF_JSGT | BPF_K:
1722
+ case BPF_JMP32 | BPF_JSGE | BPF_K:
1723
+ case BPF_JMP32 | BPF_JSET | BPF_K:
1724
+ case BPF_JMP32 | BPF_JLT | BPF_K:
1725
+ case BPF_JMP32 | BPF_JLE | BPF_K:
1726
+ case BPF_JMP32 | BPF_JSLT | BPF_K:
1727
+ case BPF_JMP32 | BPF_JSLE | BPF_K:
16821728 if (off == 0)
16831729 break;
16841730 rm = tmp2[0];
....@@ -1690,7 +1736,8 @@
16901736 rd = arm_bpf_get_reg64(dst, tmp, ctx);
16911737
16921738 /* Check for the condition */
1693
- emit_ar_r(rd[0], rd[1], rm, rn, ctx, BPF_OP(code));
1739
+ emit_ar_r(rd[0], rd[1], rm, rn, ctx, BPF_OP(code),
1740
+ BPF_CLASS(code) == BPF_JMP);
16941741
16951742 /* Setup JUMP instruction */
16961743 jmp_offset = bpf2a32_offset(i+off, i, ctx);
....@@ -1841,6 +1888,11 @@
18411888 /* Nothing to do here. We support Internal BPF. */
18421889 }
18431890
1891
+bool bpf_jit_needs_zext(void)
1892
+{
1893
+ return true;
1894
+}
1895
+
18441896 struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
18451897 {
18461898 struct bpf_prog *tmp, *orig_prog = prog;