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?
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?