ARMv8-M Secure and Non-Secure Mode Transitions During Interrupt Handling

The ARMv8-M architecture introduces a robust security model that partitions the processor into Secure and Non-Secure states. This partitioning is critical for modern embedded systems, where secure and non-secure software components must coexist while maintaining isolation. A common scenario involves a Non-Secure world interrupt handler calling a Secure world API. Understanding the CPU state and stack pointer behavior during such transitions is essential for designing reliable and secure systems.

When a Non-Secure world interrupt occurs, the processor transitions from Non-Secure Thread Mode to Non-Secure Handler Mode to execute the interrupt service routine (ISR). If the ISR calls a Secure API, the processor must transition to the Secure state. The key question is: What is the CPU mode (Thread or Handler) and which stack pointer (MSP or PSP) is used after transitioning to the Secure state?

The ARMv8-M architecture defines four distinct modes:

  • Secure Thread Mode
  • Secure Handler Mode
  • Non-Secure Thread Mode
  • Non-Secure Handler Mode

Handler Mode is reserved for exception handling, such as interrupt service routines and system calls, while Thread Mode is used for application code execution. The stack pointer used depends on the current mode and the state (Secure or Non-Secure). In Handler Mode, the Main Stack Pointer (MSP) is typically used, while in Thread Mode, the Process Stack Pointer (PSP) may be used, depending on the configuration.

When a Non-Secure Handler Mode calls a Secure API, the processor transitions to Secure Handler Mode. This transition is initiated by the Secure Gateway (SG) instruction, which is placed in Non-Secure Callable (NSC) memory. The SG instruction ensures that the transition to the Secure state is controlled and secure. After executing the SG instruction, the processor branches to the Secure memory region where the Secure API resides.

During this transition, the processor remains in Handler Mode but switches from Non-Secure Handler Mode to Secure Handler Mode. The stack pointer used in Secure Handler Mode is the Secure Main Stack Pointer (MSP_S). This behavior ensures that the Secure API executes with the appropriate privileges and stack context.

Secure and Non-Secure Stack Pointer Management During Mode Transitions

The management of stack pointers during Secure and Non-Secure mode transitions is a critical aspect of ARMv8-M systems. The processor uses separate stack pointers for Secure and Non-Secure states, and these stack pointers are further divided into Main Stack Pointers (MSP) and Process Stack Pointers (PSP) depending on the mode.

In the scenario where a Non-Secure Handler Mode calls a Secure API, the processor transitions to Secure Handler Mode and uses the Secure Main Stack Pointer (MSP_S). This ensures that the Secure API executes with the appropriate stack context and privileges. The Non-Secure Handler Mode stack pointer (MSP_NS or PSP_NS) is saved as part of the context switching process.

The Interrupt Program Status Register (IPSR) plays a crucial role in determining the processor mode during these transitions. The IPSR value indicates whether the processor is in Thread Mode (IPSR = 0) or Handler Mode (IPSR ≠ 0). When transitioning from Non-Secure Handler Mode to Secure Handler Mode, the IPSR value is preserved, ensuring that the processor remains in Handler Mode.

A common use case involves using a Non-Secure SVC (Supervisor Call) to transition to Non-Secure Handler Mode and then calling a Secure API. In this scenario, the processor remains in Handler Mode after transitioning to the Secure state, allowing the Secure API to use the Secure Main Stack Pointer (MSP_S). This behavior enables the Secure API to set up the Secure Process Stack Pointer (PSP_S) and its limit (PSPLIM_S) with the appropriate privileges.

If the Non-Secure world calls a Secure API in Thread Mode, the processor transitions to Secure Thread Mode and uses the Secure Process Stack Pointer (PSP_S). This ensures that the Secure API executes in the context of the calling thread, maintaining isolation between Secure and Non-Secure worlds.

Implementing Secure API Calls from Non-Secure Interrupt Handlers

To implement Secure API calls from Non-Secure interrupt handlers, developers must carefully manage the processor state and stack pointers. The following steps outline the process and provide solutions for common challenges:

  1. Non-Secure SVC Execution: When a Non-Secure SVC is issued, the processor transitions from Non-Secure Thread Mode to Non-Secure Handler Mode. The SVC handler executes in Non-Secure Handler Mode, using the Non-Secure Main Stack Pointer (MSP_NS).

  2. Secure API Call: Within the Non-Secure SVC handler, a call to a Secure API is made using the Secure Gateway (SG) instruction. The SG instruction is placed in Non-Secure Callable (NSC) memory, ensuring a secure transition to the Secure state.

  3. Transition to Secure Handler Mode: After executing the SG instruction, the processor transitions to Secure Handler Mode and branches to the Secure memory region where the Secure API resides. The processor uses the Secure Main Stack Pointer (MSP_S) during the execution of the Secure API.

  4. Stack Pointer Management: In Secure Handler Mode, the Secure API can configure the Secure Process Stack Pointer (PSP_S) and its limit (PSPLIM_S). This setup ensures that subsequent Secure API calls in Thread Mode use the correct stack pointer.

  5. Return to Non-Secure State: After completing the Secure API execution, the processor returns to Non-Secure Handler Mode using the function return mechanism (e.g., BX lr with FNC_RETURN). The processor state and stack pointers are restored to their previous values.

A critical consideration is the preservation of the processor state during transitions. The IPSR value must be checked to ensure that the processor remains in the correct mode (Thread or Handler) after transitioning between Secure and Non-Secure states. Additionally, developers must ensure that the Secure and Non-Secure stack pointers are properly initialized and managed to avoid stack corruption.

For example, consider a system where a Non-Secure SVC handler calls a Secure API to perform a privileged operation. The Secure API executes in Secure Handler Mode, allowing it to configure the Secure Process Stack Pointer (PSP_S) and its limit (PSPLIM_S). Once the Secure API completes, the processor returns to Non-Secure Handler Mode, and the Non-Secure SVC handler continues execution.

In cases where the Non-Secure world calls a Secure API in Thread Mode, the processor transitions to Secure Thread Mode and uses the Secure Process Stack Pointer (PSP_S). This ensures that the Secure API executes in the context of the calling thread, maintaining isolation between Secure and Non-Secure worlds.

By following these steps and understanding the processor state and stack pointer behavior, developers can implement Secure API calls from Non-Secure interrupt handlers reliably and securely. Proper management of the processor state and stack pointers is essential for ensuring the correct operation of ARMv8-M systems with Security Extensions.

Similar Posts

Leave a Reply

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