Core: Improve secure function entry point in Library model
In current Library model implementation, each secure function
includes the same inline entry point tfm_core_partition_request().
However, it is only required to make NS client check as inline.
The remaining steps in tfm_core_partition_request() increase the
memory footprint when they are also inlined in secure functions.
Extract checking NS client from tfm_core_partition_request() and
add an inline function tfm_core_is_ns_client().
Change tfm_core_partition_request() to a normal function called
by each secure function.
It can save several KB in code size in Library model.
Change-Id: I2b8d58d8daff22068cddbfa1145203ca92f305a4
Signed-off-by: David Hu <david.hu@arm.com>
diff --git a/secure_fw/core/include/tfm_secure_api.h b/secure_fw/core/include/tfm_secure_api.h
index b85bdd8..250dc0a 100644
--- a/secure_fw/core/include/tfm_secure_api.h
+++ b/secure_fw/core/include/tfm_secure_api.h
@@ -127,20 +127,16 @@
return (int32_t)TFM_ERROR_GENERIC; \
} while (0)
#else
-#define TFM_CORE_IOVEC_SFN_REQUEST(id, fn, a, b, c, d) \
- return tfm_core_partition_request(id, fn, \
+#define TFM_CORE_IOVEC_SFN_REQUEST(id, is_ns, fn, a, b, c, d) \
+ return tfm_core_partition_request(id, is_ns, fn, \
(int32_t)a, (int32_t)b, (int32_t)c, (int32_t)d)
-__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;
+int32_t tfm_core_partition_request(uint32_t id, bool is_ns, void *fn,
+ int32_t arg1, int32_t arg2, int32_t arg3, int32_t arg4);
- desc.sp_id = id;
- desc.sfn = (sfn_t) fn;
- desc.args = args;
+__attribute__ ((always_inline)) __STATIC_INLINE
+bool tfm_core_is_ns_client(void)
+{
/*
* This preprocessor condition checks if a version of GCC smaller than
* 7.3.1 is being used to compile the code.
@@ -156,30 +152,16 @@
* Use the fact that, if called from Non-Secure, the LSB of the return
* address is set to 0.
*/
- desc.ns_caller = !(
- (intptr_t)__builtin_extract_return_addr(__builtin_return_address(0U))
- & 1);
+ return !(
+ (uintptr_t)__builtin_extract_return_addr(__builtin_return_address(0U))
+ & 0x1);
#else
/*
* Convert the result of cmse_nonsecure_caller from an int to a bool
* to prevent using an int in the tfm_sfn_req_s structure.
*/
- desc.ns_caller = (cmse_nonsecure_caller() != 0) ? true : false;
+ return (cmse_nonsecure_caller() != 0) ? true : false;
#endif /* Check for GCC compiler version smaller than 7.3.1 */
- if (__get_active_exc_num() != EXC_NUM_THREAD_MODE) {
- /* The veneer of a secure service had been called from Handler mode.
- * This violates TF-M's programming model, and is considered an
- * unrecoverable error.
- */
- tfm_core_panic();
- } else {
- if (desc.ns_caller) {
- return tfm_core_sfn_request(desc_ptr);
- } else {
- return tfm_spm_sfn_request_thread_mode(desc_ptr);
- }
- }
- return TFM_ERROR_GENERIC;
}
#endif
diff --git a/secure_fw/core/tfm_secure_api.c b/secure_fw/core/tfm_secure_api.c
index 53b3499..2c49717 100644
--- a/secure_fw/core/tfm_secure_api.c
+++ b/secure_fw/core/tfm_secure_api.c
@@ -57,3 +57,32 @@
ERROR_MSG("Security violation when calling secure API");
tfm_core_panic();
}
+
+#ifndef TFM_PSA_API
+int32_t tfm_core_partition_request(uint32_t id, bool is_ns, 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 = (sfn_t) fn;
+ desc.args = args;
+ desc.ns_caller = is_ns;
+
+ if (__get_active_exc_num() != EXC_NUM_THREAD_MODE) {
+ /* The veneer of a secure service had been called from Handler mode.
+ * This violates TF-M's programming model, and is considered an
+ * unrecoverable error.
+ */
+ tfm_core_panic();
+ } else {
+ if (desc.ns_caller) {
+ return tfm_core_sfn_request(desc_ptr);
+ } else {
+ return tfm_spm_sfn_request_thread_mode(desc_ptr);
+ }
+ }
+ return TFM_ERROR_GENERIC;
+}
+#endif
diff --git a/secure_fw/ns_callable/tfm_veneers.c b/secure_fw/ns_callable/tfm_veneers.c
index 02b0ca4..0ec4da5 100644
--- a/secure_fw/ns_callable/tfm_veneers.c
+++ b/secure_fw/ns_callable/tfm_veneers.c
@@ -175,7 +175,10 @@
psa_outvec *out_vec, \
size_t out_len) \
{ \
+ bool is_ns = tfm_core_is_ns_client(); \
+ \
TFM_CORE_IOVEC_SFN_REQUEST(partition_name, \
+ is_ns, \
(void *) sfn_name, \
in_vec, in_len, out_vec, out_len); \
}
diff --git a/secure_fw/ns_callable/tfm_veneers.c.template b/secure_fw/ns_callable/tfm_veneers.c.template
index a5035aa..258f5bd 100644
--- a/secure_fw/ns_callable/tfm_veneers.c.template
+++ b/secure_fw/ns_callable/tfm_veneers.c.template
@@ -31,7 +31,10 @@
psa_outvec *out_vec, \
size_t out_len) \
{ \
+ bool is_ns = tfm_core_is_ns_client(); \
+ \
TFM_CORE_IOVEC_SFN_REQUEST(partition_name, \
+ is_ns, \
(void *) sfn_name, \
in_vec, in_len, out_vec, out_len); \
}