ARM Cortex-M55 TrustZone Secure-to-Non-Secure Transition Overhead

The ARM Cortex-M55 processor, with its TrustZone security extension, provides a robust mechanism for isolating secure and non-secure worlds. A common use case involves calling secure services from the non-secure world, which is facilitated by the cmse_ns_entry function and the BXNS instruction. However, when the same secure service is called from the secure world, the overhead of the secure-to-non-secure transition mechanisms becomes redundant and impacts performance. This issue arises because the cmse_ns_entry function and its associated assembly instructions are designed to handle the transition between secure and non-secure states, which is unnecessary when the caller is already in the secure state.

The core of the problem lies in the fact that the BXNS instruction, along with its associated context-saving and restoration instructions (such as STCL, VLDM, and LDCL), are executed even when the caller is in the secure state. These instructions are essential for ensuring a safe transition between security states but are redundant when the caller and callee are both in the secure state. This redundancy introduces unnecessary performance overhead, particularly when the secure service is called frequently from the secure world.

Redundant Execution of BXNS and Context-Saving Instructions

The BXNS instruction is designed to conditionally transition from the secure to the non-secure state based on the value of the least significant bit (LSB) of the target address register (Rm). When the LSB of Rm is 0, the processor transitions to the non-secure state. When the LSB is 1, the processor remains in the secure state. In the case of a secure function call from the secure world, the LSB of the return address (LR) is set to 1, indicating that the processor should remain in the secure state. However, the BXNS instruction and its associated context-saving instructions are still executed, even though the security state does not change.

The STCL, VLDM, and LDCL instructions are part of the context-saving and restoration process that ensures the secure state is preserved during a transition to the non-secure state. These instructions save and restore the secure context, including registers and stack pointers, to prevent leakage of secure information to the non-secure world. While these instructions are critical for maintaining security during a state transition, they are unnecessary when the caller and callee are both in the secure state. Executing these instructions in such scenarios introduces unnecessary overhead, which can degrade performance, especially in time-sensitive applications.

Implementing Conditional Execution of Secure-to-Non-Secure Transition Code

To address the performance overhead caused by the redundant execution of BXNS and context-saving instructions, a conditional execution mechanism can be implemented. This mechanism ensures that the secure-to-non-secure transition code is only executed when the caller is in the non-secure state. When the caller is in the secure state, the transition code is bypassed, and the secure function is called directly.

One approach to implementing this mechanism is to use a runtime check to determine the security state of the caller. The TT (Test Target) instruction can be used to check the security state of the return address (LR). If the return address is in the secure state, the transition code is bypassed, and the secure function is called directly. If the return address is in the non-secure state, the transition code is executed to ensure a safe transition to the non-secure state.

The following table summarizes the key steps involved in implementing this conditional execution mechanism:

Step Description
1 Use the TT instruction to check the security state of the return address (LR).
2 If the return address is in the secure state, branch directly to the secure function.
3 If the return address is in the non-secure state, execute the STCL, VLDM, and LDCL instructions to save and restore the secure context.
4 Execute the BXNS instruction to transition to the non-secure state.

By implementing this conditional execution mechanism, the performance overhead associated with redundant secure-to-non-secure transition code can be significantly reduced. This approach ensures that the transition code is only executed when necessary, preserving the security of the system while optimizing performance.

In addition to the runtime check, the use of compiler attributes can further optimize the execution of secure functions. The cmse_ns_entry attribute can be used to indicate that a function is intended to be called from the non-secure world. When this attribute is applied, the compiler generates the necessary transition code for calls from the non-secure world. However, when the function is called from the secure world, the compiler can generate a direct call to the secure function, bypassing the transition code.

The following example demonstrates the use of the cmse_ns_entry attribute to optimize secure function calls:

// Secure function intended to be called from the non-secure world
__attribute__((cmse_ns_entry)) void secure_service(void) {
    // Secure service implementation
}

// Secure function called from the secure world
void secure_service_direct(void) {
    // Direct call to the secure service implementation
    secure_service();
}

In this example, the secure_service function is marked with the cmse_ns_entry attribute, indicating that it is intended to be called from the non-secure world. When secure_service is called from the non-secure world, the compiler generates the necessary transition code. However, when secure_service_direct is called from the secure world, the compiler generates a direct call to secure_service, bypassing the transition code.

By combining runtime checks and compiler attributes, the performance overhead associated with redundant secure-to-non-secure transition code can be effectively minimized. This approach ensures that the transition code is only executed when necessary, preserving the security of the system while optimizing performance.

Conclusion

The ARM Cortex-M55 TrustZone security extension provides a robust mechanism for isolating secure and non-secure worlds. However, the overhead associated with redundant secure-to-non-secure transition code can impact performance, particularly when secure functions are called frequently from the secure world. By implementing a conditional execution mechanism and leveraging compiler attributes, the performance overhead can be significantly reduced. This approach ensures that the transition code is only executed when necessary, preserving the security of the system while optimizing performance.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *