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