[PATCH 2/3] MIPS: traps.c: Correct microMIPS RDHWR emulation

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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: Maciej W. Rozycki <macro@xxxxxxxxxx>
---
linux-umips-rdhwr-opcode.diff
Index: linux-sfr-test/arch/mips/kernel/traps.c
===================================================================
--- linux-sfr-test.orig/arch/mips/kernel/traps.c	2016-01-30 03:39:20.000000000 +0000
+++ linux-sfr-test/arch/mips/kernel/traps.c	2016-01-30 03:40:58.944753000 +0000
@@ -663,7 +663,7 @@ static int simulate_rdhwr_normal(struct 
 	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) {
 		int rd = (opcode & MM_RS) >> 16;
@@ -1119,11 +1119,12 @@ asmlinkage void do_ri(struct pt_regs *re
 	if (get_isa16_mode(regs->cp0_epc)) {
 		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;
-		if (unlikely(get_user(mmop[1], epc) < 0))
+		if (unlikely(get_user(mmop[1], (u16 __user *)epc + 1) < 0))
 			status = SIGSEGV;
-		opcode = (mmop[0] << 16) | mmop[1];
+		opcode = mmop[0];
+		opcode = (opcode << 16) | mmop[1];
 
 		if (status < 0)
 			status = simulate_rdhwr_mm(regs, opcode);




[Index of Archives]     [Linux MIPS Home]     [LKML Archive]     [Linux ARM Kernel]     [Linux ARM]     [Linux]     [Git]     [Yosemite News]     [Linux SCSI]     [Linux Hams]

  Powered by Linux