AArch64 SVE2 LD/ST instructions segfault on MMIO addresses

Host environment

  • QEMU flavor: qemu-system-aarch64
  • QEMU version: version 6.2.0

Emulated/Virtualized environment

  • Architecture: AArch64

Description of problem

During execution of the following SVE2 instruction: ld1b {z9.s}, p2/z, [x17, z26.s, sxtw] with the following register state:

(gdb) p $x17
$1 = 0xffffffe2
(gdb) p $z26.s.u
$2 = {0x0 <repeats 16 times>}
(gdb) p $p2
$3 = {0xc4, 0x0, 0x9d, 0x0, 0xe5, 0x0, 0x83, 0x0, 0x80, 0xce, 0x3f, 0x3, 0x0, 0x0, 0x0, 0x0, 0x46, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x56, 0x1a, 0x6e, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf0, 0xd8, 0x96, 0xee, 0xfc, 0x7f, 0x0, 0x0, 0x50, 0xce, 0x94, 0x1, 0x0, 0x0, 0x0, 0x0, 0xf0, 0xd8, 0x96, 0xee, 0xfc, 0x7f, 0x0, 0x0, 0x10, 0x38, 0x40, 0x3, 0x0, 0x0, 0x0, 0x0}

QEMU segfaults due to a null pointer access. Note that after translation this address is an MMIO address that points to a UART device.

Additional information

A quick look at the implementation of the SVE2 load/store host memory access functions I've noticed that the TLB_MMIO flag is ignored in sve_probe_page, which means that users use the (null) host address as if it was pointing to real memory. This function (or the ones above it) should (probably) throw the appropriate external data abort, otherwise this needs to be instrumented to support reading from MMIO mapped devices.

Reproducer seed for my future self S6008340160849309262|Q|cd4t|pq|w5|lK124
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information