Skip to content

arm HSTR trap settings routed to EL1 instead of EL2

Host environment

  • Operating system: Debian Bookworm
  • OS/kernel version: 5.15.146.1-microsoft-standard-WSL2
  • Architecture: x86_64
  • QEMU flavor: qemu-system-arm
  • QEMU version: QEMU emulator version 8.2.50 (v8.2.0-2542-gba49d760)
  • QEMU command line:
    qemu-system-arm \
     -nographic \
     -cpu cortex-a7 \
     -M virt,virtualization=on \
     -m 1G \
     -kernel el2.elf

Emulated/Virtualized environment

  • Operating system: Bare mental test program (listed in Steps to reproduce)
  • OS/kernel version: N/A
  • Architecture: ARM

Description of problem

ARM's HSTR register is used to trap CP15 access from EL1/0. qemu's implementation seems to be inconsistent with ARM's documentation.

Take the system register VBAR for example, the following pseudo code is grabbed from ARM DDI 0487J.a ID042523 G8-10651, which is the logics behind when reading VBAR.

if PSTATE.EL == EL0 then
    UNDEFINED;
elsif PSTATE.EL == EL1 then
    if EL2Enabled() && !ELUsingAArch32(EL2) && HSTR_EL2.T12 == '1' then
        AArch64.AArch32SystemAccessTrap(EL2, 0x03);
    elsif EL2Enabled() && ELUsingAArch32(EL2) && HSTR.T12 == '1' then
        AArch32.TakeHypTrapException(0x03);
    elsif HaveEL(EL3) && ELUsingAArch32(EL3) then
        R[t] = VBAR_NS;
    else
        R[t] = VBAR;
elsif PSTATE.EL == EL2 then
    if HaveEL(EL3) && ELUsingAArch32(EL3) then
        R[t] = VBAR_NS;
    else
        R[t] = VBAR;
elsif PSTATE.EL == EL3 then
    if SCR.NS == '0' then
        R[t] = VBAR_S;
    else
        R[t] = VBAR_NS;

The main logics in my attached test program are:

  1. Setting EL2 and EL1's exception table
  2. Set HSTR.T12
  3. ERET to EL1, and read VBAR from EL1

As the document mentions, when CPU running on EL1 && HSTR.T12 is set, HypTrapException 0x3 should be taken, which is EL2. But the test program shows, on such circumstances, CPU is being routed to EL1's undefined exception.

Steps to reproduce

  1. Clone this repo https://github.com/roolrz/reproduce-qemu-arm-hstr-issue
  2. Use make to build the test program
  3. Use following command to launch it
qemu-system-arm \
	-nographic \
	-cpu cortex-a7 \
	-M virt,virtualization=on \
	-m 1G \
	-kernel el2.elf
  1. The following message is printed by the program, problem reproduced
EL2 Booted
Jumping to el1
el1 reached, triggering trap
EL1 undefined sync triggered

Additional information

Edited by roolrz
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information