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

Commit 7aa70471 authored by Maciej W. Rozycki's avatar Maciej W. Rozycki Committed by Ralf Baechle
Browse files

MIPS: traps.c: Correct microMIPS RDHWR emulation



Fix the code to fetch and decode the whole 32-bit instruction.  This
only really matters with the `noulri' kernel parameter as all microMIPS
processors are supposed to have all the hardware registers we support.

Signed-off-by: default avatarMaciej W. Rozycki <macro@imgtec.com>
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/12281/


Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>
parent 10f6d99f
Loading
Loading
Loading
Loading
+5 −4
Original line number Original line Diff line number Diff line
@@ -663,7 +663,7 @@ static int simulate_rdhwr_normal(struct pt_regs *regs, unsigned int opcode)
	return -1;
	return -1;
}
}


static int simulate_rdhwr_mm(struct pt_regs *regs, unsigned short opcode)
static int simulate_rdhwr_mm(struct pt_regs *regs, unsigned int opcode)
{
{
	if ((opcode & MM_POOL32A_FUNC) == MM_RDHWR) {
	if ((opcode & MM_POOL32A_FUNC) == MM_RDHWR) {
		int rd = (opcode & MM_RS) >> 16;
		int rd = (opcode & MM_RS) >> 16;
@@ -1119,11 +1119,12 @@ asmlinkage void do_ri(struct pt_regs *regs)
	if (get_isa16_mode(regs->cp0_epc)) {
	if (get_isa16_mode(regs->cp0_epc)) {
		unsigned short mmop[2] = { 0 };
		unsigned short mmop[2] = { 0 };


		if (unlikely(get_user(mmop[0], epc) < 0))
		if (unlikely(get_user(mmop[0], (u16 __user *)epc + 0) < 0))
			status = SIGSEGV;
			status = SIGSEGV;
		if (unlikely(get_user(mmop[1], epc) < 0))
		if (unlikely(get_user(mmop[1], (u16 __user *)epc + 1) < 0))
			status = SIGSEGV;
			status = SIGSEGV;
		opcode = (mmop[0] << 16) | mmop[1];
		opcode = mmop[0];
		opcode = (opcode << 16) | mmop[1];


		if (status < 0)
		if (status < 0)
			status = simulate_rdhwr_mm(regs, opcode);
			status = simulate_rdhwr_mm(regs, opcode);