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

acassis 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 04e750eacd8 arch/arm: keep g_running_tasks valid on ARMv6-M
04e750eacd8 is described below

commit 04e750eacd8ba99db5a48eb9e21ac509523f77b0
Author: raiden00pl <[email protected]>
AuthorDate: Wed Oct 21 12:42:29 2026 +0200

    arch/arm: keep g_running_tasks valid on ARMv6-M
    
    d20189bdfa2 made up_exit() and the ARMv6-M arm_sigdeliver() set
    g_running_tasks to NULL before SYS_restore_context, so that the ARMv6-M
    arm_doirq() skips saving the registers into it. That NULL is passed to
    nxsched_switch_context(), which dereferences it; with tickless
    round-robin this locked up the STM32F0.
    
    d20189bdfa2 replaced the check of the SVCall number and R0, because on
    ARMv6-M the SVC arrives as HardFault when issued with PRIMASK set
    (ARMv6-M ARM, DDI 0419E, B1.5.4). Restore that check, accepting SVCall
    and HardFault, and remove the NULL from up_exit() and arm_sigdeliver().
    
    Signed-off-by: raiden00pl <[email protected]>
    Assisted-by: Claude Code
---
 arch/arm/src/armv6-m/arm_doirq.c      | 6 ++++--
 arch/arm/src/armv6-m/arm_sigdeliver.c | 1 -
 arch/arm/src/common/arm_exit.c        | 9 ---------
 3 files changed, 4 insertions(+), 12 deletions(-)

diff --git a/arch/arm/src/armv6-m/arm_doirq.c b/arch/arm/src/armv6-m/arm_doirq.c
index b1a7e39e880..a94d8a20b78 100644
--- a/arch/arm/src/armv6-m/arm_doirq.c
+++ b/arch/arm/src/armv6-m/arm_doirq.c
@@ -62,10 +62,12 @@ uint32_t *arm_doirq(int irq, uint32_t *regs)
   struct tcb_s *tcb           = *running_task;
 
   /* This judgment proves that (*running_task)->xcp.regs
-   * is invalid, and we can safely overwrite it.
+   * is invalid, and we can safely overwrite it.  SYS_restore_context
+   * issued with PRIMASK set arrives as an escalated HardFault.
    */
 
-  if (*running_task != NULL)
+  if (!((irq == NVIC_IRQ_SVCALL || irq == NVIC_IRQ_HARDFAULT) &&
+        regs[REG_R0] == SYS_restore_context))
     {
       tcb->xcp.regs = regs;
     }
diff --git a/arch/arm/src/armv6-m/arm_sigdeliver.c 
b/arch/arm/src/armv6-m/arm_sigdeliver.c
index ce43e27fff7..4d25226a637 100644
--- a/arch/arm/src/armv6-m/arm_sigdeliver.c
+++ b/arch/arm/src/armv6-m/arm_sigdeliver.c
@@ -163,7 +163,6 @@ retry:
   leave_critical_section(up_irq_save());
 #endif
 
-  g_running_tasks[this_cpu()] = NULL;
   rtcb->xcp.regs = rtcb->xcp.saved_regs;
   rtcb->xcp.saved_regs = NULL;
   arm_fullcontextrestore();
diff --git a/arch/arm/src/common/arm_exit.c b/arch/arm/src/common/arm_exit.c
index c6538f52954..0bad7838891 100644
--- a/arch/arm/src/common/arm_exit.c
+++ b/arch/arm/src/common/arm_exit.c
@@ -62,16 +62,7 @@ void up_exit(int status)
 
   /* Update g_running_tasks */
 
-#ifdef CONFIG_ARCH_ARMV6M
-  /* ARMV6M syscal may trigger hard fault, We use
-   * running_task != NULL to determine whether it is
-   * a context for restoration.
-   */
-
-  g_running_tasks[this_cpu()] = NULL;
-#else
   g_running_tasks[this_cpu()] = this_task();
-#endif
 
   /* Then switch contexts */
 

Reply via email to