| .. | .. |
|---|
| 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); |
|---|