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 */
 

Reply via email to