Skip to content

Commit c88cfb5

Browse files
committed
openrisc: traps: Don't send signals to kernel mode threads
OpenRISC exception handling sends signals to user processes on floating point exceptions and trap instructions (for debugging) among others. There is a bug where the trap handling logic may send signals to kernel threads, we should not send these signals to kernel threads, if that happens we treat it as an error. This patch adds conditions to die if the kernel receives these exceptions in kernel mode code. Fixes: 2726765 ("openrisc: Support floating point user api") Signed-off-by: Stafford Horne <shorne@gmail.com>
1 parent ee7e551 commit c88cfb5

File tree

1 file changed

+29
-19
lines changed

1 file changed

+29
-19
lines changed

arch/openrisc/kernel/traps.c

Lines changed: 29 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -180,29 +180,39 @@ asmlinkage void unhandled_exception(struct pt_regs *regs, int ea, int vector)
180180

181181
asmlinkage void do_fpe_trap(struct pt_regs *regs, unsigned long address)
182182
{
183-
int code = FPE_FLTUNK;
184-
unsigned long fpcsr = regs->fpcsr;
185-
186-
if (fpcsr & SPR_FPCSR_IVF)
187-
code = FPE_FLTINV;
188-
else if (fpcsr & SPR_FPCSR_OVF)
189-
code = FPE_FLTOVF;
190-
else if (fpcsr & SPR_FPCSR_UNF)
191-
code = FPE_FLTUND;
192-
else if (fpcsr & SPR_FPCSR_DZF)
193-
code = FPE_FLTDIV;
194-
else if (fpcsr & SPR_FPCSR_IXF)
195-
code = FPE_FLTRES;
196-
197-
/* Clear all flags */
198-
regs->fpcsr &= ~SPR_FPCSR_ALLF;
199-
200-
force_sig_fault(SIGFPE, code, (void __user *)regs->pc);
183+
if (user_mode(regs)) {
184+
int code = FPE_FLTUNK;
185+
unsigned long fpcsr = regs->fpcsr;
186+
187+
if (fpcsr & SPR_FPCSR_IVF)
188+
code = FPE_FLTINV;
189+
else if (fpcsr & SPR_FPCSR_OVF)
190+
code = FPE_FLTOVF;
191+
else if (fpcsr & SPR_FPCSR_UNF)
192+
code = FPE_FLTUND;
193+
else if (fpcsr & SPR_FPCSR_DZF)
194+
code = FPE_FLTDIV;
195+
else if (fpcsr & SPR_FPCSR_IXF)
196+
code = FPE_FLTRES;
197+
198+
/* Clear all flags */
199+
regs->fpcsr &= ~SPR_FPCSR_ALLF;
200+
201+
force_sig_fault(SIGFPE, code, (void __user *)regs->pc);
202+
} else {
203+
pr_emerg("KERNEL: Illegal fpe exception 0x%.8lx\n", regs->pc);
204+
die("Die:", regs, SIGFPE);
205+
}
201206
}
202207

203208
asmlinkage void do_trap(struct pt_regs *regs, unsigned long address)
204209
{
205-
force_sig_fault(SIGTRAP, TRAP_BRKPT, (void __user *)regs->pc);
210+
if (user_mode(regs)) {
211+
force_sig_fault(SIGTRAP, TRAP_BRKPT, (void __user *)regs->pc);
212+
} else {
213+
pr_emerg("KERNEL: Illegal trap exception 0x%.8lx\n", regs->pc);
214+
die("Die:", regs, SIGILL);
215+
}
206216
}
207217

208218
asmlinkage void do_unaligned_access(struct pt_regs *regs, unsigned long address)

0 commit comments

Comments
 (0)