This is an automated email from the ASF dual-hosted git repository.

jerpelea 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 a04d67e7dc8 arch/risc-v: fix fault handler misattributing kernel 
faults to user tasks
a04d67e7dc8 is described below

commit a04d67e7dc840e3445d43e7f976b7cde3397524d
Author: liang.huang <[email protected]>
AuthorDate: Sat Jul 18 11:33:30 2026 +0800

    arch/risc-v: fix fault handler misattributing kernel faults to user tasks
    
    riscv_fault_handler() only checked the task type and SYSCALL flag, so a
    fault taken inside an interrupt handler (running in kernel mode) was
    blamed on the user task that happened to be interrupted and killed with
    SIGSEGV, hiding the real kernel bug.  Use the STATUS_PPP bit of the trap
    frame to tell whether the fault originated from user mode: only then is
    it safe to kill the task.
    
    Signed-off-by: liang.huang <[email protected]>
---
 arch/risc-v/src/common/riscv_exception.c | 17 ++++++++++++-----
 1 file changed, 12 insertions(+), 5 deletions(-)

diff --git a/arch/risc-v/src/common/riscv_exception.c 
b/arch/risc-v/src/common/riscv_exception.c
index 8196444c983..6f5c81b2fd8 100644
--- a/arch/risc-v/src/common/riscv_exception.c
+++ b/arch/risc-v/src/common/riscv_exception.c
@@ -87,10 +87,11 @@ static const char *g_reasons_str[RISCV_MAX_EXCEPTION + 1] =
  *
  * Description:
  *   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.
+ *   not currently in a syscall or interrupt context, kill it with SIGSEGV
+ *   instead of taking down the whole system. Otherwise (kernel thread, a
+ *   fault while already in kernel context on behalf of a syscall, or a
+ *   fault while handling an interrupt) there is no safe task to kill, so
+ *   panic.
  *
  * Input Parameters:
  *   cause - The (masked) machine cause of the exception, used for the
@@ -104,8 +105,14 @@ static void riscv_fault_handler(uintreg_t cause, void 
*regs)
 #ifdef CONFIG_ARCH_KERNEL_STACK
   struct tcb_s *tcb = this_task();
 
+  /* The STATUS_PPP check alone is enough: any kernel-mode fault (kernel
+   * thread, syscall body, or interrupt) has STATUS_PPP != 0.  The other
+   * two checks are kept as defensive redundancy.
+   */
+
   if (((tcb->flags & TCB_FLAG_TTYPE_MASK) != TCB_FLAG_TTYPE_KERNEL) &&
-      ((tcb->flags & TCB_FLAG_SYSCALL) == false))
+      ((tcb->flags & TCB_FLAG_SYSCALL) == false) &&
+      !(((uintreg_t *)regs)[REG_INT_CTX] & STATUS_PPP))
     {
       struct tcb_s *ptcb = nxsched_get_tcb(tcb->group->tg_pid);
 

Reply via email to