| From d65e5677ad5b3a49c43f60ec07644dc1f87bbd2e Mon Sep 17 00:00:00 2001 |
| From: Leonid Yegoshin <Leonid.Yegoshin@imgtec.com> |
| Date: Thu, 25 Aug 2016 10:37:38 -0700 |
| Subject: [PATCH] MIPS: R2-on-R6 MULTU/MADDU/MSUBU emulation bugfix |
| |
| commit d65e5677ad5b3a49c43f60ec07644dc1f87bbd2e upstream. |
| |
| MIPS instructions MULTU, MADDU and MSUBU emulation requires registers HI/LO |
| to be converted to signed 32bits before 64bit sign extension on MIPS64. |
| |
| Bug was found on running MIPS32 R2 test application on MIPS64 R6 kernel. |
| |
| Fixes: b0a668fb2038 ("MIPS: kernel: mips-r2-to-r6-emul: Add R2 emulator for MIPS R6") |
| Signed-off-by: Leonid Yegoshin <Leonid.Yegoshin@imgtec.com> |
| Reported-by: Nikola.Veljkovic@imgtec.com |
| Cc: paul.burton@imgtec.com |
| Cc: yamada.masahiro@socionext.com |
| Cc: akpm@linux-foundation.org |
| Cc: andrea.gelmini@gelma.net |
| Cc: macro@imgtec.com |
| Cc: linux-mips@linux-mips.org |
| Patchwork: https://patchwork.linux-mips.org/patch/14043/ |
| Signed-off-by: Ralf Baechle <ralf@linux-mips.org> |
| |
| diff --git a/arch/mips/kernel/mips-r2-to-r6-emul.c b/arch/mips/kernel/mips-r2-to-r6-emul.c |
| index ef2ca28a028b..d8f1cf1ec370 100644 |
| --- a/arch/mips/kernel/mips-r2-to-r6-emul.c |
| +++ b/arch/mips/kernel/mips-r2-to-r6-emul.c |
| @@ -433,8 +433,8 @@ static int multu_func(struct pt_regs *regs, u32 ir) |
| rs = regs->regs[MIPSInst_RS(ir)]; |
| res = (u64)rt * (u64)rs; |
| rt = res; |
| - regs->lo = (s64)rt; |
| - regs->hi = (s64)(res >> 32); |
| + regs->lo = (s64)(s32)rt; |
| + regs->hi = (s64)(s32)(res >> 32); |
| |
| MIPS_R2_STATS(muls); |
| |
| @@ -670,9 +670,9 @@ static int maddu_func(struct pt_regs *regs, u32 ir) |
| res += ((((s64)rt) << 32) | (u32)rs); |
| |
| rt = res; |
| - regs->lo = (s64)rt; |
| + regs->lo = (s64)(s32)rt; |
| rs = res >> 32; |
| - regs->hi = (s64)rs; |
| + regs->hi = (s64)(s32)rs; |
| |
| MIPS_R2_STATS(dsps); |
| |
| @@ -728,9 +728,9 @@ static int msubu_func(struct pt_regs *regs, u32 ir) |
| res = ((((s64)rt) << 32) | (u32)rs) - res; |
| |
| rt = res; |
| - regs->lo = (s64)rt; |
| + regs->lo = (s64)(s32)rt; |
| rs = res >> 32; |
| - regs->hi = (s64)rs; |
| + regs->hi = (s64)(s32)rs; |
| |
| MIPS_R2_STATS(dsps); |
| |
| -- |
| 2.12.0 |
| |