Exception: Fix PSPSEL for ARMv8-M exception
EXC_RETURN.PSPSEL should be used only if EXC_RETURN.S is equal to
EXC_RETURN.ES (captured by ExceptionTaken). Otherwise CONTROL of
interrupted state should be used to evaluate SPSEL.
This patch use CONTROL_NS.SPSEL to evaluate PSP to capture exception
info generated by non-secure code.
Signed-off-by: Roman Mazurak <roman.mazurak@infineon.com>
Change-Id: I3b71557e44539d92f19541ffb8342c763a847892
diff --git a/platform/ext/common/exception_info.c b/platform/ext/common/exception_info.c
index c9cdc3b..03264ba 100644
--- a/platform/ext/common/exception_info.c
+++ b/platform/ext/common/exception_info.c
@@ -45,8 +45,14 @@
return ((lr == EXC_RETURN_THREAD_PSP) || (lr == EXC_RETURN_THREAD_PSP_FPU));
#elif defined(__ARM_ARCH_8M_BASE__) || defined(__ARM_ARCH_8M_MAIN__) \
|| defined(__ARM_ARCH_8_1M_MAIN__)
- /* PSP is used only if SPSEL is set, and we came from thread mode. */
- return ((lr & EXC_RETURN_SPSEL) && is_return_thread_mode(lr));
+ if (is_return_secure_stack(lr)) {
+ /* PSP is used only if SPSEL is set, and we came from thread mode. */
+ return ((lr & EXC_RETURN_SPSEL) && is_return_thread_mode(lr));
+ } else {
+ /* PSP is used only if CONTROL_NS.SPSEL is set, and we came from thread mode. */
+ bool sp_sel = _FLD2VAL(CONTROL_SPSEL, __TZ_get_CONTROL_NS()) != 0;
+ return (sp_sel && is_return_thread_mode(lr));
+ }
#else
return (lr == EXC_RETURN_THREAD_PSP);
#endif