nuttx/arch
xuxingliang cdd8032cb9 arch/armv8-m: Fix IRQ number corruption in exception_direct with O2 optimization
When compiling with O2 optimization, the compiler optimizes the code
in a way that causes irq variable to be corrupted. The getipsr()
function reads IPSR into r0, but the subsequent inline assembly that
sets FPSCR also uses r0 without declaring it as clobbered. This causes
the compiler to reuse r0 for the immediate value (0x40000), overwriting
the IRQ number read from IPSR.

The issue manifests as:
- getipsr() correctly reads IPSR (e.g., 0xf for IRQ 15)
- Compiler optimizes and reuses r0 for ARM_FPSCR_LTPSIZE_NONE (0x40000)
- irq variable gets the wrong value 0x40000 instead of actual IRQ number
- This leads to assertion failures in irq_dispatch due to invalid IRQ

Root cause analysis from disassembly:
  mrs r0, IPSR          ; Read IPSR to r0
  mov.w r0, #262144     ; Compiler overwrites r0 with 0x40000!
  vmsr fpscr, r0        ; Set FPSCR
  str r0, [sp, #4]      ; Store corrupted 0x40000 as irq
  ...
  ldr r0, [sp, #4]      ; Load corrupted value
  bl irq_dispatch       ; Call with wrong IRQ number 0x40000

Fix by adding r0 to the clobber list in the inline assembly, which
forces the compiler to save irq value before using r0 for FPSCR setup.

This issue only occurs at O2 optimization level and affects ARMv8-M
architecture with FPU enabled.

Signed-off-by: xuxingliang <xuxingliang@xiaomi.com>
2025-12-29 19:15:21 +08:00
..
arm arch/armv8-m: Fix IRQ number corruption in exception_direct with O2 optimization 2025-12-29 19:15:21 +08:00
arm64 barrier: add UP_RMB UP_WMB 2025-12-22 10:22:06 -03:00
avr sched/sched: Remove nxsched_alarm_expiration 2025-12-22 21:17:13 +08:00
ceva barrier: add UP_RMB UP_WMB 2025-12-22 10:22:06 -03:00
dummy
hc arch/udelay: Make common, weak definition of up_*delay functions 2025-09-29 09:22:56 +08:00
mips sched:use tcb_s inside of task_tcb_s , remove all cast 2025-12-22 17:55:45 +08:00
misoc arch/Toolchain.defs: use _start entry 2025-12-16 13:07:37 -03:00
or1k arch/Toolchain.defs: use _start entry 2025-12-16 13:07:37 -03:00
renesas renesas/rx65n: Replace spinlock/sched_lock with spin_lock_irqsave_nopreempt 2025-11-04 22:46:15 +08:00
risc-v risc-v/litex: Implement up_flush_dcache_all when CONFIG_ARCH_DCACHE is defined. 2025-12-27 07:00:29 -03:00
sim sim_netdriver: add addmac/rmmac support 2025-12-25 10:01:43 +08:00
sparc arch/Toolchain.defs: use _start entry 2025-12-16 13:07:37 -03:00
tricore barrier: add UP_RMB UP_WMB 2025-12-22 10:22:06 -03:00
x86 arch/Toolchain.defs: use _start entry 2025-12-16 13:07:37 -03:00
x86_64 barrier: add UP_RMB UP_WMB 2025-12-22 10:22:06 -03:00
xtensa sched:use tcb_s inside of task_tcb_s , remove all cast 2025-12-22 17:55:45 +08:00
z16 arch/udelay: Make common, weak definition of up_*delay functions 2025-09-29 09:22:56 +08:00
z80 arch/Toolchain.defs: use _start entry 2025-12-16 13:07:37 -03:00
CMakeLists.txt arch/z80: migrate to SPDX identifier 2024-12-02 17:23:25 +08:00
Kconfig arch:use ARCH_64BIT to mark arch is support 64bit 2025-12-18 22:05:12 +08:00