diff --git a/arch/mips/include/asm/fpu_emulator.h b/arch/mips/include/asm/fpu_emulator.h index 2f021cdfba4f..3225c3c0724b 100644 --- a/arch/mips/include/asm/fpu_emulator.h +++ b/arch/mips/include/asm/fpu_emulator.h @@ -79,7 +79,7 @@ int mm_isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn, /* * Break instruction with special math emu break code set */ -#define BREAK_MATH (0x0000000d | (BRK_MEMU << 16)) +#define BREAK_MATH(micromips) (((micromips) ? 0x7 : 0xd) | (BRK_MEMU << 16)) #define SIGNALLING_NAN 0x7ff800007ff80000LL diff --git a/arch/mips/include/asm/mips-r2-to-r6-emul.h b/arch/mips/include/asm/mips-r2-to-r6-emul.h index 4b89f28047f7..1f6ea8352ca9 100644 --- a/arch/mips/include/asm/mips-r2-to-r6-emul.h +++ b/arch/mips/include/asm/mips-r2-to-r6-emul.h @@ -52,7 +52,7 @@ do { \ __this_cpu_inc(mipsr2emustats.M); \ err = __get_user(nir, (u32 __user *)regs->cp0_epc); \ if (!err) { \ - if (nir == BREAK_MATH) \ + if (nir == BREAK_MATH(0)) \ __this_cpu_inc(mipsr2bdemustats.M); \ } \ preempt_enable(); \ diff --git a/arch/mips/math-emu/dsemul.c b/arch/mips/math-emu/dsemul.c index 4e30bfc3cdd5..32ec5d7e1728 100644 --- a/arch/mips/math-emu/dsemul.c +++ b/arch/mips/math-emu/dsemul.c @@ -38,6 +38,7 @@ struct emuframe { */ int mips_dsemul(struct pt_regs *regs, mips_instruction ir, unsigned long cpc) { + mips_instruction break_math; struct emuframe __user *fr; int err; @@ -65,6 +66,7 @@ int mips_dsemul(struct pt_regs *regs, mips_instruction ir, unsigned long cpc) * branches, but gives us a cleaner interface to the exception * handler (single entry point). */ + break_math = BREAK_MATH(get_isa16_mode(regs->cp0_epc)); /* Ensure that the two instructions are in the same cache line */ fr = (struct emuframe __user *) @@ -79,13 +81,13 @@ int mips_dsemul(struct pt_regs *regs, mips_instruction ir, unsigned long cpc) (u16 __user *)(&fr->emul)); err |= __put_user(ir & 0xffff, (u16 __user *)((long)(&fr->emul) + 2)); - err |= __put_user(BREAK_MATH >> 16, + err |= __put_user(break_math >> 16, (u16 __user *)(&fr->badinst)); - err |= __put_user(BREAK_MATH & 0xffff, + err |= __put_user(break_math & 0xffff, (u16 __user *)((long)(&fr->badinst) + 2)); } else { err = __put_user(ir, &fr->emul); - err |= __put_user((mips_instruction)BREAK_MATH, &fr->badinst); + err |= __put_user(break_math, &fr->badinst); } err |= __put_user((mips_instruction)BD_COOKIE, &fr->cookie); @@ -139,7 +141,8 @@ int do_dsemulret(struct pt_regs *xcp) } err |= __get_user(cookie, &fr->cookie); - if (unlikely(err || (insn != BREAK_MATH) || (cookie != BD_COOKIE))) { + if (unlikely(err || insn != BREAK_MATH(get_isa16_mode(xcp->cp0_epc)) || + cookie != BD_COOKIE)) { MIPS_FPU_EMU_INC_STATS(errors); return 0; }