MIPS: Trap exception handling fixes
2a0b24f56c
broke Trap exception handling in
the standard MIPS mode. Additionally the microMIPS-mode trap code mask is
wrong, as it's a 4-bit field. Here's a fix.
Signed-off-by: Maciej W. Rozycki <macro@codesourcery.com>
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/5309/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
This commit is contained in:
parent
8f657933a3
commit
a9a6e7a095
|
@ -897,22 +897,24 @@ out_sigsegv:
|
||||||
|
|
||||||
asmlinkage void do_tr(struct pt_regs *regs)
|
asmlinkage void do_tr(struct pt_regs *regs)
|
||||||
{
|
{
|
||||||
unsigned int opcode, tcode = 0;
|
u32 opcode, tcode = 0;
|
||||||
u16 instr[2];
|
u16 instr[2];
|
||||||
unsigned long epc = exception_epc(regs);
|
unsigned long epc = msk_isa16_mode(exception_epc(regs));
|
||||||
|
|
||||||
if ((__get_user(instr[0], (u16 __user *)msk_isa16_mode(epc))) ||
|
if (get_isa16_mode(regs->cp0_epc)) {
|
||||||
(__get_user(instr[1], (u16 __user *)msk_isa16_mode(epc + 2))))
|
if (__get_user(instr[0], (u16 __user *)(epc + 0)) ||
|
||||||
|
__get_user(instr[1], (u16 __user *)(epc + 2)))
|
||||||
goto out_sigsegv;
|
goto out_sigsegv;
|
||||||
opcode = (instr[0] << 16) | instr[1];
|
opcode = (instr[0] << 16) | instr[1];
|
||||||
|
/* Immediate versions don't provide a code. */
|
||||||
/* Immediate versions don't provide a code. */
|
if (!(opcode & OPCODE))
|
||||||
if (!(opcode & OPCODE)) {
|
tcode = (opcode >> 12) & ((1 << 4) - 1);
|
||||||
if (get_isa16_mode(regs->cp0_epc))
|
} else {
|
||||||
/* microMIPS */
|
if (__get_user(opcode, (u32 __user *)epc))
|
||||||
tcode = (opcode >> 12) & 0x1f;
|
goto out_sigsegv;
|
||||||
else
|
/* Immediate versions don't provide a code. */
|
||||||
tcode = ((opcode >> 6) & ((1 << 10) - 1));
|
if (!(opcode & OPCODE))
|
||||||
|
tcode = (opcode >> 6) & ((1 << 10) - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
do_trap_or_bp(regs, tcode, "Trap");
|
do_trap_or_bp(regs, tcode, "Trap");
|
||||||
|
|
Loading…
Reference in New Issue