This is an automated email from the ASF dual-hosted git repository.
xiaoxiang781216 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
The following commit(s) were added to refs/heads/master by this push:
new e0b4eb7c9cc arch/risc-v: kill faulting user task instead of panicking
kernel
e0b4eb7c9cc is described below
commit e0b4eb7c9cc1df17f6b6471bf531ed38af86b843
Author: liang.huang <[email protected]>
AuthorDate: Thu Jul 9 11:32:03 2026 +0800
arch/risc-v: kill faulting user task instead of panicking kernel
riscv_fillpage() unconditionally panics the kernel on an unmappable
or invalid access, even when the fault is caused by a user task. A
user-space fault should terminate that task with SIGSEGV instead of
taking down the whole system, matching the existing behavior for
other exceptions in riscv_exception().
Signed-off-by: liang.huang <[email protected]>
---
arch/risc-v/src/common/riscv_exception.c | 66 ++++++++++++++++++++------------
1 file changed, 42 insertions(+), 24 deletions(-)
diff --git a/arch/risc-v/src/common/riscv_exception.c
b/arch/risc-v/src/common/riscv_exception.c
index 584db45c025..8196444c983 100644
--- a/arch/risc-v/src/common/riscv_exception.c
+++ b/arch/risc-v/src/common/riscv_exception.c
@@ -83,26 +83,27 @@ static const char *g_reasons_str[RISCV_MAX_EXCEPTION + 1] =
****************************************************************************/
/****************************************************************************
- * Name: riscv_exception
+ * Name: riscv_fault_handler
*
* Description:
- * This is the exception handler.
+ * Handle a fault caused by the running task. If the task is a user task
+ * not currently in a syscall, kill it with SIGSEGV instead of
+ * taking down the whole system. Otherwise (kernel thread, or a fault
+ * while already in kernel context on behalf of a syscall) there is no
+ * safe task to kill, so panic.
+ *
+ * Input Parameters:
+ * cause - The (masked) machine cause of the exception, used for the
+ * panic message only.
+ * regs - A pointer to the register state at the time of the exception.
*
****************************************************************************/
-int riscv_exception(int mcause, void *regs, void *args)
+static void riscv_fault_handler(uintreg_t cause, void *regs)
{
#ifdef CONFIG_ARCH_KERNEL_STACK
struct tcb_s *tcb = this_task();
-#endif
- uintreg_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));
-#ifdef CONFIG_ARCH_KERNEL_STACK
if (((tcb->flags & TCB_FLAG_TTYPE_MASK) != TCB_FLAG_TTYPE_KERNEL) &&
((tcb->flags & TCB_FLAG_SYSCALL) == false))
{
@@ -124,15 +125,34 @@ int riscv_exception(int mcause, void *regs, void *args)
*/
running_regs()[REG_SP] = tcb->xcp.ktopstk;
+ return;
}
- else
#endif
- {
- _alert("PANIC!!! Exception = %" PRIxREG "\n", cause);
- up_irq_save();
- up_set_interrupt_context(true);
- PANIC_WITH_REGS("panic", regs);
- }
+
+ _alert("PANIC!!! Exception = %" PRIxREG "\n", cause);
+ up_irq_save();
+ up_set_interrupt_context(true);
+ PANIC_WITH_REGS("panic", regs);
+}
+
+/****************************************************************************
+ * Name: riscv_exception
+ *
+ * Description:
+ * This is the exception handler.
+ *
+ ****************************************************************************/
+
+int riscv_exception(int mcause, void *regs, void *args)
+{
+ uintreg_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));
+
+ riscv_fault_handler(cause, regs);
return 0;
}
@@ -200,7 +220,7 @@ int riscv_fillpage(int mcause, void *regs, void *args)
}
else
{
- _alert("PANIC!!! virtual address not mappable: %" PRIxPTR "\n", vaddr);
+ _alert("Virtual address not mappable: %" PRIxPTR "\n", vaddr);
goto access_fault;
}
@@ -242,7 +262,7 @@ int riscv_fillpage(int mcause, void *regs, void *args)
if (mmu_ln_getentry(ARCH_PGT_MAX_LEVELS, ptlast, vaddr) & PTE_VALID)
{
- _alert("PANIC!!! page already mapped, permission violation: %"
+ _alert("Page already mapped, permission violation: %"
PRIxPTR "\n", vaddr);
goto access_fault;
}
@@ -264,10 +284,8 @@ int riscv_fillpage(int mcause, void *regs, void *args)
return 0;
access_fault:
- up_irq_save();
- up_set_interrupt_context(true);
- PANIC_WITH_REGS("panic", regs);
- return -EINVAL;
+ riscv_fault_handler(cause, regs);
+ return 0;
}
#endif /* CONFIG_PAGING */