On Tue, 2026-09-15 at 10:49 +0800, Zephyr Li wrote:
> vsepc is the VS-mode counterpart of sepc and is a WARL register, but
> unlike mepc and sepc its accessors do not mask the low address bits
> according to IALIGN.  As a result, values with invalid low bits can
> be
> observed through vsepc.
> 
> Apply get_xepc_mask() to both vsepc reads and writes, matching the
> existing mepc/sepc handling.
> 
> Add a TCG regression test covering both IALIGN=16 and IALIGN=32.
> 
> Fixes: 8747c9eeb2aa ("target/riscv: Add Hypervisor virtual CSRs
> accesses")
> Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/4420
> Signed-off-by: Zephyr Li <[email protected]>

Thanks!

Applied to riscv-to-apply.next

Alistair

> ---
>  target/riscv/tcg/csr.c                 |  4 +-
>  tests/tcg/riscv64/system/meson.build   | 11 ++++++
>  tests/tcg/riscv64/test-vsepc-masking.S | 54
> ++++++++++++++++++++++++++
>  3 files changed, 67 insertions(+), 2 deletions(-)
>  create mode 100644 tests/tcg/riscv64/test-vsepc-masking.S
> 
> diff --git a/target/riscv/tcg/csr.c b/target/riscv/tcg/csr.c
> index bd4b6dc114..274c5cfbf4 100644
> --- a/target/riscv/tcg/csr.c
> +++ b/target/riscv/tcg/csr.c
> @@ -5299,14 +5299,14 @@ static RISCVException
> write_vsscratch(CPURISCVState *env, int csrno,
>  static RISCVException read_vsepc(CPURISCVState *env, int csrno,
>                                   target_ulong *val)
>  {
> -    *val = env->vsepc;
> +    *val = env->vsepc & get_xepc_mask(env);
>      return RISCV_EXCP_NONE;
>  }
>  
>  static RISCVException write_vsepc(CPURISCVState *env, int csrno,
>                                    target_ulong val, uintptr_t ra)
>  {
> -    env->vsepc = val;
> +    env->vsepc = val & get_xepc_mask(env);
>      return RISCV_EXCP_NONE;
>  }
>  
> diff --git a/tests/tcg/riscv64/system/meson.build
> b/tests/tcg/riscv64/system/meson.build
> index 8604c2a45a..5d633a266a 100644
> --- a/tests/tcg/riscv64/system/meson.build
> +++ b/tests/tcg/riscv64/system/meson.build
> @@ -24,6 +24,17 @@ tests += {
>    'test-crc32.S': setup + {'qemu_args': ['-cpu', 'rv64,xlrbr=true',
> qemu_args]},
>    'test-minstret-ecall.S': setup + {'qemu_args': ['-icount',
> 'shift=1', qemu_args]},
>    'test-misa-w.S': setup + {'qemu_args': ['-cpu', 'rv64,x-misa-
> w=true,c=true,v=true', qemu_args]},
> +  'test-vsepc-masking.S': setup + {
> +    'test_name': 'test-vsepc-masking-c',
> +    'qemu_args': ['-cpu', 'rv64,h=true,c=true', qemu_args],
> +  },
> +}
> +
> +tests += {
> +  'test-vsepc-masking.S': {
> +    'test_name': 'test-vsepc-masking-no-c',
> +    'qemu_args': ['-cpu', 'rv64,h=true,c=false,zca=false',
> qemu_args],
> +  },
>  }
>  
>  tests += {
> diff --git a/tests/tcg/riscv64/test-vsepc-masking.S
> b/tests/tcg/riscv64/test-vsepc-masking.S
> new file mode 100644
> index 0000000000..e5460f8aee
> --- /dev/null
> +++ b/tests/tcg/riscv64/test-vsepc-masking.S
> @@ -0,0 +1,54 @@
> +/* SPDX-License-Identifier: GPL-2.0-or-later */
> +
> +#define MISA_C          (1 << 2)
> +
> +     .option norvc
> +     .text
> +     .global _start
> +_start:
> +     csrr    s0, misa
> +     andi    s0, s0, MISA_C
> +
> +     lla     s1, test_addr
> +     ori     t0, s1, 3
> +     csrw    vsepc, t0
> +     csrr    t1, vsepc
> +
> +     beqz    s0, ialign32
> +     addi    t2, s1, 2       /* IALIGN=16: bit 0 reads as zero.
> */
> +     j       check
> +
> +ialign32:
> +     /* IALIGN=32: bits [1:0] read as zero. */
> +     mv      t2, s1
> +
> +check:
> +     li      a0, 2
> +     bne     t1, t2, _exit
> +
> +     li      a0, 0
> +     j       _exit
> +
> +     .balign 4
> +test_addr:
> +     nop
> +
> +/* Exit code in a0. */
> +_exit:
> +     lla     a1, semiargs
> +     li      t0, 0x20026     /* ADP_Stopped_ApplicationExit */
> +     sd      t0, 0(a1)
> +     sd      a0, 8(a1)
> +     li      a0, 0x20        /* TARGET_SYS_EXIT_EXTENDED */
> +
> +     /* Semihosting call sequence. */
> +     .balign 16
> +     slli    zero, zero, 0x1f
> +     ebreak
> +     srai    zero, zero, 0x7
> +     j       .
> +
> +     .data
> +     .balign 16
> +semiargs:
> +     .space  16

Reply via email to