Skip to content

Commit e90a7ec

Browse files
rnavgregkh
authored andcommitted
powerpc/bpf: use unsigned division instruction for 64-bit operations
commit 758f204 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: 156d0e2 ("powerpc/ebpf/jit: Implement JIT compiler for extended BPF") Cc: [email protected] # v4.8+ Signed-off-by: Naveen N. Rao <[email protected]> Signed-off-by: Daniel Borkmann <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent a97e265 commit e90a7ec

File tree

3 files changed

+6
-5
lines changed

3 files changed

+6
-5
lines changed

arch/powerpc/include/asm/ppc-opcode.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,7 @@
261261
#define PPC_INST_MULLI 0x1c000000
262262
#define PPC_INST_DIVWU 0x7c000396
263263
#define PPC_INST_DIVD 0x7c0003d2
264+
#define PPC_INST_DIVDU 0x7c000392
264265
#define PPC_INST_RLWINM 0x54000000
265266
#define PPC_INST_RLWIMI 0x50000000
266267
#define PPC_INST_RLDICL 0x78000000

arch/powerpc/net/bpf_jit.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@
116116
___PPC_RA(a) | IMM_L(i))
117117
#define PPC_DIVWU(d, a, b) EMIT(PPC_INST_DIVWU | ___PPC_RT(d) | \
118118
___PPC_RA(a) | ___PPC_RB(b))
119-
#define PPC_DIVD(d, a, b) EMIT(PPC_INST_DIVD | ___PPC_RT(d) | \
119+
#define PPC_DIVDU(d, a, b) EMIT(PPC_INST_DIVDU | ___PPC_RT(d) | \
120120
___PPC_RA(a) | ___PPC_RB(b))
121121
#define PPC_AND(d, a, b) EMIT(PPC_INST_AND | ___PPC_RA(d) | \
122122
___PPC_RS(a) | ___PPC_RB(b))

arch/powerpc/net/bpf_jit_comp64.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -419,12 +419,12 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image,
419419
PPC_LI(b2p[BPF_REG_0], 0);
420420
PPC_JMP(exit_addr);
421421
if (BPF_OP(code) == BPF_MOD) {
422-
PPC_DIVD(b2p[TMP_REG_1], dst_reg, src_reg);
422+
PPC_DIVDU(b2p[TMP_REG_1], dst_reg, src_reg);
423423
PPC_MULD(b2p[TMP_REG_1], src_reg,
424424
b2p[TMP_REG_1]);
425425
PPC_SUB(dst_reg, dst_reg, b2p[TMP_REG_1]);
426426
} else
427-
PPC_DIVD(dst_reg, dst_reg, src_reg);
427+
PPC_DIVDU(dst_reg, dst_reg, src_reg);
428428
break;
429429
case BPF_ALU | BPF_MOD | BPF_K: /* (u32) dst %= (u32) imm */
430430
case BPF_ALU | BPF_DIV | BPF_K: /* (u32) dst /= (u32) imm */
@@ -452,15 +452,15 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image,
452452
break;
453453
case BPF_ALU64:
454454
if (BPF_OP(code) == BPF_MOD) {
455-
PPC_DIVD(b2p[TMP_REG_2], dst_reg,
455+
PPC_DIVDU(b2p[TMP_REG_2], dst_reg,
456456
b2p[TMP_REG_1]);
457457
PPC_MULD(b2p[TMP_REG_1],
458458
b2p[TMP_REG_1],
459459
b2p[TMP_REG_2]);
460460
PPC_SUB(dst_reg, dst_reg,
461461
b2p[TMP_REG_1]);
462462
} else
463-
PPC_DIVD(dst_reg, dst_reg,
463+
PPC_DIVDU(dst_reg, dst_reg,
464464
b2p[TMP_REG_1]);
465465
break;
466466
}

0 commit comments

Comments
 (0)