powerpc/bpf: use unsigned division instruction for 64-bit operations
commit 758f2046ea040773ae8ea7f72dd3bbd8fa984501 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: 156d0e290e969c ("powerpc/ebpf/jit: Implement JIT compiler for extended BPF") Cc: stable@vger.kernel.org # v4.8+ Signed-off-by: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
4ef48fdde3
commit
a402228419
@ -324,6 +324,7 @@
|
||||
#define PPC_INST_MULLI 0x1c000000
|
||||
#define PPC_INST_DIVWU 0x7c000396
|
||||
#define PPC_INST_DIVD 0x7c0003d2
|
||||
#define PPC_INST_DIVDU 0x7c000392
|
||||
#define PPC_INST_RLWINM 0x54000000
|
||||
#define PPC_INST_RLWIMI 0x50000000
|
||||
#define PPC_INST_RLDICL 0x78000000
|
||||
|
@ -116,7 +116,7 @@
|
||||
___PPC_RA(a) | IMM_L(i))
|
||||
#define PPC_DIVWU(d, a, b) EMIT(PPC_INST_DIVWU | ___PPC_RT(d) | \
|
||||
___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))
|
||||
#define PPC_AND(d, a, b) EMIT(PPC_INST_AND | ___PPC_RA(d) | \
|
||||
___PPC_RS(a) | ___PPC_RB(b))
|
||||
|
@ -415,12 +415,12 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image,
|
||||
PPC_LI(b2p[BPF_REG_0], 0);
|
||||
PPC_JMP(exit_addr);
|
||||
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,
|
||||
b2p[TMP_REG_1]);
|
||||
PPC_SUB(dst_reg, dst_reg, b2p[TMP_REG_1]);
|
||||
} else
|
||||
PPC_DIVD(dst_reg, dst_reg, src_reg);
|
||||
PPC_DIVDU(dst_reg, dst_reg, src_reg);
|
||||
break;
|
||||
case BPF_ALU | BPF_MOD | BPF_K: /* (u32) dst %= (u32) imm */
|
||||
case BPF_ALU | BPF_DIV | BPF_K: /* (u32) dst /= (u32) imm */
|
||||
@ -448,7 +448,7 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image,
|
||||
break;
|
||||
case BPF_ALU64:
|
||||
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]);
|
||||
PPC_MULD(b2p[TMP_REG_1],
|
||||
b2p[TMP_REG_1],
|
||||
@ -456,7 +456,7 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image,
|
||||
PPC_SUB(dst_reg, dst_reg,
|
||||
b2p[TMP_REG_1]);
|
||||
} else
|
||||
PPC_DIVD(dst_reg, dst_reg,
|
||||
PPC_DIVDU(dst_reg, dst_reg,
|
||||
b2p[TMP_REG_1]);
|
||||
break;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user