Let's say that I'm running in EL1 and I want to change the stack location used by the exception code.
Using the SP_EL1 register is actually not permitted when running in EL1, so something like this is not permitted according to the ARM ARM:
ldr x0, =(some_location) msr sp_el1, x0
But I can still do something like this:
msr SPSel, #1 ldr x0, =(some_location) mov sp, x0 msr SPSel, #0
After setting the new location for SP_ELx I go back to the SP_EL0 stack.
This is confusing to me. Why reading / writing the SP_EL1 register is not permitted from EL1 when I can still use SPSEL + MOV?
Hi Carlo,
Regarding SP_EL1, the "Arm Architecture Reference Manual for Armv8-A architecture profile" states that "When the value of SPSel.SP is 1, this register is also accessible at EL1 as the current stack pointer."
Why are you not able to use SP_EL1 at EL1?
Yes, but you cannot write to it to set the SP. See:
if PSTATE.EL == EL0 then UNDEFINED; elsif PSTATE.EL == EL1 then if EL2Enabled() && HCR_EL2.<NV2,NV> == '11' then NVMem[0x240] = X[t]; elsif EL2Enabled() && HCR_EL2.NV == '1' then AArch64.SystemAccessTrap(EL2, 0x18); else UNDEFINED; ...
Did you try with a MOV SP, <Xn>?
This is exactly what I’m doing. Please read my question. I can change the SP_EL1 with SPSEL + MOV but not acting directly on the SP_ EL1 register.
The docu clearly states that "msr SP_EL1,<xt>" is undefined in EL1. So what?