--- /dev/null
+From 6e61dc9da0b7a0d91d57c2e20b5ea4fd2d4e7e53 Mon Sep 17 00:00:00 2001
+From: Ilya Leoshkevich <iii@linux.ibm.com>
+Date: Tue, 7 Sep 2021 13:41:16 +0200
+Subject: s390/bpf: Fix 64-bit subtraction of the -0x80000000 constant
+
+From: Ilya Leoshkevich <iii@linux.ibm.com>
+
+commit 6e61dc9da0b7a0d91d57c2e20b5ea4fd2d4e7e53 upstream.
+
+The JIT uses agfi for subtracting constants, but -(-0x80000000) cannot
+be represented as a 32-bit signed binary integer. Fix by using algfi in
+this particular case.
+
+Reported-by: Johan Almbladh <johan.almbladh@anyfinetworks.com>
+Fixes: 054623105728 ("s390/bpf: Add s390x eBPF JIT compiler backend")
+Reviewed-by: Heiko Carstens <hca@linux.ibm.com>
+Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
+Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/s390/net/bpf_jit_comp.c | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+--- a/arch/s390/net/bpf_jit_comp.c
++++ b/arch/s390/net/bpf_jit_comp.c
+@@ -795,8 +795,13 @@ static noinline int bpf_jit_insn(struct
+ case BPF_ALU64 | BPF_SUB | BPF_K: /* dst = dst - imm */
+ if (!imm)
+ break;
+- /* agfi %dst,-imm */
+- EMIT6_IMM(0xc2080000, dst_reg, -imm);
++ if (imm == -0x80000000) {
++ /* algfi %dst,0x80000000 */
++ EMIT6_IMM(0xc20a0000, dst_reg, 0x80000000);
++ } else {
++ /* agfi %dst,-imm */
++ EMIT6_IMM(0xc2080000, dst_reg, -imm);
++ }
+ break;
+ /*
+ * BPF_MUL
--- /dev/null
+From 1511df6f5e9ef32826f20db2ee81f8527154dc14 Mon Sep 17 00:00:00 2001
+From: Ilya Leoshkevich <iii@linux.ibm.com>
+Date: Tue, 7 Sep 2021 11:58:59 +0200
+Subject: s390/bpf: Fix branch shortening during codegen pass
+
+From: Ilya Leoshkevich <iii@linux.ibm.com>
+
+commit 1511df6f5e9ef32826f20db2ee81f8527154dc14 upstream.
+
+EMIT6_PCREL() macro assumes that the previous pass generated 6 bytes
+of code, which is not the case if branch shortening took place. Fix by
+using jit->prg, like all the other EMIT6_PCREL_*() macros.
+
+Reported-by: Johan Almbladh <johan.almbladh@anyfinetworks.com>
+Fixes: 4e9b4a6883dd ("s390/bpf: Use relative long branches")
+Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
+Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/s390/net/bpf_jit_comp.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+--- a/arch/s390/net/bpf_jit_comp.c
++++ b/arch/s390/net/bpf_jit_comp.c
+@@ -248,8 +248,7 @@ static inline void reg_set_seen(struct b
+
+ #define EMIT6_PCREL(op1, op2, b1, b2, i, off, mask) \
+ ({ \
+- /* Branch instruction needs 6 bytes */ \
+- int rel = (addrs[(i) + (off) + 1] - (addrs[(i) + 1] - 6)) / 2;\
++ int rel = (addrs[(i) + (off) + 1] - jit->prg) / 2; \
+ _EMIT6((op1) | reg(b1, b2) << 16 | (rel & 0xffff), (op2) | (mask));\
+ REG_SET_SEEN(b1); \
+ REG_SET_SEEN(b2); \
--- /dev/null
+From db7bee653859ef7179be933e7d1384644f795f26 Mon Sep 17 00:00:00 2001
+From: Ilya Leoshkevich <iii@linux.ibm.com>
+Date: Mon, 6 Sep 2021 15:04:14 +0200
+Subject: s390/bpf: Fix optimizing out zero-extensions
+
+From: Ilya Leoshkevich <iii@linux.ibm.com>
+
+commit db7bee653859ef7179be933e7d1384644f795f26 upstream.
+
+Currently the JIT completely removes things like `reg32 += 0`,
+however, the BPF_ALU semantics requires the target register to be
+zero-extended in such cases.
+
+Fix by optimizing out only the arithmetic operation, but not the
+subsequent zero-extension.
+
+Reported-by: Johan Almbladh <johan.almbladh@anyfinetworks.com>
+Fixes: 054623105728 ("s390/bpf: Add s390x eBPF JIT compiler backend")
+Reviewed-by: Heiko Carstens <hca@linux.ibm.com>
+Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
+Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/s390/net/bpf_jit_comp.c | 58 ++++++++++++++++++++++---------------------
+ 1 file changed, 30 insertions(+), 28 deletions(-)
+
+--- a/arch/s390/net/bpf_jit_comp.c
++++ b/arch/s390/net/bpf_jit_comp.c
+@@ -761,10 +761,10 @@ static noinline int bpf_jit_insn(struct
+ EMIT4(0xb9080000, dst_reg, src_reg);
+ break;
+ case BPF_ALU | BPF_ADD | BPF_K: /* dst = (u32) dst + (u32) imm */
+- if (!imm)
+- break;
+- /* alfi %dst,imm */
+- EMIT6_IMM(0xc20b0000, dst_reg, imm);
++ if (imm != 0) {
++ /* alfi %dst,imm */
++ EMIT6_IMM(0xc20b0000, dst_reg, imm);
++ }
+ EMIT_ZERO(dst_reg);
+ break;
+ case BPF_ALU64 | BPF_ADD | BPF_K: /* dst = dst + imm */
+@@ -786,10 +786,10 @@ static noinline int bpf_jit_insn(struct
+ EMIT4(0xb9090000, dst_reg, src_reg);
+ break;
+ case BPF_ALU | BPF_SUB | BPF_K: /* dst = (u32) dst - (u32) imm */
+- if (!imm)
+- break;
+- /* alfi %dst,-imm */
+- EMIT6_IMM(0xc20b0000, dst_reg, -imm);
++ if (imm != 0) {
++ /* alfi %dst,-imm */
++ EMIT6_IMM(0xc20b0000, dst_reg, -imm);
++ }
+ EMIT_ZERO(dst_reg);
+ break;
+ case BPF_ALU64 | BPF_SUB | BPF_K: /* dst = dst - imm */
+@@ -811,10 +811,10 @@ static noinline int bpf_jit_insn(struct
+ EMIT4(0xb90c0000, dst_reg, src_reg);
+ break;
+ case BPF_ALU | BPF_MUL | BPF_K: /* dst = (u32) dst * (u32) imm */
+- if (imm == 1)
+- break;
+- /* msfi %r5,imm */
+- EMIT6_IMM(0xc2010000, dst_reg, imm);
++ if (imm != 1) {
++ /* msfi %r5,imm */
++ EMIT6_IMM(0xc2010000, dst_reg, imm);
++ }
+ EMIT_ZERO(dst_reg);
+ break;
+ case BPF_ALU64 | BPF_MUL | BPF_K: /* dst = dst * imm */
+@@ -867,6 +867,8 @@ static noinline int bpf_jit_insn(struct
+ if (BPF_OP(insn->code) == BPF_MOD)
+ /* lhgi %dst,0 */
+ EMIT4_IMM(0xa7090000, dst_reg, 0);
++ else
++ EMIT_ZERO(dst_reg);
+ break;
+ }
+ /* lhi %w0,0 */
+@@ -999,10 +1001,10 @@ static noinline int bpf_jit_insn(struct
+ EMIT4(0xb9820000, dst_reg, src_reg);
+ break;
+ case BPF_ALU | BPF_XOR | BPF_K: /* dst = (u32) dst ^ (u32) imm */
+- if (!imm)
+- break;
+- /* xilf %dst,imm */
+- EMIT6_IMM(0xc0070000, dst_reg, imm);
++ if (imm != 0) {
++ /* xilf %dst,imm */
++ EMIT6_IMM(0xc0070000, dst_reg, imm);
++ }
+ EMIT_ZERO(dst_reg);
+ break;
+ case BPF_ALU64 | BPF_XOR | BPF_K: /* dst = dst ^ imm */
+@@ -1033,10 +1035,10 @@ static noinline int bpf_jit_insn(struct
+ EMIT6_DISP_LH(0xeb000000, 0x000d, dst_reg, dst_reg, src_reg, 0);
+ break;
+ case BPF_ALU | BPF_LSH | BPF_K: /* dst = (u32) dst << (u32) imm */
+- if (imm == 0)
+- break;
+- /* sll %dst,imm(%r0) */
+- EMIT4_DISP(0x89000000, dst_reg, REG_0, imm);
++ if (imm != 0) {
++ /* sll %dst,imm(%r0) */
++ EMIT4_DISP(0x89000000, dst_reg, REG_0, imm);
++ }
+ EMIT_ZERO(dst_reg);
+ break;
+ case BPF_ALU64 | BPF_LSH | BPF_K: /* dst = dst << imm */
+@@ -1058,10 +1060,10 @@ static noinline int bpf_jit_insn(struct
+ EMIT6_DISP_LH(0xeb000000, 0x000c, dst_reg, dst_reg, src_reg, 0);
+ break;
+ case BPF_ALU | BPF_RSH | BPF_K: /* dst = (u32) dst >> (u32) imm */
+- if (imm == 0)
+- break;
+- /* srl %dst,imm(%r0) */
+- EMIT4_DISP(0x88000000, dst_reg, REG_0, imm);
++ if (imm != 0) {
++ /* srl %dst,imm(%r0) */
++ EMIT4_DISP(0x88000000, dst_reg, REG_0, imm);
++ }
+ EMIT_ZERO(dst_reg);
+ break;
+ case BPF_ALU64 | BPF_RSH | BPF_K: /* dst = dst >> imm */
+@@ -1083,10 +1085,10 @@ static noinline int bpf_jit_insn(struct
+ EMIT6_DISP_LH(0xeb000000, 0x000a, dst_reg, dst_reg, src_reg, 0);
+ break;
+ case BPF_ALU | BPF_ARSH | BPF_K: /* ((s32) dst >> imm */
+- if (imm == 0)
+- break;
+- /* sra %dst,imm(%r0) */
+- EMIT4_DISP(0x8a000000, dst_reg, REG_0, imm);
++ if (imm != 0) {
++ /* sra %dst,imm(%r0) */
++ EMIT4_DISP(0x8a000000, dst_reg, REG_0, imm);
++ }
+ EMIT_ZERO(dst_reg);
+ break;
+ case BPF_ALU64 | BPF_ARSH | BPF_K: /* ((s64) dst) >>= imm */