arch: arm: cortex_a_r: Fix restore of registers while exiting exception

This commit fixes potential unpredictable behavior, caused by using
the ^ form of ldmia instruction, while exiting an exception in SMP
mode on Cortex-A/R.

Change:
Use "pop" instead of "ldmia" to restore user mode registers while
exiting from an exception via `z_arm_cortex_ar_exit_exc`.

Reason for change:
Processor mode is always set to system (MODE_SYS) before calling
`z_arm_cortex_ar_exit_exc` and hence, the user mode register can be
accessed directly without the ^ form of the instruction. Also, LDMIA
instruction is UNPREDICTABLE in SYStem mode.

Signed-off-by: Sudan Landge <sudan.landge@arm.com>
This commit is contained in:
Sudan Landge 2024-07-12 17:26:32 +01:00 committed by Anas Nashif
parent 6d8deac010
commit b3fe647eaf
2 changed files with 15 additions and 2 deletions

View File

@ -339,6 +339,15 @@ z_arm_cortex_ar_irq_done:
str r0, [r2, #___cpu_t_nested_OFFSET]
/* Do not context switch if exiting a nested interrupt */
cmp r0, #0
/* Note that this function is only called from `z_arm_svc`,
* while handling irq_offload, with below modes set:
* ```
* if (cpu interrupts are nested)
* mode=MODE_SYS
* else
* mode=MODE_IRQ
* ```
*/
bhi __EXIT_INT
/* retrieve pointer to the current thread */

View File

@ -41,6 +41,11 @@ SECTION_SUBSEC_FUNC(exc_vector_table,_vector_table_section,_vector_table)
GTEXT(z_arm_cortex_ar_exit_exc)
SECTION_SUBSEC_FUNC(TEXT, _HandlerModeExit, z_arm_cortex_ar_exit_exc)
/* Note:
* This function is expected to be *always* called with
* processor mode set to MODE_SYS.
*/
/* decrement exception depth */
get_cpu r2
ldrb r1, [r2, #_cpu_offset_to_exc_depth]
@ -51,7 +56,6 @@ SECTION_SUBSEC_FUNC(TEXT, _HandlerModeExit, z_arm_cortex_ar_exit_exc)
* Restore r0-r3, r12, lr, lr_und and spsr_und from the exception stack
* and return to the current thread.
*/
ldmia sp, {r0-r3, r12, lr}^
add sp, #24
pop {r0-r3, r12, lr}
rfeia sp!
#endif