Commit 3de55893 authored by Ilya Leoshkevich's avatar Ilya Leoshkevich Committed by Alexei Starovoitov
Browse files

s390/bpf: Implement BPF_MOV | BPF_X with sign-extension



Implement the cpuv4 register-to-register move with sign extension. It
is distinguished from the normal moves by non-zero values in
insn->off, which determine the source size. s390x has instructions to
deal with all of them: lbr, lhr, lgbr, lghr and lgfr.

Signed-off-by: default avatarIlya Leoshkevich <iii@linux.ibm.com>
Link: https://lore.kernel.org/r/20230919101336.2223655-5-iii@linux.ibm.com


Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
parent 9873ce2e
Loading
Loading
Loading
Loading
+40 −8
Original line number Diff line number Diff line
@@ -795,16 +795,48 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp,
	/*
	 * BPF_MOV
	 */
	case BPF_ALU | BPF_MOV | BPF_X: /* dst = (u32) src */
	case BPF_ALU | BPF_MOV | BPF_X:
		switch (insn->off) {
		case 0: /* DST = (u32) SRC */
			/* llgfr %dst,%src */
			EMIT4(0xb9160000, dst_reg, src_reg);
			if (insn_is_zext(&insn[1]))
				insn_count = 2;
			break;
	case BPF_ALU64 | BPF_MOV | BPF_X: /* dst = src */
		case 8: /* DST = (u32)(s8) SRC */
			/* lbr %dst,%src */
			EMIT4(0xb9260000, dst_reg, src_reg);
			/* llgfr %dst,%dst */
			EMIT4(0xb9160000, dst_reg, dst_reg);
			break;
		case 16: /* DST = (u32)(s16) SRC */
			/* lhr %dst,%src */
			EMIT4(0xb9270000, dst_reg, src_reg);
			/* llgfr %dst,%dst */
			EMIT4(0xb9160000, dst_reg, dst_reg);
			break;
		}
		break;
	case BPF_ALU64 | BPF_MOV | BPF_X:
		switch (insn->off) {
		case 0: /* DST = SRC */
			/* lgr %dst,%src */
			EMIT4(0xb9040000, dst_reg, src_reg);
			break;
		case 8: /* DST = (s8) SRC */
			/* lgbr %dst,%src */
			EMIT4(0xb9060000, dst_reg, src_reg);
			break;
		case 16: /* DST = (s16) SRC */
			/* lghr %dst,%src */
			EMIT4(0xb9070000, dst_reg, src_reg);
			break;
		case 32: /* DST = (s32) SRC */
			/* lgfr %dst,%src */
			EMIT4(0xb9140000, dst_reg, src_reg);
			break;
		}
		break;
	case BPF_ALU | BPF_MOV | BPF_K: /* dst = (u32) imm */
		/* llilf %dst,imm */
		EMIT6_IMM(0xc00f0000, dst_reg, imm);