What are the necessary preconditions to load a guest into EL1 from EL2?

I have successfully moved from EL3 to EL2. After doing some initialization I am trying to move from EL2 into EL1 with a very simple guest image. My process looks like:

  • Map EL1 memory into EL2
  • Copy EL1 image to RAM
  • Initialize sctlr_el1 = 0x30d00800
    • MMU disabled (bit unset)
    • I/D cache disabled (bit unset)
    • RES1 bits set
  • Initialize spsr_el2 = 0x3c9
    • Mask FIAD interrupts (0x3c0)
    • Set spsr.M to EL1h (SPx) (0x9)
  • Set elr_el2 to load address
  • Initialize hcr_el2 = 0
    • Set to zero, no intended traps back to EL2 for simplicity
  • eret

However, after the eret the machine will immediately trigger an instruction prefetch abort with FAR equal to the load address. From the looks of it, I don't think the hardware ever left EL2. In fact, esr_el2 has IL set, which indicates an illegal configuration (though I am confused as to why it did not manifest as an UNKNOWN exception (EC = 0x00) instead.

While debugging this I tried a few cases that seemed relevant:

  • Return to EL2 to load address of EL1 (fail)
  • Return to EL2 to load address in mapped EL2 memory (success)
  • Return to EL1 to load address in mapped EL2 memory (fail)
  • Return to EL1 to load address of EL1 (fail -- the "normal" case)

In all failure cases the hardware throws the same instruction abort (EC = 0x21)

Am I missing a step?

More questions in this forum