aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMaciej W. Rozycki <macro@imgtec.com>2016-01-30 04:08:43 -0500
committerRalf Baechle <ralf@linux-mips.org>2016-04-04 09:25:34 -0400
commit3d50a7fb42992545e45e10b068406546ea699489 (patch)
tree377a54dd0c80f3f287e4463d3ea9577866384cfa
parent6870e707c6d934329872eadc77a7d2d07586e36c (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.c26
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)