Hi Everybody ,
I am working on the FVP_Base_RevC-2xAEMvA platform with the following setup:
FVP_Base_RevC-2xAEMvA
Secure OS: OP-TEE
EL3 Monitor: Trusted Firmware-A (TF-A)
Non-Secure OS: Linux (running at EL1, no EL2/hypervisor)
I am trying to read and write EL1 system registers (e.g., SCTLR_EL1) of the non-secure world (Linux) from EL3 (secure monitor context) in the absence of EL2.
SCTLR_EL1
I am issuing an SMC from EL1 (non-secure) to EL3, and at EL3 I intend to read and modify system registers belonging to the Linux environment. The goal is for these changes made at EL3 to be reflected when execution returns to the non-secure world. I tried to toggle wxor bit of SCTLR_EL1 register so it is a valid change I also verified it by doing MSR instruction from Linux and I can see the change if I toggle that bit from Linux.
What I Did:
1. System Call in Linux (Non-Secure World)
I wrote a custom Linux system call that issues an SMC to EL3.
In this syscall, I read the value of SCTLR_EL1 before and after the SMC call, to check whether any changes made in EL3 were reflected.
2. I tried to write to system registers of Linux (Non secure wold EL1) at EL3 by two approaches.
A. Context Management API & Direct Register Access (in opteed_main.c)
opteed_main.c
I implemented a secure service handler inside opteed_main.c at EL3.
First, I attempted to read the value of SCTLR_EL1 using a direct MRS instruction inside this handler.However, the value retrieved was different from what I observed in Linux.
MRS
I then tried to update the value using MSR, but the modification did not reflect when control returned to the non-secure world.
MSR
Additionally, I used the TF-A context management APIs (e.g., write_ctx_reg, read_ctx_reg) to manipulate the non-secure context.Despite this, the values read were still different, and any modifications did not propagate back to the non-secure Linux environment.
write_ctx_reg
read_ctx_reg
B. Direct MSR from el3_exit() (Before ERET)
el3_exit()
el3_exit() routine I used mv instruction to change the content of x28 before eret instruction,
I also came across a Trusted Firmware-A technical presentation discussing the context management library, where it was shown (via a diagram) that only general-purpose registers are saved when transitioning from the non-secure world to EL3. Here I attached that diagram and presentation for reference.
Presentation : www.trustedfirmware.org/.../RefactorContextMgmt.pdf
Based on this I have some doubts
Questions
What happens to non-secure world EL1 system registers (e.g., SCTLR_EL1) during an SMC exception?
Are these registers saved and restored by TF-A as part of the non-secure context management, or Hardware does that?
Why am I getting different values from non secure Linux and from EL3 while reading the same register (I checked NS bit also I am reading the values of Non secure world copies only)?
What is the correct or recommended way to access or modify non-secure EL1 system registers from EL3, especially when EL2 is not present?
Thank you in advance for any insights or guidance.
Best regards, Dev