On Fri, 4 Sept 2026 at 06:23, <[email protected]> wrote:
>
> From: Frédéric Pétrot <[email protected]>
>
> Adding asm tests to check that mstatus and sstatus are updated as
> expected in an rv128 cpu.
>
> Signed-off-by: Frédéric Pétrot <[email protected]>
> Reviewed-by: Daniel Henrique Barboza <[email protected]>
> Message-ID: <[email protected]>
> Signed-off-by: Alistair Francis <[email protected]>

Hi; this test case provokes undefined behaviour which trips the
clang sanitizer if you run 'make check-tcg' on a build with it enabled
(i.e. configure with "--cc=clang --cxx=clang++ --enable-ubsan").

Running the test case on its own:

$ 
UBSAN_OPTIONS=halt_on_error=1:abort_on_error=1:print_summary=1:print_stacktrace=1
./build/riscv-san-dbg/qemu-system-riscv64 -cpu x-rv128 -M virt
-display none -serial stdio -semihosting -bios
./build/riscv-san-dbg/tests/tcg/riscv64-softmmu-test-rv128-sstatus.test
../../target/riscv/tcg/pmp.c:572:25: runtime error: shift exponent 64
is too large for 64-bit type 'target_ulong' (aka 'unsigned long')
/usr/bin/llvm-symbolizer-18: error: '/memfd:tcg-jit (deleted)': No
such file or directory
    #0 0x5ab9d5e8b569 in pmpcfg_csr_read
/home/pm215/qemu/build/riscv-san-dbg/../../target/riscv/tcg/pmp.c:572:25
    #1 0x5ab9d5f91440 in read_pmpcfg
/home/pm215/qemu/build/riscv-san-dbg/../../target/riscv/tcg/csr.c:5588:12
    #2 0x5ab9d5f79085 in riscv_csrrw_do64
/home/pm215/qemu/build/riscv-san-dbg/../../target/riscv/tcg/csr.c:5889:15
    #3 0x5ab9d5f7a274 in riscv_csrrw_i128
/home/pm215/qemu/build/riscv-san-dbg/../../target/riscv/tcg/csr.c:6046:11
    #4 0x5ab9d5fb7b11 in helper_csrw_i128
/home/pm215/qemu/build/riscv-san-dbg/../../target/riscv/tcg/op_helper.c:117:26
    #5 0x77568c0008ba  (/memfd:tcg-jit (deleted)+0x8ba)

SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior
../../target/riscv/tcg/pmp.c:572:25
Aborted (core dumped)

What happens is that in pmpcfg_csr_read() we do this:

    int pmpcfg_nums = 2 << riscv_cpu_mxl(env);

    for (i = 0; i < pmpcfg_nums; i++) {
        val = pmp_read_cfg(env, (reg_index * 4) + i);
        cfg_val |= (val << (i * 8));
    }

For the x-rv128 CPU pmpcfg_nums comes out as 16, and then
we try to assemble 16 bytes into an 8-bit target_ulong variable,
and for bytes 8..15 the shift amount is larger than the
type, which is UB.

I'm not sure how this is intended to work; could you have
a look at it, please?

thanks
-- PMM

Reply via email to