MIPS: Fix branch emulation of branch likely instructions.
authorRalf Baechle <ralf@linux-mips.org>
Thu, 22 May 2014 21:19:00 +0000 (23:19 +0200)
committerRalf Baechle <ralf@linux-mips.org>
Thu, 22 May 2014 23:00:26 +0000 (01:00 +0200)
Two issues:

  o For beql_op, beql_op, bne_op, bnel_op, blez_op, blezl_op, bgtz_op and
    bgtzl_op the wrong field was being checked for the instruction opcode.
  o For blez_op / blezl_op and bgtz_op / bgtzl_op the test was testing
    for the wrong opcode.

This bug got introduced by d8d4e3ae0b5c179c0bfd3f0af5b352d13bea9cfa [MIPS
Kprobes: Refactor branch emulation].

Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Acked-by: Leonid Yegoshin <Leonid.Yegoshin@imgtec.com>
Acked-by: Victor Kamensky <kamensky@cisco.com>
arch/mips/kernel/branch.c

index 4d78bf445a9cd2e7397898ac32e24b4ee1bac8dd..76122ff5cb5ef877a7c0e6b3c55ecc6232f9c899 100644 (file)
@@ -317,7 +317,7 @@ int __compute_return_epc_for_insn(struct pt_regs *regs,
                if (regs->regs[insn.i_format.rs] ==
                    regs->regs[insn.i_format.rt]) {
                        epc = epc + 4 + (insn.i_format.simmediate << 2);
-                       if (insn.i_format.rt == beql_op)
+                       if (insn.i_format.opcode == beql_op)
                                ret = BRANCH_LIKELY_TAKEN;
                } else
                        epc += 8;
@@ -329,7 +329,7 @@ int __compute_return_epc_for_insn(struct pt_regs *regs,
                if (regs->regs[insn.i_format.rs] !=
                    regs->regs[insn.i_format.rt]) {
                        epc = epc + 4 + (insn.i_format.simmediate << 2);
-                       if (insn.i_format.rt == bnel_op)
+                       if (insn.i_format.opcode == bnel_op)
                                ret = BRANCH_LIKELY_TAKEN;
                } else
                        epc += 8;
@@ -341,7 +341,7 @@ int __compute_return_epc_for_insn(struct pt_regs *regs,
                /* rt field assumed to be zero */
                if ((long)regs->regs[insn.i_format.rs] <= 0) {
                        epc = epc + 4 + (insn.i_format.simmediate << 2);
-                       if (insn.i_format.rt == bnel_op)
+                       if (insn.i_format.opcode == blezl_op)
                                ret = BRANCH_LIKELY_TAKEN;
                } else
                        epc += 8;
@@ -353,7 +353,7 @@ int __compute_return_epc_for_insn(struct pt_regs *regs,
                /* rt field assumed to be zero */
                if ((long)regs->regs[insn.i_format.rs] > 0) {
                        epc = epc + 4 + (insn.i_format.simmediate << 2);
-                       if (insn.i_format.rt == bnel_op)
+                       if (insn.i_format.opcode == bgtzl_op)
                                ret = BRANCH_LIKELY_TAKEN;
                } else
                        epc += 8;