diff options
author | Leonid Yegoshin <Leonid.Yegoshin@imgtec.com> | 2016-08-25 13:37:38 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-05-14 08:00:20 -0400 |
commit | b0e2e3acfe8ebe95e9d6189b94e75d685c7f6d15 (patch) | |
tree | 473cb7ed821e8b2085bd7f678697e1ba6eecd32d | |
parent | 2d652d0abd3ccda1097345d13d728b8ba1b7c68f (diff) |
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>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | arch/mips/kernel/mips-r2-to-r6-emul.c | 12 |
1 files changed, 6 insertions, 6 deletions
diff --git a/arch/mips/kernel/mips-r2-to-r6-emul.c b/arch/mips/kernel/mips-r2-to-r6-emul.c index bd09853aecdf..d8227f289d7f 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) | |||
433 | rs = regs->regs[MIPSInst_RS(ir)]; | 433 | rs = regs->regs[MIPSInst_RS(ir)]; |
434 | res = (u64)rt * (u64)rs; | 434 | res = (u64)rt * (u64)rs; |
435 | rt = res; | 435 | rt = res; |
436 | regs->lo = (s64)rt; | 436 | regs->lo = (s64)(s32)rt; |
437 | regs->hi = (s64)(res >> 32); | 437 | regs->hi = (s64)(s32)(res >> 32); |
438 | 438 | ||
439 | MIPS_R2_STATS(muls); | 439 | MIPS_R2_STATS(muls); |
440 | 440 | ||
@@ -670,9 +670,9 @@ static int maddu_func(struct pt_regs *regs, u32 ir) | |||
670 | res += ((((s64)rt) << 32) | (u32)rs); | 670 | res += ((((s64)rt) << 32) | (u32)rs); |
671 | 671 | ||
672 | rt = res; | 672 | rt = res; |
673 | regs->lo = (s64)rt; | 673 | regs->lo = (s64)(s32)rt; |
674 | rs = res >> 32; | 674 | rs = res >> 32; |
675 | regs->hi = (s64)rs; | 675 | regs->hi = (s64)(s32)rs; |
676 | 676 | ||
677 | MIPS_R2_STATS(dsps); | 677 | MIPS_R2_STATS(dsps); |
678 | 678 | ||
@@ -728,9 +728,9 @@ static int msubu_func(struct pt_regs *regs, u32 ir) | |||
728 | res = ((((s64)rt) << 32) | (u32)rs) - res; | 728 | res = ((((s64)rt) << 32) | (u32)rs) - res; |
729 | 729 | ||
730 | rt = res; | 730 | rt = res; |
731 | regs->lo = (s64)rt; | 731 | regs->lo = (s64)(s32)rt; |
732 | rs = res >> 32; | 732 | rs = res >> 32; |
733 | regs->hi = (s64)rs; | 733 | regs->hi = (s64)(s32)rs; |
734 | 734 | ||
735 | MIPS_R2_STATS(dsps); | 735 | MIPS_R2_STATS(dsps); |
736 | 736 | ||