Exception handling in HYP mode on ARMv7-A

Jim Posen jim.posen at gmail.com
Tue Oct 12 21:02:44 CEST 2021


I've run into an issue with exception handling on the Raspberry Pi 3 in
32-bit
mode (config rpi_3_32b) and the ODroid XU4 (config odroid-xu3). When
testing
the "exception undefined" command, instead of printing out register info
and
resetting the CPU like it's supposed to, U-Boot just hangs.

I noticed that on both of these boards, U-Boot runs in hypervisor mode
(HYP)
because both the Pi's Cortex-A53 and the ODroid's Cortex-A7 support
virtualization extensions. This causes several issues with the ARMv7
exception
handling code, which assumes that exceptions are taken in EL1.

(All file names and line numbers referenced below are respect to the
v2021.10
release)

The first issue running in HYP mode is that the vector table base address
is
not set correctly. In arch/arm/cpu/armv7/start.S L78 and
arch/arm/lib/relocate.S L45, the VBAR register is loaded with the vector
table
base address. However, exceptions taken to EL2 use the address in the HVBAR
register, not VBAR.

The next issue is that the get_bad_stack macro (arch/arm/lib/vectors.S)
uses
"movs pc, lr" to return from the exception into supervisor mode, but this
is an
illegal instruction in HYP mode as it was replaced by "eret". Also, the lr
register does not hold the exception return address (which is used to
determine
the PC before the exception), since exceptions taken to EL2 store the
return
address in the new ELR_hyp register instead. I'm also not sure in reading
this
code why there's a switch to supervisor mode...

So to handle an exception to EL2 properly, an instruction like "msr
ELR_hyp,
lr" needs to be assembled, and this requires "-march=armv7ve" in the CC
flags,
not "-march=armv7-a".

I found it quite surprising that this didn't work correctly. I'd be happy
to
submit a patch for it, and could use some guidance. To change the CC flag
to
the correct architecture, it seems like introducing a CONFIG_CPU_V7VE may
be
the right approach. Then I'd say that for builds with this config, there
should
be two separate exception vector tables, one for EL1, which would be left
as it
currently is, and a new one for EL2, with this table loaded into HVBAR.

I'd appreciate your thoughts, thanks.


More information about the U-Boot mailing list