diff options
author | Maciej W. Rozycki <macro@imgtec.com> | 2016-01-30 04:08:43 -0500 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2016-04-04 09:25:34 -0400 |
commit | 3d50a7fb42992545e45e10b068406546ea699489 (patch) | |
tree | 377a54dd0c80f3f287e4463d3ea9577866384cfa | |
parent | 6870e707c6d934329872eadc77a7d2d07586e36c (diff) |
MIPS: traps.c: Verify the ISA for microMIPS RDHWR emulation
Make sure it's the microMIPS rather than MIPS16 ISA before emulating
microMIPS RDHWR. Mostly needed as an optimisation for configurations
where `cpu_has_mmips' is hardcoded to 0 and also a good measure in case
we add further microMIPS instructions to emulate in the future, as the
corresponding MIPS16 encoding is ADDIUSP, not supposed to trap.
Signed-off-by: Maciej W. Rozycki <macro@imgtec.com>
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/12282/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
-rw-r--r-- | arch/mips/kernel/traps.c | 26 |
1 files changed, 13 insertions, 13 deletions
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index 80339ce64521..ae0c89d23ad7 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c | |||
@@ -1122,19 +1122,7 @@ no_r2_instr: | |||
1122 | if (unlikely(compute_return_epc(regs) < 0)) | 1122 | if (unlikely(compute_return_epc(regs) < 0)) |
1123 | goto out; | 1123 | goto out; |
1124 | 1124 | ||
1125 | if (get_isa16_mode(regs->cp0_epc)) { | 1125 | if (!get_isa16_mode(regs->cp0_epc)) { |
1126 | unsigned short mmop[2] = { 0 }; | ||
1127 | |||
1128 | if (unlikely(get_user(mmop[0], (u16 __user *)epc + 0) < 0)) | ||
1129 | status = SIGSEGV; | ||
1130 | if (unlikely(get_user(mmop[1], (u16 __user *)epc + 1) < 0)) | ||
1131 | status = SIGSEGV; | ||
1132 | opcode = mmop[0]; | ||
1133 | opcode = (opcode << 16) | mmop[1]; | ||
1134 | |||
1135 | if (status < 0) | ||
1136 | status = simulate_rdhwr_mm(regs, opcode); | ||
1137 | } else { | ||
1138 | if (unlikely(get_user(opcode, epc) < 0)) | 1126 | if (unlikely(get_user(opcode, epc) < 0)) |
1139 | status = SIGSEGV; | 1127 | status = SIGSEGV; |
1140 | 1128 | ||
@@ -1149,6 +1137,18 @@ no_r2_instr: | |||
1149 | 1137 | ||
1150 | if (status < 0) | 1138 | if (status < 0) |
1151 | status = simulate_fp(regs, opcode, old_epc, old31); | 1139 | status = simulate_fp(regs, opcode, old_epc, old31); |
1140 | } else if (cpu_has_mmips) { | ||
1141 | unsigned short mmop[2] = { 0 }; | ||
1142 | |||
1143 | if (unlikely(get_user(mmop[0], (u16 __user *)epc + 0) < 0)) | ||
1144 | status = SIGSEGV; | ||
1145 | if (unlikely(get_user(mmop[1], (u16 __user *)epc + 1) < 0)) | ||
1146 | status = SIGSEGV; | ||
1147 | opcode = mmop[0]; | ||
1148 | opcode = (opcode << 16) | mmop[1]; | ||
1149 | |||
1150 | if (status < 0) | ||
1151 | status = simulate_rdhwr_mm(regs, opcode); | ||
1152 | } | 1152 | } |
1153 | 1153 | ||
1154 | if (status < 0) | 1154 | if (status < 0) |