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