Skip to content

Commit

Permalink
arch/risc-v/src/common/riscv_exception.c: Just _exit the user task ca…
Browse files Browse the repository at this point in the history
…using an exception

We shouldn't panic the kernel when a user task excepts, we can just kill the user task and
it's children. Do this by returning to _exit() in kernel context.

Signed-off-by: Jukka Laitinen <[email protected]>
  • Loading branch information
jlaitine committed Mar 21, 2024
1 parent e4d95ee commit ac70ce4
Showing 1 changed file with 31 additions and 4 deletions.
35 changes: 31 additions & 4 deletions arch/risc-v/src/common/riscv_exception.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include <nuttx/irq.h>
#include <nuttx/arch.h>

#include "sched/sched.h"
#include "riscv_internal.h"
#include "chip.h"

Expand Down Expand Up @@ -72,17 +73,43 @@ static const char *g_reasons_str[RISCV_MAX_EXCEPTION + 1] =

int riscv_exception(int mcause, void *regs, void *args)
{
#ifdef CONFIG_ARCH_KERNEL_STACK
FAR struct tcb_s *tcb = this_task();
#endif
uintptr_t cause = mcause & RISCV_IRQ_MASK;

_alert("EXCEPTION: %s. MCAUSE: %" PRIxREG ", EPC: %" PRIxREG
", MTVAL: %" PRIxREG "\n",
mcause > RISCV_MAX_EXCEPTION ? "Unknown" : g_reasons_str[cause],
cause, READ_CSR(CSR_EPC), READ_CSR(CSR_TVAL));

_alert("PANIC!!! Exception = %" PRIxREG "\n", cause);
up_irq_save();
CURRENT_REGS = regs;
PANIC_WITH_REGS("panic", regs);
#ifdef CONFIG_ARCH_KERNEL_STACK
if ((tcb->flags & TCB_FLAG_TTYPE_MASK) != TCB_FLAG_TTYPE_KERNEL)
{
_alert("Segmentation fault in PID %d: %s\n", tcb->pid, tcb->name);

tcb->flags |= TCB_FLAG_FORCED_CANCEL;

/* Return to _exit function in privileged mode with argument SIGSEGV */

CURRENT_REGS[REG_EPC] = (uintptr_t)_exit;
CURRENT_REGS[REG_A0] = SIGSEGV;
CURRENT_REGS[REG_INT_CTX] |= STATUS_PPP;

/* Continue with kernel stack in use. The frame(s) in kernel stack
* are no longer needed, so just set it to top
*/

CURRENT_REGS[REG_SP] = (uintptr_t)tcb->xcp.ktopstk;
}
else
#endif
{
_alert("PANIC!!! Exception = %" PRIxREG "\n", cause);
up_irq_save();
CURRENT_REGS = regs;
PANIC_WITH_REGS("panic", regs);
}

return 0;
}
Expand Down

0 comments on commit ac70ce4

Please sign in to comment.