aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/net
diff options
context:
space:
mode:
authorMichael Holzheu <holzheu@linux.vnet.ibm.com>2015-04-27 05:12:25 -0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2015-04-30 07:50:34 -0400
commit771aada9ace7e5dd837a69ef0bca08b5455b2d36 (patch)
tree761f957eb0d7284e4e3e5b549f8ae4d2c57afc0a /arch/s390/net
parent3d99e3fe13d473ac4578c37f477a59b829530764 (diff)
s390/bpf: Adjust ALU64_DIV/MOD to match interpreter change
The s390x ALU64_DIV/MOD has been implemented according to the eBPF interpreter specification that used do_div(). This function does a 64-bit by 32-bit divide. It turned out that this was wrong and now the interpreter uses div64_u64_rem() for full 64-bit division. So fix this and use full 64-bit division in the s390x eBPF backend code. Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch/s390/net')
-rw-r--r--arch/s390/net/bpf_jit_comp.c14
1 files changed, 6 insertions, 8 deletions
diff --git a/arch/s390/net/bpf_jit_comp.c b/arch/s390/net/bpf_jit_comp.c
index 7690dc8e1ab5..065aca02bc65 100644
--- a/arch/s390/net/bpf_jit_comp.c
+++ b/arch/s390/net/bpf_jit_comp.c
@@ -588,8 +588,8 @@ static int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp, int i)
588 EMIT4(0xb9160000, dst_reg, rc_reg); 588 EMIT4(0xb9160000, dst_reg, rc_reg);
589 break; 589 break;
590 } 590 }
591 case BPF_ALU64 | BPF_DIV | BPF_X: /* dst = dst / (u32) src */ 591 case BPF_ALU64 | BPF_DIV | BPF_X: /* dst = dst / src */
592 case BPF_ALU64 | BPF_MOD | BPF_X: /* dst = dst % (u32) src */ 592 case BPF_ALU64 | BPF_MOD | BPF_X: /* dst = dst % src */
593 { 593 {
594 int rc_reg = BPF_OP(insn->code) == BPF_DIV ? REG_W1 : REG_W0; 594 int rc_reg = BPF_OP(insn->code) == BPF_DIV ? REG_W1 : REG_W0;
595 595
@@ -602,10 +602,8 @@ static int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp, int i)
602 EMIT4_IMM(0xa7090000, REG_W0, 0); 602 EMIT4_IMM(0xa7090000, REG_W0, 0);
603 /* lgr %w1,%dst */ 603 /* lgr %w1,%dst */
604 EMIT4(0xb9040000, REG_W1, dst_reg); 604 EMIT4(0xb9040000, REG_W1, dst_reg);
605 /* llgfr %dst,%src (u32 cast) */
606 EMIT4(0xb9160000, dst_reg, src_reg);
607 /* dlgr %w0,%dst */ 605 /* dlgr %w0,%dst */
608 EMIT4(0xb9870000, REG_W0, dst_reg); 606 EMIT4(0xb9870000, REG_W0, src_reg);
609 /* lgr %dst,%rc */ 607 /* lgr %dst,%rc */
610 EMIT4(0xb9040000, dst_reg, rc_reg); 608 EMIT4(0xb9040000, dst_reg, rc_reg);
611 break; 609 break;
@@ -632,8 +630,8 @@ static int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp, int i)
632 EMIT4(0xb9160000, dst_reg, rc_reg); 630 EMIT4(0xb9160000, dst_reg, rc_reg);
633 break; 631 break;
634 } 632 }
635 case BPF_ALU64 | BPF_DIV | BPF_K: /* dst = dst / (u32) imm */ 633 case BPF_ALU64 | BPF_DIV | BPF_K: /* dst = dst / imm */
636 case BPF_ALU64 | BPF_MOD | BPF_K: /* dst = dst % (u32) imm */ 634 case BPF_ALU64 | BPF_MOD | BPF_K: /* dst = dst % imm */
637 { 635 {
638 int rc_reg = BPF_OP(insn->code) == BPF_DIV ? REG_W1 : REG_W0; 636 int rc_reg = BPF_OP(insn->code) == BPF_DIV ? REG_W1 : REG_W0;
639 637
@@ -649,7 +647,7 @@ static int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp, int i)
649 EMIT4(0xb9040000, REG_W1, dst_reg); 647 EMIT4(0xb9040000, REG_W1, dst_reg);
650 /* dlg %w0,<d(imm)>(%l) */ 648 /* dlg %w0,<d(imm)>(%l) */
651 EMIT6_DISP_LH(0xe3000000, 0x0087, REG_W0, REG_0, REG_L, 649 EMIT6_DISP_LH(0xe3000000, 0x0087, REG_W0, REG_0, REG_L,
652 EMIT_CONST_U64((u32) imm)); 650 EMIT_CONST_U64(imm));
653 /* lgr %dst,%rc */ 651 /* lgr %dst,%rc */
654 EMIT4(0xb9040000, dst_reg, rc_reg); 652 EMIT4(0xb9040000, dst_reg, rc_reg);
655 break; 653 break;