]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - queue-4.14/powerpc-bpf-use-unsigned-division-instruction-for-64-bit-operations.patch
4.14-stable patches
[thirdparty/kernel/stable-queue.git] / queue-4.14 / powerpc-bpf-use-unsigned-division-instruction-for-64-bit-operations.patch
1 From 758f2046ea040773ae8ea7f72dd3bbd8fa984501 Mon Sep 17 00:00:00 2001
2 From: "Naveen N. Rao" <naveen.n.rao@linux.vnet.ibm.com>
3 Date: Thu, 13 Jun 2019 00:21:40 +0530
4 Subject: powerpc/bpf: use unsigned division instruction for 64-bit operations
5
6 From: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>
7
8 commit 758f2046ea040773ae8ea7f72dd3bbd8fa984501 upstream.
9
10 BPF_ALU64 div/mod operations are currently using signed division, unlike
11 BPF_ALU32 operations. Fix the same. DIV64 and MOD64 overflow tests pass
12 with this fix.
13
14 Fixes: 156d0e290e969c ("powerpc/ebpf/jit: Implement JIT compiler for extended BPF")
15 Cc: stable@vger.kernel.org # v4.8+
16 Signed-off-by: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>
17 Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
18 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
19
20 ---
21 arch/powerpc/include/asm/ppc-opcode.h | 1 +
22 arch/powerpc/net/bpf_jit.h | 2 +-
23 arch/powerpc/net/bpf_jit_comp64.c | 8 ++++----
24 3 files changed, 6 insertions(+), 5 deletions(-)
25
26 --- a/arch/powerpc/include/asm/ppc-opcode.h
27 +++ b/arch/powerpc/include/asm/ppc-opcode.h
28 @@ -324,6 +324,7 @@
29 #define PPC_INST_MULLI 0x1c000000
30 #define PPC_INST_DIVWU 0x7c000396
31 #define PPC_INST_DIVD 0x7c0003d2
32 +#define PPC_INST_DIVDU 0x7c000392
33 #define PPC_INST_RLWINM 0x54000000
34 #define PPC_INST_RLWIMI 0x50000000
35 #define PPC_INST_RLDICL 0x78000000
36 --- a/arch/powerpc/net/bpf_jit.h
37 +++ b/arch/powerpc/net/bpf_jit.h
38 @@ -116,7 +116,7 @@
39 ___PPC_RA(a) | IMM_L(i))
40 #define PPC_DIVWU(d, a, b) EMIT(PPC_INST_DIVWU | ___PPC_RT(d) | \
41 ___PPC_RA(a) | ___PPC_RB(b))
42 -#define PPC_DIVD(d, a, b) EMIT(PPC_INST_DIVD | ___PPC_RT(d) | \
43 +#define PPC_DIVDU(d, a, b) EMIT(PPC_INST_DIVDU | ___PPC_RT(d) | \
44 ___PPC_RA(a) | ___PPC_RB(b))
45 #define PPC_AND(d, a, b) EMIT(PPC_INST_AND | ___PPC_RA(d) | \
46 ___PPC_RS(a) | ___PPC_RB(b))
47 --- a/arch/powerpc/net/bpf_jit_comp64.c
48 +++ b/arch/powerpc/net/bpf_jit_comp64.c
49 @@ -415,12 +415,12 @@ static int bpf_jit_build_body(struct bpf
50 PPC_LI(b2p[BPF_REG_0], 0);
51 PPC_JMP(exit_addr);
52 if (BPF_OP(code) == BPF_MOD) {
53 - PPC_DIVD(b2p[TMP_REG_1], dst_reg, src_reg);
54 + PPC_DIVDU(b2p[TMP_REG_1], dst_reg, src_reg);
55 PPC_MULD(b2p[TMP_REG_1], src_reg,
56 b2p[TMP_REG_1]);
57 PPC_SUB(dst_reg, dst_reg, b2p[TMP_REG_1]);
58 } else
59 - PPC_DIVD(dst_reg, dst_reg, src_reg);
60 + PPC_DIVDU(dst_reg, dst_reg, src_reg);
61 break;
62 case BPF_ALU | BPF_MOD | BPF_K: /* (u32) dst %= (u32) imm */
63 case BPF_ALU | BPF_DIV | BPF_K: /* (u32) dst /= (u32) imm */
64 @@ -448,7 +448,7 @@ static int bpf_jit_build_body(struct bpf
65 break;
66 case BPF_ALU64:
67 if (BPF_OP(code) == BPF_MOD) {
68 - PPC_DIVD(b2p[TMP_REG_2], dst_reg,
69 + PPC_DIVDU(b2p[TMP_REG_2], dst_reg,
70 b2p[TMP_REG_1]);
71 PPC_MULD(b2p[TMP_REG_1],
72 b2p[TMP_REG_1],
73 @@ -456,7 +456,7 @@ static int bpf_jit_build_body(struct bpf
74 PPC_SUB(dst_reg, dst_reg,
75 b2p[TMP_REG_1]);
76 } else
77 - PPC_DIVD(dst_reg, dst_reg,
78 + PPC_DIVDU(dst_reg, dst_reg,
79 b2p[TMP_REG_1]);
80 break;
81 }