Skip to content

RISC-V: incorrect emulation of load and store on big-endian systems

For TCG emulation of load and store operations where the endianness of host and target differ, byte swapping is needed. This is controlled by passing the flag MO_TE to the code generating functions.

Unfortunately this has only incompletely observed when implementing new extensions for the RISC-V ISA. Here is just one example. There is a long and a compressed form of the lhu opcode. While the long form implementation of lhu correctly passes MO_TE via usage of MO_TEUW the implementation of c.lhu does not:

static bool trans_lhu(DisasContext *ctx, arg_lhu *a)
{
    return gen_load(ctx, a, MO_TEUW);
}

static bool trans_c_lhu(DisasContext *ctx, arg_c_lhu *a)
{
    REQUIRE_ZCB(ctx);
    return gen_load(ctx, a, MO_UW);
}

As reported in Launchpad issue https://bugs.launchpad.net/ubuntu/+source/qemu/+bug/2123828 this leads to failures when emulating RISC-V on a big endian platform like IBM System/390 (s390x).

c.lhu is just an example of this problem. At least the following includes are affected:

  • target/riscv/insn_trans/trans_rvi.c.inc
  • target/riscv/insn_trans/trans_rvzce.c.inc
  • target/riscv/insn_trans/trans_xthead.c.inc
  • target/riscv/insn_trans/trans_rvzabha.c.inc

Best regards

Heinrich

Host environment

  • Operating system: Ubuntu 25.10
  • Architecture: s390x
  • QEMU flavor: qemu-riscv64
  • QEMU version: 9.2, 10.1
  • QEMU command line: qemu-riscv64 hello

Emulated/Virtualized environment

  • Operating system: Ubuntu 25.10
  • Architecture: riscv64

Minimal reproducer:

$ sudo apt update && sudo apt install qemu-user
$ dpkg -l | grep libc6
ii libc6:s390x 2.42-0ubuntu3
$ dpkg -l | grep qemu-user
ii qemu-user 1:10.1.0+ds-5ubuntu1
$ dpkg --print-architecture
s390x
$ sudo dpkg --add-architecture riscv64
$ sudo apt update
$ sudo apt install hello:riscv64
$ /usr/bin/qemu-riscv64 /usr/bin/hello
/usr/bin/hello: /lib/ld-linux-riscv64-lp64d.so.1: unsupported version 256 of Verdef record
/usr/bin/hello: /lib/riscv64-linux-gnu/libc.so.6: unsupported version 256 of Verdef record
/usr/bin/hello: /lib/riscv64-linux-gnu/libc.so.6: unsupported version 256 of Verdef record
/usr/bin/hello: /lib/riscv64-linux-gnu/libc.so.6: unsupported version 256 of Verdef record
/usr/bin/hello: /lib/ld-linux-riscv64-lp64d.so.1: unsupported version 256 of Verdef record
/usr/bin/hello: /lib/ld-linux-riscv64-lp64d.so.1: unsupported version 256 of Verdef record
/usr/bin/hello: /lib/ld-linux-riscv64-lp64d.so.1: unsupported version 256 of Verdef record
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information