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>
This commit is contained in:
committed by
Ralf Baechle
parent
10f6d99f0f
commit
7aa7047100
@@ -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 @@ no_r2_instr:
|
|||||||
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);
|
||||||
|
|||||||
Reference in New Issue
Block a user