Fixed the clobbered return address in the RISC-V context save (#696)

_tx_thread_context_save() returns to its caller with ret, which uses the
return address held in ra. When TX_ENABLE_EXECUTION_CHANGE_NOTIFY was
defined, the call to _tx_execution_isr_enter overwrote ra with the address
of the instruction following the call, so the subsequent ret returned into
_tx_thread_context_save itself instead of the interrupt service routine.

The return address is now saved on the stack around the call and recovered
afterwards, which is the same idiom already used by the Arm ports. The fix
covers all three affected paths (nested save, thread save and idle system
save) in the risc-v32 GNU, risc-v32 IAR and risc-v64 GNU ports.

Fixes #348

Assisted-by: Copilot (Opus 5) <noreply@github.com>
This commit is contained in:
Frédéric Desbiens
2026-09-03 14:17:49 -04:00
committed by GitHub
parent 508af549da
commit d7789f0b12
3 changed files with 40 additions and 0 deletions
@@ -1,5 +1,6 @@
/***************************************************************************
* Copyright (c) 2025 10xEngineers
* Copyright (c) 2026 Eclipse ThreadX contributors
*
* This program and the accompanying materials are made available under the
* terms of the MIT License which is available at
@@ -8,6 +9,7 @@
* SPDX-License-Identifier: MIT
**************************************************************************/
// Some portions generated by Copilot (Opus 5).
/**************************************************************************/
/**************************************************************************/
@@ -173,7 +175,11 @@ _tx_thread_skip_fpu_save:
/* Call the ISR execution exit function if enabled. */
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
addi sp, sp, -16 // Reserve space to save the return address
sw ra, 0(sp) // Save the return address
call _tx_execution_isr_enter // Call the ISR execution enter function
lw ra, 0(sp) // Recover the return address
addi sp, sp, 16 // Recover the reserved stack space
#endif
ret // Return to ISR
@@ -261,7 +267,11 @@ _tx_thread_skip_nested_fpu_save:
/* Call the ISR execution exit function if enabled. */
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
addi sp, sp, -16 // Reserve space to save the return address
sw ra, 0(sp) // Save the return address
call _tx_execution_isr_enter // Call the ISR execution enter function
lw ra, 0(sp) // Recover the return address
addi sp, sp, 16 // Recover the reserved stack space
#endif
ret // Return to ISR
@@ -270,7 +280,11 @@ _tx_thread_idle_system_save:
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
addi sp, sp, -16 // Reserve space to save the return address
sw ra, 0(sp) // Save the return address
call _tx_execution_isr_enter // Call the ISR execution enter function
lw ra, 0(sp) // Recover the return address
addi sp, sp, 16 // Recover the reserved stack space
#endif
/* Interrupt occurred in the scheduling loop. */
@@ -9,6 +9,7 @@
* SPDX-License-Identifier: MIT
**************************************************************************/
; Some portions generated by Copilot (Opus 5).
/**************************************************************************/
/**************************************************************************/
@@ -145,7 +146,11 @@ _tx_thread_context_save:
#endif
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
addi sp, sp, -16 ; Reserve space to save the return address
sw ra, 0(sp) ; Save the return address
call _tx_execution_isr_enter ; Call the ISR execution enter function
lw ra, 0(sp) ; Recover the return address
addi sp, sp, 16 ; Recover the reserved stack space
#endif
ret ; Return to calling ISR
@@ -223,7 +228,11 @@ _tx_thread_not_nested_save:
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
/* _tx_execution_isr_enter is called with thread stack pointer */
addi sp, sp, -16 ; Reserve space to save the return address
sw ra, 0(sp) ; Save the return address
call _tx_execution_isr_enter ; Call the ISR execution enter function
lw ra, 0(sp) ; Recover the return address
addi sp, sp, 16 ; Recover the reserved stack space
#endif
@@ -238,7 +247,11 @@ _tx_thread_idle_system_save:
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
addi sp, sp, -16 ; Reserve space to save the return address
sw ra, 0(sp) ; Save the return address
call _tx_execution_isr_enter ; Call the ISR execution enter function
lw ra, 0(sp) ; Recover the return address
addi sp, sp, 16 ; Recover the reserved stack space
#endif
/* Interrupt occurred in the scheduling loop. */
@@ -9,6 +9,7 @@
* SPDX-License-Identifier: MIT
**************************************************************************/
// Some portions generated by Copilot (Opus 5).
/**************************************************************************/
/**************************************************************************/
@@ -181,7 +182,11 @@ _tx_thread_context_save:
#endif
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
addi sp, sp, -16 // Reserve space to save the return address
sd ra, 0(sp) // Save the return address
call _tx_execution_isr_enter // Call the ISR execution enter function
ld ra, 0(sp) // Recover the return address
addi sp, sp, 16 // Recover the reserved stack space
#endif
ret // Return to calling ISR
@@ -316,7 +321,11 @@ _tx_thread_not_nested_save:
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
/* _tx_execution_isr_enter is called with thread stack pointer */
addi sp, sp, -16 // Reserve space to save the return address
sd ra, 0(sp) // Save the return address
call _tx_execution_isr_enter // Call the ISR execution enter function
ld ra, 0(sp) // Recover the return address
addi sp, sp, 16 // Recover the reserved stack space
#endif
la t0, _tx_thread_system_stack_ptr // Pickup system stack pointer address
@@ -331,7 +340,11 @@ _tx_thread_idle_system_save:
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
addi sp, sp, -16 // Reserve space to save the return address
sd ra, 0(sp) // Save the return address
call _tx_execution_isr_enter // Call the ISR execution enter function
ld ra, 0(sp) // Recover the return address
addi sp, sp, 16 // Recover the reserved stack space
#endif
/* Interrupt occurred in the scheduling loop. */