Commit b0e2e3ac authored by Leonid Yegoshin's avatar Leonid Yegoshin Committed by Greg Kroah-Hartman

MIPS: R2-on-R6 MULTU/MADDU/MSUBU emulation bugfix

commit d65e5677 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: b0a668fb ("MIPS: kernel: mips-r2-to-r6-emul: Add R2 emulator for MIPS R6")
Signed-off-by: default avatarLeonid 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: default avatarRalf Baechle <ralf@linux-mips.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 2d652d0a
...@@ -433,8 +433,8 @@ static int multu_func(struct pt_regs *regs, u32 ir) ...@@ -433,8 +433,8 @@ static int multu_func(struct pt_regs *regs, u32 ir)
rs = regs->regs[MIPSInst_RS(ir)]; rs = regs->regs[MIPSInst_RS(ir)];
res = (u64)rt * (u64)rs; res = (u64)rt * (u64)rs;
rt = res; rt = res;
regs->lo = (s64)rt; regs->lo = (s64)(s32)rt;
regs->hi = (s64)(res >> 32); regs->hi = (s64)(s32)(res >> 32);
MIPS_R2_STATS(muls); MIPS_R2_STATS(muls);
...@@ -670,9 +670,9 @@ static int maddu_func(struct pt_regs *regs, u32 ir) ...@@ -670,9 +670,9 @@ static int maddu_func(struct pt_regs *regs, u32 ir)
res += ((((s64)rt) << 32) | (u32)rs); res += ((((s64)rt) << 32) | (u32)rs);
rt = res; rt = res;
regs->lo = (s64)rt; regs->lo = (s64)(s32)rt;
rs = res >> 32; rs = res >> 32;
regs->hi = (s64)rs; regs->hi = (s64)(s32)rs;
MIPS_R2_STATS(dsps); MIPS_R2_STATS(dsps);
...@@ -728,9 +728,9 @@ static int msubu_func(struct pt_regs *regs, u32 ir) ...@@ -728,9 +728,9 @@ static int msubu_func(struct pt_regs *regs, u32 ir)
res = ((((s64)rt) << 32) | (u32)rs) - res; res = ((((s64)rt) << 32) | (u32)rs) - res;
rt = res; rt = res;
regs->lo = (s64)rt; regs->lo = (s64)(s32)rt;
rs = res >> 32; rs = res >> 32;
regs->hi = (s64)rs; regs->hi = (s64)(s32)rs;
MIPS_R2_STATS(dsps); MIPS_R2_STATS(dsps);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment