diff options
author | Maciej W. Rozycki <macro@imgtec.com> | 2016-01-30 12:08:28 +0300 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2016-02-02 04:16:29 +0300 |
commit | 7aa7047100113ec9f5e4e685f94223825bd74a7b (patch) | |
tree | 6bea043bb48433dd7867fba6856ca0611ca24c7a /arch/mips | |
parent | 10f6d99f0fb186bbca1e9e2905d0d3693f941396 (diff) | |
download | linux-7aa7047100113ec9f5e4e685f94223825bd74a7b.tar.xz |
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: Maciej W. Rozycki <macro@imgtec.com>
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/12281/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips')
-rw-r--r-- | arch/mips/kernel/traps.c | 9 |
1 files changed, 5 insertions, 4 deletions
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index 485b0d517177..ae790c575d4f 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -663,7 +663,7 @@ static int simulate_rdhwr_normal(struct pt_regs *regs, unsigned int opcode) 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 @@ no_r2_instr: 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); |