We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
In current trusted-firmware-m version, secure functions such as secure storage service functions can only be called from handler mode.
But I have a question about the call sequence, when none secure side call sst_get_handle sevice function, it will first call svc instruction to enter handler mode, and in the svc handler, there will be the call sequence as follows:
svc hanlder() -> sst_veneer_get_handle->TFM_CORE_SFN_REQUEST(tfm_core_partition_request) __attribute__ ((always_inline)) __STATIC_INLINE int32_t tfm_core_partition_request(uint32_t id, void *fn, int32_t arg1, int32_t arg2, int32_t arg3, int32_t arg4) { int32_t args[4] = {arg1, arg2, arg3, arg4}; struct tfm_sfn_req_s desc, *desc_ptr = &desc; desc.sp_id = id; desc.sfn = fn; desc.args = args; desc.ns_caller = cmse_nonsecure_caller(); desc.exc_num = __get_active_exc_num(); // what is the exc_num here? I guess it will not be EXC_NUM_THREAD_MODE, right? ... return tfm_core_sfn_request_function(desc_ptr); } ->tfm_core_sfn_request_function ->tfm_core_call_sfn(desc_ptr){ #if TFM_LVL == 1 if ((desc_ptr->exc_num == EXC_NUM_THREAD_MODE) && (!tfm_secure_api_init)) { /* Secure partition to secure partition call in TFM level 1 */ int32_t res; int32_t *args = desc_ptr->args; int32_t retVal = desc_ptr->sfn(args[0], args[1], args[2], args[3]); /* return handler should restore original exc_return value... */ res = tfm_pop_lock(NULL); if (res == TFM_SUCCESS) { /* If unlock successful, pass SS return value to caller */ res = retVal; } else { /* Unlock errors indicate ctx database corruption or unknown * anomalies. Halt execution */ ERROR_MSG("Secure API error during unlock!"); tfm_secure_api_error_handler(); } return res; } #endif /* Exception return to partition start */ return tfm_core_exc_return_to_sfn(); }
My question is whether desc_ptr->sfn(args[0], args[1], args[2], args[3]); can be executed or not in the last tfm_core_call_sfn call if TFM_LVL =1. I think desc_ptr->exc_num is not EXC_NUM_THREAD_MODE because the call sequence is from none-secure side svc handler, please let me know if I am wrong, thanks.
matt-ma said:desc.exc_num = __get_active_exc_num(); // what is the exc_num here? I guess it will not be EXC_NUM_THREAD_MODE, right?
That is correct. exc_num, i.e. exception number will be the ISR value at the point of call. ISR is not mapped between security states, so the non-secure SVC handler call to this veneer will result in an exc_num value of 11 (EXC_NUM_SVCALL).
In tfm_core_call_sfn(desc_ptr), since desc_ptr->exc_num != EXC_NUM_THREAD_MODE, the entire
if ((desc_ptr->exc_num == EXC_NUM_THREAD_MODE) && (!tfm_secure_api_init)) {
block is skipped (note that there's no corresponding else statement). This results in the code below being executed:
/* Exception return to partition start */ return tfm_core_exc_return_to_sfn();
That will perform a secure exception return to the context prepared for secure function execution, so desc_ptr->sfn(…) will be executed.
Regards
Miklos