Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cea8cd49 authored by Matt Redfearn's avatar Matt Redfearn Committed by Ralf Baechle
Browse files

MIPS: microMIPS: Fix decoding of swsp16 instruction



When the immediate encoded in the instruction is accessed, it is sign
extended due to being a signed value being assigned to a signed integer.
The ISA specifies that this operation is an unsigned operation.
The sign extension leads us to incorrectly decode:

801e9c8e:       cbf1            sw      ra,68(sp)

As having an immediate of 1073741809.

Since the instruction format does not specify signed/unsigned, and this
is currently the only location to use this instuction format, change it
to an unsigned immediate.

Fixes: bb9bc468 ("MIPS: Calculate microMIPS ra properly when unwinding the stack")
Suggested-by: default avatarPaul Burton <paul.burton@imgtec.com>
Signed-off-by: default avatarMatt Redfearn <matt.redfearn@imgtec.com>
Reviewed-by: default avatarJames Hogan <james.hogan@imgtec.com>
Cc: Marcin Nowakowski <marcin.nowakowski@imgtec.com>
Cc: Miodrag Dinic <miodrag.dinic@imgtec.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: David Daney <david.daney@cavium.com>
Cc: linux-mips@linux-mips.org
Cc: linux-kernel@vger.kernel.org
Patchwork: https://patchwork.linux-mips.org/patch/16957/


Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>
parent a0ae2b08
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -981,7 +981,7 @@ struct mm16_r3_format { /* Load from global pointer format */
struct mm16_r5_format {		/* Load/store from stack pointer format */
	__BITFIELD_FIELD(unsigned int opcode : 6,
	__BITFIELD_FIELD(unsigned int rt : 5,
	__BITFIELD_FIELD(signed int simmediate : 5,
	__BITFIELD_FIELD(unsigned int imm : 5,
	__BITFIELD_FIELD(unsigned int : 16, /* Ignored */
	;))))
};
+1 −1
Original line number Diff line number Diff line
@@ -214,7 +214,7 @@ static inline int is_ra_save_ins(union mips_instruction *ip, int *poff)
			if (ip->mm16_r5_format.rt != 31)
				return 0;

			*poff = ip->mm16_r5_format.simmediate;
			*poff = ip->mm16_r5_format.imm;
			*poff = (*poff << 2) / sizeof(ulong);
			return 1;