aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2014-05-22 17:19:00 -0400
committerRalf Baechle <ralf@linux-mips.org>2014-05-22 19:00:26 -0400
commit41ca86e8502952116234fa558f4277092a5aaae9 (patch)
tree2d7a21e12a66b126ac3933074cd1bf7b2b00d76a
parentdc93f7b68a039fe7d918613163b1cdd21b279ec5 (diff)
MIPS: Fix branch emulation of branch likely instructions.
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>
-rw-r--r--arch/mips/kernel/branch.c8
1 files changed, 4 insertions, 4 deletions
diff --git a/arch/mips/kernel/branch.c b/arch/mips/kernel/branch.c
index 4d78bf445a9c..76122ff5cb5e 100644
--- a/arch/mips/kernel/branch.c
+++ b/arch/mips/kernel/branch.c
@@ -317,7 +317,7 @@ int __compute_return_epc_for_insn(struct pt_regs *regs,
317 if (regs->regs[insn.i_format.rs] == 317 if (regs->regs[insn.i_format.rs] ==
318 regs->regs[insn.i_format.rt]) { 318 regs->regs[insn.i_format.rt]) {
319 epc = epc + 4 + (insn.i_format.simmediate << 2); 319 epc = epc + 4 + (insn.i_format.simmediate << 2);
320 if (insn.i_format.rt == beql_op) 320 if (insn.i_format.opcode == beql_op)
321 ret = BRANCH_LIKELY_TAKEN; 321 ret = BRANCH_LIKELY_TAKEN;
322 } else 322 } else
323 epc += 8; 323 epc += 8;
@@ -329,7 +329,7 @@ int __compute_return_epc_for_insn(struct pt_regs *regs,
329 if (regs->regs[insn.i_format.rs] != 329 if (regs->regs[insn.i_format.rs] !=
330 regs->regs[insn.i_format.rt]) { 330 regs->regs[insn.i_format.rt]) {
331 epc = epc + 4 + (insn.i_format.simmediate << 2); 331 epc = epc + 4 + (insn.i_format.simmediate << 2);
332 if (insn.i_format.rt == bnel_op) 332 if (insn.i_format.opcode == bnel_op)
333 ret = BRANCH_LIKELY_TAKEN; 333 ret = BRANCH_LIKELY_TAKEN;
334 } else 334 } else
335 epc += 8; 335 epc += 8;
@@ -341,7 +341,7 @@ int __compute_return_epc_for_insn(struct pt_regs *regs,
341 /* rt field assumed to be zero */ 341 /* rt field assumed to be zero */
342 if ((long)regs->regs[insn.i_format.rs] <= 0) { 342 if ((long)regs->regs[insn.i_format.rs] <= 0) {
343 epc = epc + 4 + (insn.i_format.simmediate << 2); 343 epc = epc + 4 + (insn.i_format.simmediate << 2);
344 if (insn.i_format.rt == bnel_op) 344 if (insn.i_format.opcode == blezl_op)
345 ret = BRANCH_LIKELY_TAKEN; 345 ret = BRANCH_LIKELY_TAKEN;
346 } else 346 } else
347 epc += 8; 347 epc += 8;
@@ -353,7 +353,7 @@ int __compute_return_epc_for_insn(struct pt_regs *regs,
353 /* rt field assumed to be zero */ 353 /* rt field assumed to be zero */
354 if ((long)regs->regs[insn.i_format.rs] > 0) { 354 if ((long)regs->regs[insn.i_format.rs] > 0) {
355 epc = epc + 4 + (insn.i_format.simmediate << 2); 355 epc = epc + 4 + (insn.i_format.simmediate << 2);
356 if (insn.i_format.rt == bnel_op) 356 if (insn.i_format.opcode == bgtzl_op)
357 ret = BRANCH_LIKELY_TAKEN; 357 ret = BRANCH_LIKELY_TAKEN;
358 } else 358 } else
359 epc += 8; 359 epc += 8;