Commit e9d92d22 authored by Markos Chandras's avatar Markos Chandras Committed by Ralf Baechle

MIPS: Fix branch emulation for BLTC and BGEC instructions

Commits f1b44067 ("MIPS: Emulate the
new MIPS R6 B{L,G}T{Z,}{AL,}C instructions") and commit
a8ff66f5 ("MIPS: Emulate the new MIPS
R6 B{L,G}E{Z,}{AL,}C instructions") added support for emulating various
branch compact instructions. However, it missed the case for those which
use the old BLEZL and BGTZL opcodes leading to random crashes when the R6
emulator is disabled. We fix this by ensuring that the 'rt' field is not
zero which is always true for these branch compact instructions.

Fixes: f1b44067 ("MIPS: Emulate the new MIPS R6 B{L,G}T{Z,}{AL,}C instructions")
Fixes: a8ff66f5 ("MIPS: Emulate the new MIPS R6 B{L,G}E{Z,}{AL,}C instructions")
Cc: <stable@vger.kernel.org> # 4.0+
Signed-off-by: default avatarMarkos Chandras <markos.chandras@imgtec.com>
Cc: linux-mips@linux-mips.org
Cc: Markos Chandras <markos.chandras@imgtec.com>
Patchwork: https://patchwork.linux-mips.org/patch/10582/Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>
parent 761b4493
...@@ -600,7 +600,7 @@ int __compute_return_epc_for_insn(struct pt_regs *regs, ...@@ -600,7 +600,7 @@ int __compute_return_epc_for_insn(struct pt_regs *regs,
break; break;
case blezl_op: /* not really i_format */ case blezl_op: /* not really i_format */
if (NO_R6EMU) if (!insn.i_format.rt && NO_R6EMU)
goto sigill_r6; goto sigill_r6;
case blez_op: case blez_op:
/* /*
...@@ -635,7 +635,7 @@ int __compute_return_epc_for_insn(struct pt_regs *regs, ...@@ -635,7 +635,7 @@ int __compute_return_epc_for_insn(struct pt_regs *regs,
break; break;
case bgtzl_op: case bgtzl_op:
if (NO_R6EMU) if (!insn.i_format.rt && NO_R6EMU)
goto sigill_r6; goto sigill_r6;
case bgtz_op: case bgtz_op:
/* /*
......
...@@ -551,7 +551,7 @@ static int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn, ...@@ -551,7 +551,7 @@ static int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
dec_insn.next_pc_inc; dec_insn.next_pc_inc;
return 1; return 1;
case blezl_op: case blezl_op:
if (NO_R6EMU) if (!insn.i_format.rt && NO_R6EMU)
break; break;
case blez_op: case blez_op:
...@@ -588,7 +588,7 @@ static int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn, ...@@ -588,7 +588,7 @@ static int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
dec_insn.next_pc_inc; dec_insn.next_pc_inc;
return 1; return 1;
case bgtzl_op: case bgtzl_op:
if (NO_R6EMU) if (!insn.i_format.rt && NO_R6EMU)
break; break;
case bgtz_op: case bgtz_op:
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment