Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933668AbcKGS4B (ORCPT ); Mon, 7 Nov 2016 13:56:01 -0500 Received: from mailapp01.imgtec.com ([195.59.15.196]:4753 "EHLO mailapp01.imgtec.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933166AbcKGSz7 (ORCPT ); Mon, 7 Nov 2016 13:55:59 -0500 Subject: [PATCH] MIPS: R2-on-R6 emulation bugfix of BLEZL and BGTZL instructions From: Leonid Yegoshin To: , , , , , Date: Mon, 7 Nov 2016 10:39:28 -0800 Message-ID: <20161107183928.27456.13089.stgit@ubuntu-yegoshin> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Originating-IP: [10.20.2.61] Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 1557 Lines: 47 MIPS R2 emulation doesn't take into account that BLEZL and BGTZL instructions require register RT = 0. If it is not zero it can be some legitimate MIPS R6 instruction. Problem happens after emulation optimization then emulation routine tries to pipeline emulation and after emulation of one instruction it picks up a next candidate. In single pass strategy it does not happen because CPU doesn't trap on branch-compacts which share opcode space with BLEZL/BGTZL (but has RT != 0, of course). Signed-off-by: Leonid Yegoshin Reported-by: Douglas Leung --- arch/mips/kernel/mips-r2-to-r6-emul.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/arch/mips/kernel/mips-r2-to-r6-emul.c b/arch/mips/kernel/mips-r2-to-r6-emul.c index 22dedd62818a..b0c86b08c0b9 100644 --- a/arch/mips/kernel/mips-r2-to-r6-emul.c +++ b/arch/mips/kernel/mips-r2-to-r6-emul.c @@ -919,6 +919,7 @@ int mipsr2_decoder(struct pt_regs *regs, u32 inst, unsigned long *fcr31) BUG(); return SIGEMT; } + err = 0; pr_debug("Emulating the 0x%08x R2 instruction @ 0x%08lx (pass=%d))\n", inst, epc, pass); @@ -1096,10 +1097,16 @@ int mipsr2_decoder(struct pt_regs *regs, u32 inst, unsigned long *fcr31) } break; - case beql_op: - case bnel_op: case blezl_op: case bgtzl_op: + /* return MIPS R6 instruction to CPU execution */ + if (MIPSInst_RT(inst)) { + err = SIGILL; + break; + } + + case beql_op: + case bnel_op: if (delay_slot(regs)) { err = SIGILL; break;