SMC Call Misrouting to Sync Exception at NS.EL1 Instead of EL3
When working with ARM Cortex-A53 processors, particularly in systems requiring secure and non-secure world transitions, a common issue arises when Secure Monitor Calls (SMC) fail to trap to Exception Level 3 (EL3) as expected. Instead, the processor remains in Non-Secure EL1 and triggers a synchronous exception at the same level. This behavior is often accompanied by an "unknown exception" reported in the Exception Syndrome Register (ESR). This issue is critical in systems where secure world functionality, such as trusted firmware or secure boot, relies on SMC calls to transition between secure and non-secure states.
The root cause of this problem typically lies in the configuration of system control registers, particularly the Secure Configuration Register (SCR_EL3), and the absence or misconfiguration of a Secure Monitor at EL3. The Secure Monitor is responsible for handling SMC calls and facilitating transitions between secure and non-secure states. Without proper configuration, the processor may misinterpret the SMC instruction, leading to unexpected behavior.
This guide will delve into the technical details of this issue, explore potential causes, and provide a comprehensive set of troubleshooting steps and solutions to ensure SMC calls correctly trap to EL3.
SCR_EL3.SMD Bit Configuration and Secure Monitor Presence
The primary cause of SMC calls failing to trap to EL3 is the misconfiguration of the Secure Configuration Register (SCR_EL3), specifically the Secure Monitor Disable (SMD) bit. The SMD bit controls whether SMC instructions are enabled or disabled. When SMD is set to 1, SMC instructions are treated as undefined instructions, causing the processor to trigger a synchronous exception at the current exception level instead of trapping to EL3. By default, the SMD bit is reset to 0, enabling SMC instructions to trap to EL3.
However, even with SMD set to 0, the absence of a Secure Monitor at EL3 can lead to undefined behavior. The Secure Monitor is responsible for handling SMC calls and managing transitions between secure and non-secure states. Without a Secure Monitor, the processor may not have the necessary infrastructure to process SMC calls, leading to unexpected exceptions.
Additionally, other factors such as the configuration of the Vector Base Address Register (VBAR_EL3), stack pointers, and exception handling mechanisms at EL3 can influence the behavior of SMC calls. For example, if the VBAR_EL3 is not correctly set to point to the exception vector table at EL3, the processor may fail to handle the SMC call properly.
Detailed Analysis of SCR_EL3 and Secure Monitor Initialization
To diagnose and resolve this issue, it is essential to examine the configuration of SCR_EL3 and the initialization of the Secure Monitor. Below is a detailed breakdown of the relevant components and their roles:
SCR_EL3 Configuration
The SCR_EL3 register controls various aspects of the processor’s behavior in EL3, including the handling of SMC calls. The following bits are particularly relevant:
- SMD (Secure Monitor Disable): When set to 1, SMC instructions are disabled, causing them to trigger a synchronous exception at the current exception level. When set to 0, SMC instructions are enabled, allowing them to trap to EL3.
- NS (Non-Secure): Indicates whether the processor is in secure or non-secure state. This bit is automatically managed during exception handling.
- HCE (Hypervisor Call Enable): Enables HVC instructions to trap to EL2.
- RES1 (Reserved Bits): These bits must be set to 1 as per the ARM architecture specification.
A typical configuration for SCR_EL3 when enabling SMC calls and transitioning from EL3 to lower exception levels is as follows:
mov x0, #0x5b1 // SMD=0, NS=1, HCE=1, RES1 bits set
msr SCR_EL3, x0
Secure Monitor Initialization
The Secure Monitor is a critical component that handles SMC calls and manages transitions between secure and non-secure states. It must be initialized during the boot process, typically in EL3, before transitioning to lower exception levels. The Secure Monitor is responsible for:
- Setting up the exception vector table at EL3.
- Configuring stack pointers and other system registers.
- Implementing SMC handlers to process SMC calls.
The ARM Trusted Firmware (ATF) provides a reference implementation of the Secure Monitor, including the "cold boot" path, which initializes the system and sets up SMC handlers. Below is an example of the initialization sequence:
// Set up SCR_EL3
mov x0, #0x5b1
msr SCR_EL3, x0
// Disable coprocessor traps to EL3
msr CPTR_EL3, xzr
// Initialize stack pointer and exception vectors
msr SP_EL3, x1
msr VBAR_EL3, x2
// Transition to lower exception level
mov x0, #0x3c9 // EL2_SP2 | D | A | I | F
msr SPSR_EL3, x0
msr ELR_EL3, lr
eret
Common Pitfalls
- SMD Bit Misconfiguration: Failing to set the SMD bit to 0 can prevent SMC calls from trapping to EL3.
- Missing Secure Monitor: Without a Secure Monitor, SMC calls cannot be processed, leading to undefined behavior.
- Incorrect VBAR_EL3 Setup: If the VBAR_EL3 does not point to the correct exception vector table, the processor may fail to handle SMC calls.
- Improper Exception Handling: Busy loops or incomplete exception handlers at EL3 can prevent proper handling of SMC calls.
Implementing Correct SMC Handling and Debugging Steps
To resolve the issue of SMC calls failing to trap to EL3, follow these detailed troubleshooting steps:
Step 1: Verify SCR_EL3 Configuration
Ensure that the SCR_EL3 register is correctly configured with the SMD bit set to 0. Use the following assembly code to verify and set the register:
mrs x0, SCR_EL3
and x0, x0, #0xFFFFFFFE // Clear SMD bit
msr SCR_EL3, x0
Step 2: Check for Secure Monitor Presence
Verify that a Secure Monitor is present and properly initialized at EL3. If using custom firmware, compare your initialization sequence with the ARM Trusted Firmware (ATF) reference implementation. Ensure that the following components are correctly set up:
- Exception vector table (VBAR_EL3).
- Stack pointers (SP_EL3).
- SMC handlers.
Step 3: Inspect Exception Handling
Ensure that the exception handlers at EL3 are correctly implemented and not simply busy loops. The handler for SMC calls should process the SMC instruction and perform the necessary actions, such as transitioning between secure and non-secure states.
Step 4: Debug ESR and Exception Context
When an SMC call triggers a synchronous exception, inspect the Exception Syndrome Register (ESR) to determine the cause of the exception. The ESR provides detailed information about the type of exception, such as an illegal instruction or an undefined instruction. Use the following code to read the ESR:
mrs x0, ESR_EL1
Step 5: Compare with U-Boot Initialization
If the system works correctly with U-Boot but fails with custom firmware, compare the initialization sequences of both. Pay particular attention to the configuration of SCR_EL3, VBAR_EL3, and the presence of a Secure Monitor.
Step 6: Use ARM Trusted Firmware as Reference
Refer to the ARM Trusted Firmware (ATF) source code for a complete implementation of the Secure Monitor and SMC handling. The ATF provides a robust framework for managing secure and non-secure transitions, including the "cold boot" path and PSCI services.
git clone https://github.com/ARM-software/arm-trusted-firmware.git
Step 7: Validate System State Before SMC Call
Before making an SMC call, ensure that the system is in the correct state. This includes verifying the exception level, stack pointers, and register configurations. Use the following code to check the current exception level:
mrs x0, CurrentEL
Step 8: Test with Minimal Configuration
Create a minimal test case that initializes only the necessary components (SCR_EL3, VBAR_EL3, and Secure Monitor) and makes an SMC call. This helps isolate the issue and identify any misconfigurations.
By following these steps and ensuring proper configuration of SCR_EL3 and the Secure Monitor, you can resolve the issue of SMC calls failing to trap to EL3. This guide provides a comprehensive approach to diagnosing and fixing this common problem in ARM Cortex-A53 systems.