From a9db101b735a9d49295326ae41f610f6da62b08c Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Fri, 16 Jun 2017 00:06:19 +0100 Subject: MIPS: Actually decode JALX in `__compute_return_epc_for_insn' Complement commit fb6883e5809c ("MIPS: microMIPS: Support handling of delay slots.") and actually decode the regular MIPS JALX major instruction opcode, the handling of which has been added with the said commit for EPC calculation in `__compute_return_epc_for_insn'. Fixes: fb6883e5809c ("MIPS: microMIPS: Support handling of delay slots.") Signed-off-by: Maciej W. Rozycki Cc: James Hogan Cc: linux-mips@linux-mips.org Cc: stable@vger.kernel.org # 3.9+ Patchwork: https://patchwork.linux-mips.org/patch/16394/ Signed-off-by: Ralf Baechle --- arch/mips/kernel/branch.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch/mips/kernel/branch.c') diff --git a/arch/mips/kernel/branch.c b/arch/mips/kernel/branch.c index f702a45..40cc3de 100644 --- a/arch/mips/kernel/branch.c +++ b/arch/mips/kernel/branch.c @@ -556,6 +556,7 @@ int __compute_return_epc_for_insn(struct pt_regs *regs, /* * These are unconditional and in j_format. */ + case jalx_op: case jal_op: regs->regs[31] = regs->cp0_epc + 8; case j_op: -- cgit v1.1 From 7b82c1058ac1f8f8b9f2b8786b1f710a57a870a8 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Fri, 16 Jun 2017 00:08:29 +0100 Subject: MIPS: Send SIGILL for BPOSGE32 in `__compute_return_epc_for_insn' Fix commit e50c0a8fa60d ("Support the MIPS32 / MIPS64 DSP ASE.") and send SIGILL rather than SIGBUS whenever an unimplemented BPOSGE32 DSP ASE instruction has been encountered in `__compute_return_epc_for_insn' as our Reserved Instruction exception handler would in response to an attempt to actually execute the instruction. Sending SIGBUS only makes sense for the unaligned PC case, since moved to `__compute_return_epc'. Adjust function documentation accordingly, correct formatting and use `pr_info' rather than `printk' as the other exit path already does. Fixes: e50c0a8fa60d ("Support the MIPS32 / MIPS64 DSP ASE.") Signed-off-by: Maciej W. Rozycki Cc: James Hogan Cc: linux-mips@linux-mips.org Cc: stable@vger.kernel.org # 2.6.14+ Patchwork: https://patchwork.linux-mips.org/patch/16396/ Signed-off-by: Ralf Baechle --- arch/mips/kernel/branch.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'arch/mips/kernel/branch.c') diff --git a/arch/mips/kernel/branch.c b/arch/mips/kernel/branch.c index 40cc3de..81b5608 100644 --- a/arch/mips/kernel/branch.c +++ b/arch/mips/kernel/branch.c @@ -399,7 +399,7 @@ int __MIPS16e_compute_return_epc(struct pt_regs *regs) * * @regs: Pointer to pt_regs * @insn: branch instruction to decode - * @returns: -EFAULT on error and forces SIGBUS, and on success + * @returns: -EFAULT on error and forces SIGILL, and on success * returns 0 or BRANCH_LIKELY_TAKEN as appropriate after * evaluating the branch. * @@ -832,8 +832,9 @@ int __compute_return_epc_for_insn(struct pt_regs *regs, return ret; sigill_dsp: - printk("%s: DSP branch but not DSP ASE - sending SIGBUS.\n", current->comm); - force_sig(SIGBUS, current); + pr_info("%s: DSP branch but not DSP ASE - sending SIGILL.\n", + current->comm); + force_sig(SIGILL, current); return -EFAULT; sigill_r6: pr_info("%s: R2 branch but r2-to-r6 emulator is not preset - sending SIGILL.\n", -- cgit v1.1 From 1f4edde422961397cf4470b347958c13c6a740bb Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Fri, 16 Jun 2017 00:09:23 +0100 Subject: MIPS: Rename `sigill_r6' to `sigill_r2r6' in `__compute_return_epc_for_insn' Use the more accurate `sigill_r2r6' name for the label used in the case of sending SIGILL in the absence of the instruction emulator for an earlier ISA level instruction that has been removed as from the R6 ISA, so that the `sigill_r6' name is freed for the situation where an R6 instruction is not supposed to be interpreted, because the executing processor does not support the R6 ISA. Signed-off-by: Maciej W. Rozycki Cc: James Hogan Cc: linux-mips@linux-mips.org Cc: stable@vger.kernel.org # 3.19+ Patchwork: https://patchwork.linux-mips.org/patch/16397/ Signed-off-by: Ralf Baechle --- arch/mips/kernel/branch.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'arch/mips/kernel/branch.c') diff --git a/arch/mips/kernel/branch.c b/arch/mips/kernel/branch.c index 81b5608..df5c32b 100644 --- a/arch/mips/kernel/branch.c +++ b/arch/mips/kernel/branch.c @@ -431,7 +431,7 @@ int __compute_return_epc_for_insn(struct pt_regs *regs, /* Fall through */ case jr_op: if (NO_R6EMU && insn.r_format.func == jr_op) - goto sigill_r6; + goto sigill_r2r6; regs->cp0_epc = regs->regs[insn.r_format.rs]; break; } @@ -446,7 +446,7 @@ int __compute_return_epc_for_insn(struct pt_regs *regs, switch (insn.i_format.rt) { case bltzl_op: if (NO_R6EMU) - goto sigill_r6; + goto sigill_r2r6; case bltz_op: if ((long)regs->regs[insn.i_format.rs] < 0) { epc = epc + 4 + (insn.i_format.simmediate << 2); @@ -459,7 +459,7 @@ int __compute_return_epc_for_insn(struct pt_regs *regs, case bgezl_op: if (NO_R6EMU) - goto sigill_r6; + goto sigill_r2r6; case bgez_op: if ((long)regs->regs[insn.i_format.rs] >= 0) { epc = epc + 4 + (insn.i_format.simmediate << 2); @@ -574,7 +574,7 @@ int __compute_return_epc_for_insn(struct pt_regs *regs, */ case beql_op: if (NO_R6EMU) - goto sigill_r6; + goto sigill_r2r6; case beq_op: if (regs->regs[insn.i_format.rs] == regs->regs[insn.i_format.rt]) { @@ -588,7 +588,7 @@ int __compute_return_epc_for_insn(struct pt_regs *regs, case bnel_op: if (NO_R6EMU) - goto sigill_r6; + goto sigill_r2r6; case bne_op: if (regs->regs[insn.i_format.rs] != regs->regs[insn.i_format.rt]) { @@ -602,7 +602,7 @@ int __compute_return_epc_for_insn(struct pt_regs *regs, case blezl_op: /* not really i_format */ if (!insn.i_format.rt && NO_R6EMU) - goto sigill_r6; + goto sigill_r2r6; case blez_op: /* * Compact branches for R6 for the @@ -637,7 +637,7 @@ int __compute_return_epc_for_insn(struct pt_regs *regs, case bgtzl_op: if (!insn.i_format.rt && NO_R6EMU) - goto sigill_r6; + goto sigill_r2r6; case bgtz_op: /* * Compact branches for R6 for the @@ -836,7 +836,7 @@ sigill_dsp: current->comm); force_sig(SIGILL, current); return -EFAULT; -sigill_r6: +sigill_r2r6: pr_info("%s: R2 branch but r2-to-r6 emulator is not preset - sending SIGILL.\n", current->comm); force_sig(SIGILL, current); -- cgit v1.1 From fef40be6da856afead4177aaa9d869a66fb3381f Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Fri, 16 Jun 2017 00:12:53 +0100 Subject: MIPS: Send SIGILL for linked branches in `__compute_return_epc_for_insn' Fix commit 319824eabc3f ("MIPS: kernel: branch: Do not emulate the branch likelies on MIPS R6") and also send SIGILL rather than returning -SIGILL for BLTZAL, BLTZALL, BGEZAL and BGEZALL instruction encodings no longer supported in R6, except where emulated. Returning -SIGILL is never correct as the API defines this function's result upon error to be -EFAULT and a signal actually issued. Fixes: 319824eabc3f ("MIPS: kernel: branch: Do not emulate the branch likelies on MIPS R6") Signed-off-by: Maciej W. Rozycki Cc: James Hogan Cc: linux-mips@linux-mips.org Cc: stable@vger.kernel.org # 3.19+ Patchwork: https://patchwork.linux-mips.org/patch/16398/ Signed-off-by: Ralf Baechle --- arch/mips/kernel/branch.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'arch/mips/kernel/branch.c') diff --git a/arch/mips/kernel/branch.c b/arch/mips/kernel/branch.c index df5c32b..64c8360 100644 --- a/arch/mips/kernel/branch.c +++ b/arch/mips/kernel/branch.c @@ -473,10 +473,8 @@ int __compute_return_epc_for_insn(struct pt_regs *regs, case bltzal_op: case bltzall_op: if (NO_R6EMU && (insn.i_format.rs || - insn.i_format.rt == bltzall_op)) { - ret = -SIGILL; - break; - } + insn.i_format.rt == bltzall_op)) + goto sigill_r2r6; regs->regs[31] = epc + 8; /* * OK we are here either because we hit a NAL @@ -507,10 +505,8 @@ int __compute_return_epc_for_insn(struct pt_regs *regs, case bgezal_op: case bgezall_op: if (NO_R6EMU && (insn.i_format.rs || - insn.i_format.rt == bgezall_op)) { - ret = -SIGILL; - break; - } + insn.i_format.rt == bgezall_op)) + goto sigill_r2r6; regs->regs[31] = epc + 8; /* * OK we are here either because we hit a BAL -- cgit v1.1 From a60b1a5bf88a250f1a77977c0224e502c901c77b Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Fri, 16 Jun 2017 00:14:12 +0100 Subject: MIPS: Send SIGILL for R6 branches in `__compute_return_epc_for_insn' Fix: * commit 8467ca0122e2 ("MIPS: Emulate the new MIPS R6 branch compact (BC) instruction"), * commit 84fef630127a ("MIPS: Emulate the new MIPS R6 BALC instruction"), * commit 69b9a2fd05a3 ("MIPS: Emulate the new MIPS R6 BEQZC and JIC instructions"), * commit 28d6f93d201d ("MIPS: Emulate the new MIPS R6 BNEZC and JIALC instructions"), * commit c893ce38b265 ("MIPS: Emulate the new MIPS R6 BOVC, BEQC and BEQZALC instructions") and send SIGILL rather than returning -SIGILL for R6 branch and jump instructions. Returning -SIGILL is never correct as the API defines this function's result upon error to be -EFAULT and a signal actually issued. Fixes: 8467ca0122e2 ("MIPS: Emulate the new MIPS R6 branch compact (BC) instruction") Fixes: 84fef630127a ("MIPS: Emulate the new MIPS R6 BALC instruction") Fixes: 69b9a2fd05a3 ("MIPS: Emulate the new MIPS R6 BEQZC and JIC instructions") Fixes: 28d6f93d201d ("MIPS: Emulate the new MIPS R6 BNEZC and JIALC instructions") Fixes: c893ce38b265 ("MIPS: Emulate the new MIPS R6 BOVC, BEQC and BEQZALC instructions") Signed-off-by: Maciej W. Rozycki Cc: James Hogan Cc: linux-mips@linux-mips.org Cc: stable@vger.kernel.org # 3.19+ Patchwork: https://patchwork.linux-mips.org/patch/16399/ Signed-off-by: Ralf Baechle --- arch/mips/kernel/branch.c | 35 +++++++++++++++-------------------- 1 file changed, 15 insertions(+), 20 deletions(-) (limited to 'arch/mips/kernel/branch.c') diff --git a/arch/mips/kernel/branch.c b/arch/mips/kernel/branch.c index 64c8360..6d536e5 100644 --- a/arch/mips/kernel/branch.c +++ b/arch/mips/kernel/branch.c @@ -771,35 +771,27 @@ int __compute_return_epc_for_insn(struct pt_regs *regs, #else case bc6_op: /* Only valid for MIPS R6 */ - if (!cpu_has_mips_r6) { - ret = -SIGILL; - break; - } + if (!cpu_has_mips_r6) + goto sigill_r6; regs->cp0_epc += 8; break; case balc6_op: - if (!cpu_has_mips_r6) { - ret = -SIGILL; - break; - } + if (!cpu_has_mips_r6) + goto sigill_r6; /* Compact branch: BALC */ regs->regs[31] = epc + 4; epc += 4 + (insn.i_format.simmediate << 2); regs->cp0_epc = epc; break; case pop66_op: - if (!cpu_has_mips_r6) { - ret = -SIGILL; - break; - } + if (!cpu_has_mips_r6) + goto sigill_r6; /* Compact branch: BEQZC || JIC */ regs->cp0_epc += 8; break; case pop76_op: - if (!cpu_has_mips_r6) { - ret = -SIGILL; - break; - } + if (!cpu_has_mips_r6) + goto sigill_r6; /* Compact branch: BNEZC || JIALC */ if (!insn.i_format.rs) { /* JIALC: set $31/ra */ @@ -811,10 +803,8 @@ int __compute_return_epc_for_insn(struct pt_regs *regs, case pop10_op: case pop30_op: /* Only valid for MIPS R6 */ - if (!cpu_has_mips_r6) { - ret = -SIGILL; - break; - } + if (!cpu_has_mips_r6) + goto sigill_r6; /* * Compact branches: * bovc, beqc, beqzalc, bnvc, bnec, bnezlac @@ -837,6 +827,11 @@ sigill_r2r6: current->comm); force_sig(SIGILL, current); return -EFAULT; +sigill_r6: + pr_info("%s: R6 branch but no MIPSr6 ISA support - sending SIGILL.\n", + current->comm); + force_sig(SIGILL, current); + return -EFAULT; } EXPORT_SYMBOL_GPL(__compute_return_epc_for_insn); -- cgit v1.1 From 27fe2200dad2de8207a694024a7b9037dff1b280 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Fri, 16 Jun 2017 00:15:22 +0100 Subject: MIPS: Fix a typo: s/preset/present/ in r2-to-r6 emulation error message This is a user-visible message, so we want it to be spelled correctly. Fixes: 5f9f41c474be ("MIPS: kernel: Prepare the JR instruction for emulation on MIPS R6") Signed-off-by: Maciej W. Rozycki Cc: James Hogan Cc: linux-mips@linux-mips.org Cc: stable@vger.kernel.org # 3.19+ Patchwork: https://patchwork.linux-mips.org/patch/16400/ Signed-off-by: Ralf Baechle --- arch/mips/kernel/branch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/mips/kernel/branch.c') diff --git a/arch/mips/kernel/branch.c b/arch/mips/kernel/branch.c index 6d536e5..e53379c 100644 --- a/arch/mips/kernel/branch.c +++ b/arch/mips/kernel/branch.c @@ -823,7 +823,7 @@ sigill_dsp: force_sig(SIGILL, current); return -EFAULT; sigill_r2r6: - pr_info("%s: R2 branch but r2-to-r6 emulator is not preset - sending SIGILL.\n", + pr_info("%s: R2 branch but r2-to-r6 emulator is not present - sending SIGILL.\n", current->comm); force_sig(SIGILL, current); return -EFAULT; -- cgit v1.1 From f259fe295ef07aafadf3316f58c4ac4eddfeccf1 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Fri, 16 Jun 2017 00:18:11 +0100 Subject: MIPS: Use `pr_debug' for messages from `__compute_return_epc_for_insn' Reduce the log level for branch emulation error messages issued before sending SIGILL by `__compute_return_epc_for_insn' as these are triggered by user software and are not an event that would normally require any attention. The same signal sent from elsewhere does not actually leave any trace in the kernel log at all. Signed-off-by: Maciej W. Rozycki Cc: James Hogan Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/16402/ Signed-off-by: Ralf Baechle --- arch/mips/kernel/branch.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'arch/mips/kernel/branch.c') diff --git a/arch/mips/kernel/branch.c b/arch/mips/kernel/branch.c index e53379c..b79ed9a 100644 --- a/arch/mips/kernel/branch.c +++ b/arch/mips/kernel/branch.c @@ -818,18 +818,18 @@ int __compute_return_epc_for_insn(struct pt_regs *regs, return ret; sigill_dsp: - pr_info("%s: DSP branch but not DSP ASE - sending SIGILL.\n", - current->comm); + pr_debug("%s: DSP branch but not DSP ASE - sending SIGILL.\n", + current->comm); force_sig(SIGILL, current); return -EFAULT; sigill_r2r6: - pr_info("%s: R2 branch but r2-to-r6 emulator is not present - sending SIGILL.\n", - current->comm); + pr_debug("%s: R2 branch but r2-to-r6 emulator is not present - sending SIGILL.\n", + current->comm); force_sig(SIGILL, current); return -EFAULT; sigill_r6: - pr_info("%s: R6 branch but no MIPSr6 ISA support - sending SIGILL.\n", - current->comm); + pr_debug("%s: R6 branch but no MIPSr6 ISA support - sending SIGILL.\n", + current->comm); force_sig(SIGILL, current); return -EFAULT; } -- cgit v1.1