Skip to content

Commit

Permalink
openrisc: traps: Don't send signals to kernel mode threads
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
stffrdhrn committed Apr 15, 2024
1 parent ee7e551 commit c88cfb5
Showing 1 changed file with 29 additions and 19 deletions.
48 changes: 29 additions & 19 deletions arch/openrisc/kernel/traps.c
Original file line number Diff line number Diff line change
Expand Up @@ -180,29 +180,39 @@ asmlinkage void unhandled_exception(struct pt_regs *regs, int ea, int vector)

asmlinkage void do_fpe_trap(struct pt_regs *regs, unsigned long address)
{
int code = FPE_FLTUNK;
unsigned long fpcsr = regs->fpcsr;

if (fpcsr & SPR_FPCSR_IVF)
code = FPE_FLTINV;
else if (fpcsr & SPR_FPCSR_OVF)
code = FPE_FLTOVF;
else if (fpcsr & SPR_FPCSR_UNF)
code = FPE_FLTUND;
else if (fpcsr & SPR_FPCSR_DZF)
code = FPE_FLTDIV;
else if (fpcsr & SPR_FPCSR_IXF)
code = FPE_FLTRES;

/* Clear all flags */
regs->fpcsr &= ~SPR_FPCSR_ALLF;

force_sig_fault(SIGFPE, code, (void __user *)regs->pc);
if (user_mode(regs)) {
int code = FPE_FLTUNK;
unsigned long fpcsr = regs->fpcsr;

if (fpcsr & SPR_FPCSR_IVF)
code = FPE_FLTINV;
else if (fpcsr & SPR_FPCSR_OVF)
code = FPE_FLTOVF;
else if (fpcsr & SPR_FPCSR_UNF)
code = FPE_FLTUND;
else if (fpcsr & SPR_FPCSR_DZF)
code = FPE_FLTDIV;
else if (fpcsr & SPR_FPCSR_IXF)
code = FPE_FLTRES;

/* Clear all flags */
regs->fpcsr &= ~SPR_FPCSR_ALLF;

force_sig_fault(SIGFPE, code, (void __user *)regs->pc);
} else {
pr_emerg("KERNEL: Illegal fpe exception 0x%.8lx\n", regs->pc);
die("Die:", regs, SIGFPE);
}
}

asmlinkage void do_trap(struct pt_regs *regs, unsigned long address)
{
force_sig_fault(SIGTRAP, TRAP_BRKPT, (void __user *)regs->pc);
if (user_mode(regs)) {
force_sig_fault(SIGTRAP, TRAP_BRKPT, (void __user *)regs->pc);
} else {
pr_emerg("KERNEL: Illegal trap exception 0x%.8lx\n", regs->pc);
die("Die:", regs, SIGILL);
}
}

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

0 comments on commit c88cfb5

Please sign in to comment.