.. | .. |
---|
791 | 791 | } |
---|
792 | 792 | |
---|
793 | 793 | /* Just skip the save instruction and the ctx register move. */ |
---|
794 | | -#define BPF_TAILCALL_PROLOGUE_SKIP 16 |
---|
| 794 | +#define BPF_TAILCALL_PROLOGUE_SKIP 32 |
---|
795 | 795 | #define BPF_TAILCALL_CNT_SP_OFF (STACK_BIAS + 128) |
---|
796 | 796 | |
---|
797 | 797 | static void build_prologue(struct jit_ctx *ctx) |
---|
.. | .. |
---|
824 | 824 | const u8 vfp = bpf2sparc[BPF_REG_FP]; |
---|
825 | 825 | |
---|
826 | 826 | emit(ADD | IMMED | RS1(FP) | S13(STACK_BIAS) | RD(vfp), ctx); |
---|
| 827 | + } else { |
---|
| 828 | + emit_nop(ctx); |
---|
827 | 829 | } |
---|
828 | 830 | |
---|
829 | 831 | emit_reg_move(I0, O0, ctx); |
---|
| 832 | + emit_reg_move(I1, O1, ctx); |
---|
| 833 | + emit_reg_move(I2, O2, ctx); |
---|
| 834 | + emit_reg_move(I3, O3, ctx); |
---|
| 835 | + emit_reg_move(I4, O4, ctx); |
---|
830 | 836 | /* If you add anything here, adjust BPF_TAILCALL_PROLOGUE_SKIP above. */ |
---|
831 | 837 | } |
---|
832 | 838 | |
---|
.. | .. |
---|
902 | 908 | /* dst = src */ |
---|
903 | 909 | case BPF_ALU | BPF_MOV | BPF_X: |
---|
904 | 910 | emit_alu3_K(SRL, src, 0, dst, ctx); |
---|
| 911 | + if (insn_is_zext(&insn[1])) |
---|
| 912 | + return 1; |
---|
905 | 913 | break; |
---|
906 | 914 | case BPF_ALU64 | BPF_MOV | BPF_X: |
---|
907 | 915 | emit_reg_move(src, dst, ctx); |
---|
.. | .. |
---|
936 | 944 | case BPF_ALU | BPF_DIV | BPF_X: |
---|
937 | 945 | emit_write_y(G0, ctx); |
---|
938 | 946 | emit_alu(DIV, src, dst, ctx); |
---|
| 947 | + if (insn_is_zext(&insn[1])) |
---|
| 948 | + return 1; |
---|
939 | 949 | break; |
---|
940 | 950 | case BPF_ALU64 | BPF_DIV | BPF_X: |
---|
941 | 951 | emit_alu(UDIVX, src, dst, ctx); |
---|
.. | .. |
---|
969 | 979 | break; |
---|
970 | 980 | case BPF_ALU | BPF_RSH | BPF_X: |
---|
971 | 981 | emit_alu(SRL, src, dst, ctx); |
---|
| 982 | + if (insn_is_zext(&insn[1])) |
---|
| 983 | + return 1; |
---|
972 | 984 | break; |
---|
973 | 985 | case BPF_ALU64 | BPF_RSH | BPF_X: |
---|
974 | 986 | emit_alu(SRLX, src, dst, ctx); |
---|
.. | .. |
---|
991 | 1003 | case 16: |
---|
992 | 1004 | emit_alu_K(SLL, dst, 16, ctx); |
---|
993 | 1005 | emit_alu_K(SRL, dst, 16, ctx); |
---|
| 1006 | + if (insn_is_zext(&insn[1])) |
---|
| 1007 | + return 1; |
---|
994 | 1008 | break; |
---|
995 | 1009 | case 32: |
---|
996 | | - emit_alu_K(SRL, dst, 0, ctx); |
---|
| 1010 | + if (!ctx->prog->aux->verifier_zext) |
---|
| 1011 | + emit_alu_K(SRL, dst, 0, ctx); |
---|
997 | 1012 | break; |
---|
998 | 1013 | case 64: |
---|
999 | 1014 | /* nop */ |
---|
.. | .. |
---|
1015 | 1030 | emit_alu3_K(AND, dst, 0xff, dst, ctx); |
---|
1016 | 1031 | emit_alu3_K(SLL, tmp, 8, tmp, ctx); |
---|
1017 | 1032 | emit_alu(OR, tmp, dst, ctx); |
---|
| 1033 | + if (insn_is_zext(&insn[1])) |
---|
| 1034 | + return 1; |
---|
1018 | 1035 | break; |
---|
1019 | 1036 | |
---|
1020 | 1037 | case 32: |
---|
.. | .. |
---|
1031 | 1048 | emit_alu3_K(AND, dst, 0xff, dst, ctx); /* dst = dst & 0xff */ |
---|
1032 | 1049 | emit_alu3_K(SLL, dst, 24, dst, ctx); /* dst = dst << 24 */ |
---|
1033 | 1050 | emit_alu(OR, tmp, dst, ctx); /* dst = dst | tmp */ |
---|
| 1051 | + if (insn_is_zext(&insn[1])) |
---|
| 1052 | + return 1; |
---|
1034 | 1053 | break; |
---|
1035 | 1054 | |
---|
1036 | 1055 | case 64: |
---|
.. | .. |
---|
1044 | 1063 | /* dst = imm */ |
---|
1045 | 1064 | case BPF_ALU | BPF_MOV | BPF_K: |
---|
1046 | 1065 | emit_loadimm32(imm, dst, ctx); |
---|
| 1066 | + if (insn_is_zext(&insn[1])) |
---|
| 1067 | + return 1; |
---|
1047 | 1068 | break; |
---|
1048 | 1069 | case BPF_ALU64 | BPF_MOV | BPF_K: |
---|
1049 | 1070 | emit_loadimm_sext(imm, dst, ctx); |
---|
.. | .. |
---|
1126 | 1147 | break; |
---|
1127 | 1148 | case BPF_ALU | BPF_RSH | BPF_K: |
---|
1128 | 1149 | emit_alu_K(SRL, dst, imm, ctx); |
---|
| 1150 | + if (insn_is_zext(&insn[1])) |
---|
| 1151 | + return 1; |
---|
1129 | 1152 | break; |
---|
1130 | 1153 | case BPF_ALU64 | BPF_RSH | BPF_K: |
---|
1131 | 1154 | emit_alu_K(SRLX, dst, imm, ctx); |
---|
.. | .. |
---|
1138 | 1161 | break; |
---|
1139 | 1162 | |
---|
1140 | 1163 | do_alu32_trunc: |
---|
1141 | | - if (BPF_CLASS(code) == BPF_ALU) |
---|
| 1164 | + if (BPF_CLASS(code) == BPF_ALU && |
---|
| 1165 | + !ctx->prog->aux->verifier_zext) |
---|
1142 | 1166 | emit_alu_K(SRL, dst, 0, ctx); |
---|
1143 | 1167 | break; |
---|
1144 | 1168 | |
---|
.. | .. |
---|
1259 | 1283 | rs2 = RS2(tmp); |
---|
1260 | 1284 | } |
---|
1261 | 1285 | emit(opcode | RS1(src) | rs2 | RD(dst), ctx); |
---|
| 1286 | + if (opcode != LD64 && insn_is_zext(&insn[1])) |
---|
| 1287 | + return 1; |
---|
1262 | 1288 | break; |
---|
1263 | 1289 | } |
---|
1264 | 1290 | /* speculation barrier */ |
---|
.. | .. |
---|
1429 | 1455 | *ptr++ = 0x91d02005; /* ta 5 */ |
---|
1430 | 1456 | } |
---|
1431 | 1457 | |
---|
| 1458 | +bool bpf_jit_needs_zext(void) |
---|
| 1459 | +{ |
---|
| 1460 | + return true; |
---|
| 1461 | +} |
---|
| 1462 | + |
---|
1432 | 1463 | struct sparc64_jit_data { |
---|
1433 | 1464 | struct bpf_binary_header *header; |
---|
1434 | 1465 | u8 *image; |
---|
.. | .. |
---|
1572 | 1603 | prog->jited_len = image_size; |
---|
1573 | 1604 | |
---|
1574 | 1605 | if (!prog->is_func || extra_pass) { |
---|
| 1606 | + bpf_prog_fill_jited_linfo(prog, ctx.offset); |
---|
1575 | 1607 | out_off: |
---|
1576 | 1608 | kfree(ctx.offset); |
---|
1577 | 1609 | kfree(jit_data); |
---|