From 83299917c5d19e0e4cd793b60aa5d326875bd495 Mon Sep 17 00:00:00 2001 From: Jukka Laitinen Date: Tue, 19 Mar 2024 11:41:41 +0200 Subject: [PATCH] arch/risc-v/src/common/riscv_exception.c: Just _exit the user task causing 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 --- arch/risc-v/src/common/riscv_exception.c | 35 +++++++++++++++++++++--- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/arch/risc-v/src/common/riscv_exception.c b/arch/risc-v/src/common/riscv_exception.c index f560a60b0a0be..bb81e6066da44 100644 --- a/arch/risc-v/src/common/riscv_exception.c +++ b/arch/risc-v/src/common/riscv_exception.c @@ -31,6 +31,7 @@ #include #include +#include "sched/sched.h" #include "riscv_internal.h" #include "chip.h" @@ -72,6 +73,9 @@ 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 @@ -79,10 +83,33 @@ int riscv_exception(int mcause, void *regs, void *args) 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; }