Secure World Access to Non-Secure Memory on ARMv8-M TrustZone
The ARMv8-M architecture introduces TrustZone technology, which provides hardware-enforced isolation between Secure and Non-Secure worlds. This isolation is critical for security-sensitive applications, ensuring that Secure world code and data are protected from unauthorized access by Non-Secure world code. However, this isolation also introduces complexities when Secure world code needs to access Non-Secure memory regions. In this scenario, a common issue arises where Secure world code is unable to write to Non-Secure memory regions, even when the Security Attribution Unit (SAU) has been configured to mark the memory region as Non-Secure.
The core of the problem lies in the interaction between the SAU, the Memory Protection Unit (MPU), and the address translation mechanisms. The SAU defines the security attributes of memory regions, while the MPU enforces access permissions. Additionally, the address translation between Secure and Non-Secure worlds must be handled correctly to ensure that the Secure world can access Non-Secure memory regions without violating security constraints.
In the specific case discussed, the Secure world code is running in a privileged state and attempts to write to a Non-Secure memory region defined by the SAU. However, the write operation fails, indicating a potential issue with the configuration of the SAU, MPU, or address translation. The failure to write to Non-Secure memory from the Secure world can stem from several causes, including incorrect SAU configuration, missing MPU settings, or improper address translation.
SAU Configuration and Address Translation Challenges
The Security Attribution Unit (SAU) is a critical component in ARMv8-M TrustZone systems, responsible for defining the security attributes of memory regions. The SAU divides the memory map into Secure and Non-Secure regions, and it is essential to configure it correctly to allow Secure world code to access Non-Secure memory. However, the SAU alone is not sufficient to enable access to Non-Secure memory from the Secure world. The Memory Protection Unit (MPU) must also be configured to grant the necessary permissions for the Secure world to access Non-Secure memory regions.
One of the key challenges in this scenario is address translation. The ARMv8-M architecture supports address translation between Secure and Non-Secure worlds, but this translation must be handled carefully to ensure that the Secure world can access Non-Secure memory regions without violating security constraints. In the case discussed, the SRAM region for the Secure world starts at an offset of 0x30000000, while the Non-Secure SRAM region starts at 0x20018000. The SAU is configured to mark the Non-Secure SRAM region as Non-Secure, but the Secure world code fails to write to this region.
The issue likely arises from the way the address translation is handled. When the Secure world attempts to access the Non-Secure memory region, it must use the correct address translation to ensure that the access is performed in the Non-Secure address space. If the Secure world uses the Secure address (0x30018000) instead of the Non-Secure address (0x20018000), the access will fail because the SAU and MPU are configured based on the Non-Secure address space. Similarly, if the MPU is not configured to grant the necessary permissions for the Secure world to access the Non-Secure memory region, the access will also fail.
Another potential issue is the omission of the Test Target (TT) instruction, which is used to check the permissions of Non-Secure memory regions. The TT instruction can be used to verify that the Secure world has the necessary permissions to access a Non-Secure memory region. If the TT instruction indicates that the Secure world does not have the necessary permissions, the MPU must be configured to grant these permissions.
Configuring SAU, MPU, and Address Translation for Secure World Access
To resolve the issue of Secure world code being unable to write to Non-Secure memory, a systematic approach must be taken to configure the SAU, MPU, and address translation mechanisms. The following steps outline the process for ensuring that the Secure world can access Non-Secure memory regions:
-
Configure the SAU to Define Non-Secure Memory Regions: The first step is to configure the SAU to mark the desired memory regions as Non-Secure. In this case, the Non-Secure SRAM region starting at 0x20018000 must be marked as Non-Secure. This is done by setting the appropriate SAU region registers to define the start address, end address, and security attributes of the Non-Secure memory region.
-
Configure the MPU to Grant Access Permissions: Once the SAU has been configured to mark the memory region as Non-Secure, the MPU must be configured to grant the necessary access permissions for the Secure world to access the Non-Secure memory region. This involves setting up MPU region registers to define the start address, end address, and access permissions for the Non-Secure memory region. The access permissions must include read and write permissions for the Secure world.
-
Use Correct Address Translation: When the Secure world attempts to access the Non-Secure memory region, it must use the correct address translation to ensure that the access is performed in the Non-Secure address space. In this case, the Secure world must use the Non-Secure address (0x20018000) rather than the Secure address (0x30018000). This ensures that the SAU and MPU configurations are applied correctly.
-
Use the TT Instruction to Verify Permissions: Before attempting to access the Non-Secure memory region, the Secure world code should use the TT instruction to verify that it has the necessary permissions to access the region. The TT instruction returns the permissions for the specified address, allowing the Secure world code to check whether it has read and write permissions for the Non-Secure memory region. If the TT instruction indicates that the permissions are insufficient, the MPU configuration must be updated to grant the necessary permissions.
-
Handle Faults and Debugging: If the Secure world code still fails to write to the Non-Secure memory region after configuring the SAU, MPU, and address translation, it is important to handle faults and debugging appropriately. The ARMv8-M architecture provides fault handling mechanisms that can be used to diagnose and resolve issues related to memory access. By enabling fault handlers and analyzing fault status registers, it is possible to identify the root cause of the access failure and take corrective action.
By following these steps, the Secure world code should be able to write to Non-Secure memory regions without encountering access failures. The key is to ensure that the SAU, MPU, and address translation mechanisms are configured correctly and that the Secure world code uses the correct address translation when accessing Non-Secure memory regions.
Detailed Configuration and Debugging Steps
To provide a more detailed guide, let’s break down the configuration and debugging steps into specific actions that can be taken to resolve the issue of Secure world code being unable to write to Non-Secure memory regions.
Step 1: Configure the SAU
The SAU is responsible for defining the security attributes of memory regions. To configure the SAU to mark the Non-Secure SRAM region as Non-Secure, follow these steps:
-
Identify the SAU Region Registers: The SAU typically has a set of region registers that define the start address, end address, and security attributes of each memory region. The number of SAU regions varies depending on the specific ARMv8-M implementation, but most implementations support at least 8 regions.
-
Set the Start and End Addresses: For the Non-Secure SRAM region starting at 0x20018000, set the start address to 0x20018000 and the end address to the end of the SRAM region. For example, if the SRAM region is 64 KB in size, the end address would be 0x20028000.
-
Set the Security Attribute: Set the security attribute of the SAU region to Non-Secure. This is typically done by setting a specific bit in the SAU region register to indicate that the region is Non-Secure.
-
Enable the SAU: Once the SAU region registers have been configured, enable the SAU by setting the appropriate control register bit. This activates the SAU and applies the security attributes to the defined memory regions.
Step 2: Configure the MPU
The MPU is responsible for enforcing access permissions for memory regions. To configure the MPU to grant the necessary permissions for the Secure world to access the Non-Secure SRAM region, follow these steps:
-
Identify the MPU Region Registers: The MPU typically has a set of region registers that define the start address, end address, and access permissions for each memory region. The number of MPU regions varies depending on the specific ARMv8-M implementation, but most implementations support at least 8 regions.
-
Set the Start and End Addresses: For the Non-Secure SRAM region starting at 0x20018000, set the start address to 0x20018000 and the end address to the end of the SRAM region. For example, if the SRAM region is 64 KB in size, the end address would be 0x20028000.
-
Set the Access Permissions: Set the access permissions for the MPU region to grant read and write permissions for the Secure world. This is typically done by setting specific bits in the MPU region register to indicate the desired permissions.
-
Enable the MPU: Once the MPU region registers have been configured, enable the MPU by setting the appropriate control register bit. This activates the MPU and applies the access permissions to the defined memory regions.
Step 3: Use Correct Address Translation
When the Secure world attempts to access the Non-Secure SRAM region, it must use the correct address translation to ensure that the access is performed in the Non-Secure address space. Follow these steps to ensure correct address translation:
-
Use the Non-Secure Address: When accessing the Non-Secure SRAM region from the Secure world, use the Non-Secure address (0x20018000) rather than the Secure address (0x30018000). This ensures that the SAU and MPU configurations are applied correctly.
-
Verify Address Translation: If address translation is being used, verify that the translation is configured correctly to map the Non-Secure address to the correct physical memory location. This may involve checking the configuration of the Memory Management Unit (MMU) or other address translation mechanisms.
Step 4: Use the TT Instruction to Verify Permissions
Before attempting to access the Non-Secure SRAM region, the Secure world code should use the TT instruction to verify that it has the necessary permissions to access the region. Follow these steps to use the TT instruction:
-
Execute the TT Instruction: The TT instruction takes an address as input and returns the permissions for that address. Execute the TT instruction with the Non-Secure address (0x20018000) to check the permissions for the Non-Secure SRAM region.
-
Check the Permissions: The TT instruction returns the permissions for the specified address. Check the returned permissions to ensure that the Secure world has read and write permissions for the Non-Secure SRAM region.
-
Update MPU Configuration if Necessary: If the TT instruction indicates that the permissions are insufficient, update the MPU configuration to grant the necessary permissions. This may involve modifying the access permissions in the MPU region registers or enabling additional MPU regions.
Step 5: Handle Faults and Debugging
If the Secure world code still fails to write to the Non-Secure SRAM region after configuring the SAU, MPU, and address translation, it is important to handle faults and debugging appropriately. Follow these steps to diagnose and resolve the issue:
-
Enable Fault Handlers: Enable fault handlers to catch any memory access faults that occur when the Secure world attempts to access the Non-Secure SRAM region. This may involve setting up exception handlers for bus faults, memory management faults, or other types of faults.
-
Analyze Fault Status Registers: When a fault occurs, analyze the fault status registers to determine the cause of the fault. The fault status registers provide detailed information about the type of fault, the address that caused the fault, and the security state of the access.
-
Take Corrective Action: Based on the information provided by the fault status registers, take corrective action to resolve the issue. This may involve updating the SAU, MPU, or address translation configurations, or modifying the Secure world code to handle the fault appropriately.
By following these detailed configuration and debugging steps, the Secure world code should be able to write to Non-Secure memory regions without encountering access failures. The key is to ensure that the SAU, MPU, and address translation mechanisms are configured correctly and that the Secure world code uses the correct address translation when accessing Non-Secure memory regions.
Conclusion
The issue of Secure world code being unable to write to Non-Secure memory regions on ARMv8-M TrustZone systems is a complex problem that requires careful configuration of the SAU, MPU, and address translation mechanisms. By following the steps outlined in this guide, developers can ensure that the Secure world has the necessary permissions to access Non-Secure memory regions and that the address translation is handled correctly. Additionally, the use of the TT instruction and fault handling mechanisms can help diagnose and resolve any issues that arise during the configuration process. With the correct configuration and debugging steps, Secure world code can successfully write to Non-Secure memory regions, enabling secure and efficient operation of ARMv8-M TrustZone systems.