Skip to content

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

Merged
fdesbiens merged 1 commit into
eclipse-threadx:devfrom
fdesbiens:fix/issue-348
Sep 3, 2026
Merged

Fixed the clobbered return address in the RISC-V context save#696
fdesbiens merged 1 commit into
eclipse-threadx:devfrom
fdesbiens:fix/issue-348

Conversation

@fdesbiens

Copy link
Copy Markdown
Contributor

_tx_thread_context_save() returns to its caller with ret, which uses the return address held in ra.
When TX_ENABLE_EXECUTION_CHANGE_NOTIFY is defined, the call _tx_execution_isr_enter overwrites ra with the address of the instruction following the call, so the subsequent ret returns into _tx_thread_context_save itself instead of the interrupt service routine.
This PR saves the return address on the stack around the call and recovers it afterwards. That is the same idiom the Arm ports already use, for example ports_arch/ARMv7-A/threadx/common/src/tx_thread_vectored_context_save.S, which pushes and pops lr around the same call.
All three affected paths are covered in each port: the nested save, the thread save and the idle system save.
Files changed: ports/risc-v32/gnu/src/tx_thread_context_save.S, ports/risc-v32/iar/src/tx_thread_context_save.s and ports/risc-v64/gnu/src/tx_thread_context_save.S.
I checked the remaining RISC-V assembly. tx_thread_context_restore reloads ra from the saved context and returns with mret, while tx_thread_schedule and tx_thread_system_return do not return to their caller, so none of them are affected.
The changed files assemble cleanly with and without TX_ENABLE_EXECUTION_CHANGE_NOTIFY, for rv32imac_zicsr, rv32imafc_zicsr and rv64imac_zicsr.
Note that #691 is currently open against ports/risc-v32/gnu/src/tx_thread_context_save.S and carries the same defect, so one of the two branches will need a small rebase.

Fixes #348

_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 eclipse-threadx#348

Assisted-by: Copilot (Opus 5) <noreply@github.com>
@fdesbiens
fdesbiens merged commit d7789f0 into eclipse-threadx:dev Sep 3, 2026
12 checks passed
@fdesbiens
fdesbiens deleted the fix/issue-348 branch September 3, 2026 18:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant