From 733b8bc183f491e8263009edf8ef184fb44a6882 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Fri, 22 Jan 2016 05:20:46 +0000 Subject: MIPS: math-emu: Make microMIPS branch delay slot emulation work Complement commit 102cedc32a6e ("MIPS: microMIPS: Floating point support.") which introduced microMIPS FPU emulation, but did not adjust the encoding of the BREAK instruction used to terminate the branch delay slot emulation frame. Consequently the execution of any such frame is indeterminate and, depending on CPU configuration, will result in random code execution or an offending program being terminated with SIGILL. This is because the regular MIPS BREAK instruction is encoded with the 0 major and the 0xd minor opcode, however in the microMIPS instruction set this major/minor opcode pair denotes an encoding reserved for the DSP ASE. Instead the microMIPS BREAK instruction is encoded with the 0 major and the 0x7 minor opcode. Use the correct BREAK encoding for microMIPS FPU emulation then. Signed-off-by: Maciej W. Rozycki Cc: Aurelien Jarno Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/12174/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/fpu_emulator.h | 2 +- arch/mips/include/asm/mips-r2-to-r6-emul.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'arch/mips/include') 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(); \ -- cgit v1.2.3-59-g8ed1b