Difference between SP_EL1 and SPSEL + MOV

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?

More questions in this forum