[PATCH v3] target/riscv: fix require_rvv passing on non-RVV CPUs

Sébastien Michelland posted 1 patch 20 hours ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/20260206100256.1360597-1-sebastien.michelland@inria.fr
Maintainers: Palmer Dabbelt <palmer@dabbelt.com>, Alistair Francis <alistair.francis@wdc.com>, Weiwei Li <liwei1518@gmail.com>, Daniel Henrique Barboza <dbarboza@ventanamicro.com>, Liu Zhiwei <zhiwei_liu@linux.alibaba.com>
target/riscv/tcg/tcg-cpu.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
[PATCH v3] target/riscv: fix require_rvv passing on non-RVV CPUs
Posted by Sébastien Michelland 20 hours ago
trans_rvv.c.inc checks for the RVV extension through the function
require_rvv. However, at least under CONFIG_USER_ONLY, the RVV extension
status in DisasContex->mstatus_vs is always set to DIRTY, therefore
treating RVV instructions as legal even when the extension is not
present, e.g. with -cpu=rv32,v=false.

This bug manifests rarely because vset{i}vl{i} perform extra checks that
do fail without RVV, thus raising SIGILL, and with no vtype set nearly
all other RVV instructions still pass require_rvv but fail the vill check.
Only instructions that don't depend on type (whole-register load/stores,
such as vs*r.v) would show the bug by being executed when v=false.

This patch sets mstatus_vs to DISABLED when RVV is not present (checked
with the minimalistic Zve32x), meaning require_rvv now fails as intended.

Signed-off-by: Sébastien Michelland <sebastien.michelland@inria.fr>
---
Thanks Max for your patience with this patch.

 target/riscv/tcg/tcg-cpu.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
index 988b2d905f..9c2c3ac278 100644
--- a/target/riscv/tcg/tcg-cpu.c
+++ b/target/riscv/tcg/tcg-cpu.c
@@ -153,7 +153,7 @@ static TCGTBCPUState riscv_get_tb_cpu_state(CPUState *cs)
 
 #ifdef CONFIG_USER_ONLY
     fs = EXT_STATUS_DIRTY;
-    vs = EXT_STATUS_DIRTY;
+    vs = cpu->cfg.ext_zve32x ? EXT_STATUS_DIRTY : EXT_STATUS_DISABLED;
 #else
     flags = FIELD_DP32(flags, TB_FLAGS, PRIV, env->priv);
 
-- 
2.52.0


Re: [PATCH v3] target/riscv: fix require_rvv passing on non-RVV CPUs
Posted by Max Chou 16 hours ago
On 2026-02-06 11:01, Sébastien Michelland wrote:
> trans_rvv.c.inc checks for the RVV extension through the function
> require_rvv. However, at least under CONFIG_USER_ONLY, the RVV extension
> status in DisasContex->mstatus_vs is always set to DIRTY, therefore
> treating RVV instructions as legal even when the extension is not
> present, e.g. with -cpu=rv32,v=false.
> 
> This bug manifests rarely because vset{i}vl{i} perform extra checks that
> do fail without RVV, thus raising SIGILL, and with no vtype set nearly
> all other RVV instructions still pass require_rvv but fail the vill check.
> Only instructions that don't depend on type (whole-register load/stores,
> such as vs*r.v) would show the bug by being executed when v=false.
> 
> This patch sets mstatus_vs to DISABLED when RVV is not present (checked
> with the minimalistic Zve32x), meaning require_rvv now fails as intended.
> 
> Signed-off-by: Sébastien Michelland <sebastien.michelland@inria.fr>
> ---
> Thanks Max for your patience with this patch.

Reviewed-by: Max Chou <max.chou@sifive.com>

rnax

Re: [PATCH v3] target/riscv: fix require_rvv passing on non-RVV CPUs
Posted by Chao Liu 18 hours ago
Hi Sébastien,

On Fri, Feb 06, 2026 at 11:01:23AM +0100, Sébastien Michelland wrote:
> trans_rvv.c.inc checks for the RVV extension through the function
> require_rvv. However, at least under CONFIG_USER_ONLY, the RVV extension
> status in DisasContex->mstatus_vs is always set to DIRTY, therefore
> treating RVV instructions as legal even when the extension is not
> present, e.g. with -cpu=rv32,v=false.
> 
> This bug manifests rarely because vset{i}vl{i} perform extra checks that
> do fail without RVV, thus raising SIGILL, and with no vtype set nearly
> all other RVV instructions still pass require_rvv but fail the vill check.
> Only instructions that don't depend on type (whole-register load/stores,
> such as vs*r.v) would show the bug by being executed when v=false.
> 
> This patch sets mstatus_vs to DISABLED when RVV is not present (checked
> with the minimalistic Zve32x), meaning require_rvv now fails as intended.
> 
> Signed-off-by: Sébastien Michelland <sebastien.michelland@inria.fr>
> ---
> Thanks Max for your patience with this patch.
> 
>  target/riscv/tcg/tcg-cpu.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
> index 988b2d905f..9c2c3ac278 100644
> --- a/target/riscv/tcg/tcg-cpu.c
> +++ b/target/riscv/tcg/tcg-cpu.c
> @@ -153,7 +153,7 @@ static TCGTBCPUState riscv_get_tb_cpu_state(CPUState *cs)
>  
>  #ifdef CONFIG_USER_ONLY
>      fs = EXT_STATUS_DIRTY;
> -    vs = EXT_STATUS_DIRTY;
> +    vs = cpu->cfg.ext_zve32x ? EXT_STATUS_DIRTY : EXT_STATUS_DISABLED;
This change looks good and perfect to me. Thanks for your contribution!

Reviewed-by: Chao Liu <chao.liu.zevorn@gmail.com>

Thanks,
Chao
>  #else
>      flags = FIELD_DP32(flags, TB_FLAGS, PRIV, env->priv);
>  
> -- 
> 2.52.0
> 
>