Commit e0d9022a authored by Naveen N. Rao's avatar Naveen N. Rao Committed by Greg Kroah-Hartman

powerpc/bpf: use unsigned division instruction for 64-bit operations

commit 758f2046 upstream.

BPF_ALU64 div/mod operations are currently using signed division, unlike
BPF_ALU32 operations. Fix the same. DIV64 and MOD64 overflow tests pass
with this fix.

Fixes: 156d0e29 ("powerpc/ebpf/jit: Implement JIT compiler for extended BPF")
Cc: stable@vger.kernel.org # v4.8+
Signed-off-by: default avatarNaveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>
Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 12433859
...@@ -342,6 +342,7 @@ ...@@ -342,6 +342,7 @@
#define PPC_INST_MADDLD 0x10000033 #define PPC_INST_MADDLD 0x10000033
#define PPC_INST_DIVWU 0x7c000396 #define PPC_INST_DIVWU 0x7c000396
#define PPC_INST_DIVD 0x7c0003d2 #define PPC_INST_DIVD 0x7c0003d2
#define PPC_INST_DIVDU 0x7c000392
#define PPC_INST_RLWINM 0x54000000 #define PPC_INST_RLWINM 0x54000000
#define PPC_INST_RLWINM_DOT 0x54000001 #define PPC_INST_RLWINM_DOT 0x54000001
#define PPC_INST_RLWIMI 0x50000000 #define PPC_INST_RLWIMI 0x50000000
......
...@@ -116,7 +116,7 @@ ...@@ -116,7 +116,7 @@
___PPC_RA(a) | IMM_L(i)) ___PPC_RA(a) | IMM_L(i))
#define PPC_DIVWU(d, a, b) EMIT(PPC_INST_DIVWU | ___PPC_RT(d) | \ #define PPC_DIVWU(d, a, b) EMIT(PPC_INST_DIVWU | ___PPC_RT(d) | \
___PPC_RA(a) | ___PPC_RB(b)) ___PPC_RA(a) | ___PPC_RB(b))
#define PPC_DIVD(d, a, b) EMIT(PPC_INST_DIVD | ___PPC_RT(d) | \ #define PPC_DIVDU(d, a, b) EMIT(PPC_INST_DIVDU | ___PPC_RT(d) | \
___PPC_RA(a) | ___PPC_RB(b)) ___PPC_RA(a) | ___PPC_RB(b))
#define PPC_AND(d, a, b) EMIT(PPC_INST_AND | ___PPC_RA(d) | \ #define PPC_AND(d, a, b) EMIT(PPC_INST_AND | ___PPC_RA(d) | \
___PPC_RS(a) | ___PPC_RB(b)) ___PPC_RS(a) | ___PPC_RB(b))
......
...@@ -399,12 +399,12 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, ...@@ -399,12 +399,12 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image,
case BPF_ALU64 | BPF_DIV | BPF_X: /* dst /= src */ case BPF_ALU64 | BPF_DIV | BPF_X: /* dst /= src */
case BPF_ALU64 | BPF_MOD | BPF_X: /* dst %= src */ case BPF_ALU64 | BPF_MOD | BPF_X: /* dst %= src */
if (BPF_OP(code) == BPF_MOD) { if (BPF_OP(code) == BPF_MOD) {
PPC_DIVD(b2p[TMP_REG_1], dst_reg, src_reg); PPC_DIVDU(b2p[TMP_REG_1], dst_reg, src_reg);
PPC_MULD(b2p[TMP_REG_1], src_reg, PPC_MULD(b2p[TMP_REG_1], src_reg,
b2p[TMP_REG_1]); b2p[TMP_REG_1]);
PPC_SUB(dst_reg, dst_reg, b2p[TMP_REG_1]); PPC_SUB(dst_reg, dst_reg, b2p[TMP_REG_1]);
} else } else
PPC_DIVD(dst_reg, dst_reg, src_reg); PPC_DIVDU(dst_reg, dst_reg, src_reg);
break; break;
case BPF_ALU | BPF_MOD | BPF_K: /* (u32) dst %= (u32) imm */ case BPF_ALU | BPF_MOD | BPF_K: /* (u32) dst %= (u32) imm */
case BPF_ALU | BPF_DIV | BPF_K: /* (u32) dst /= (u32) imm */ case BPF_ALU | BPF_DIV | BPF_K: /* (u32) dst /= (u32) imm */
...@@ -432,7 +432,7 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, ...@@ -432,7 +432,7 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image,
break; break;
case BPF_ALU64: case BPF_ALU64:
if (BPF_OP(code) == BPF_MOD) { if (BPF_OP(code) == BPF_MOD) {
PPC_DIVD(b2p[TMP_REG_2], dst_reg, PPC_DIVDU(b2p[TMP_REG_2], dst_reg,
b2p[TMP_REG_1]); b2p[TMP_REG_1]);
PPC_MULD(b2p[TMP_REG_1], PPC_MULD(b2p[TMP_REG_1],
b2p[TMP_REG_1], b2p[TMP_REG_1],
...@@ -440,7 +440,7 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, ...@@ -440,7 +440,7 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image,
PPC_SUB(dst_reg, dst_reg, PPC_SUB(dst_reg, dst_reg,
b2p[TMP_REG_1]); b2p[TMP_REG_1]);
} else } else
PPC_DIVD(dst_reg, dst_reg, PPC_DIVDU(dst_reg, dst_reg,
b2p[TMP_REG_1]); b2p[TMP_REG_1]);
break; break;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment