From 34d37ac5e83332ee68684c44c783c402d544c8cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Desbiens?= Date: Thu, 3 Sep 2026 14:03:31 -0400 Subject: [PATCH] Fixed the clobbered return address in the RISC-V context save _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) --- ports/risc-v32/gnu/src/tx_thread_context_save.S | 14 ++++++++++++++ ports/risc-v32/iar/src/tx_thread_context_save.s | 13 +++++++++++++ ports/risc-v64/gnu/src/tx_thread_context_save.S | 13 +++++++++++++ 3 files changed, 40 insertions(+) diff --git a/ports/risc-v32/gnu/src/tx_thread_context_save.S b/ports/risc-v32/gnu/src/tx_thread_context_save.S index 0a0c0c156..d61cea86e 100644 --- a/ports/risc-v32/gnu/src/tx_thread_context_save.S +++ b/ports/risc-v32/gnu/src/tx_thread_context_save.S @@ -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. */ diff --git a/ports/risc-v32/iar/src/tx_thread_context_save.s b/ports/risc-v32/iar/src/tx_thread_context_save.s index 00b971efb..76672cde2 100644 --- a/ports/risc-v32/iar/src/tx_thread_context_save.s +++ b/ports/risc-v32/iar/src/tx_thread_context_save.s @@ -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. */ diff --git a/ports/risc-v64/gnu/src/tx_thread_context_save.S b/ports/risc-v64/gnu/src/tx_thread_context_save.S index 7935bfee2..8cbfa32cd 100644 --- a/ports/risc-v64/gnu/src/tx_thread_context_save.S +++ b/ports/risc-v64/gnu/src/tx_thread_context_save.S @@ -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. */