On Tue, 2026-08-11 at 09:24 +0800, wangyang wrote:
> In user-only builds the base Zicntr counters cycle/instret are
> retired
> unconditionally because the ext_zicntr gate sits inside the
> #if !defined(CONFIG_USER_ONLY) block.  -cpu ... ,zicntr=false is
> therefore accepted but ignored, while the sibling zihpm=false
> correctly
> makes hpmcounter3 illegal.  Move the ext_zicntr check ahead of the
> user-only block so an explicit zicntr=false makes the base counters
> behave as unsupported in linux-user mode, matching native hardware.
> 
> Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/4148
> Signed-off-by: wangyang <[email protected]>

Reviewed-by: Alistair Francis <[email protected]>

Alistair

> ---
>  target/riscv/tcg/csr.c | 11 +++++++----
>  1 file changed, 7 insertions(+), 4 deletions(-)
> 
> diff --git a/target/riscv/tcg/csr.c b/target/riscv/tcg/csr.c
> index 36f2004bc56..c0829aab043 100644
> --- a/target/riscv/tcg/csr.c
> +++ b/target/riscv/tcg/csr.c
> @@ -111,6 +111,13 @@ static RISCVException vs(CPURISCVState *env, int
> csrno)
>  
>  static RISCVException ctr(CPURISCVState *env, int csrno)
>  {
> +    if ((csrno >= CSR_CYCLE && csrno <= CSR_INSTRET) ||
> +        (csrno >= CSR_CYCLEH && csrno <= CSR_INSTRETH)) {
> +        if (!riscv_cpu_cfg(env)->ext_zicntr) {
> +            return RISCV_EXCP_ILLEGAL_INST;
> +        }
> +    }
> +
>  #if !defined(CONFIG_USER_ONLY)
>      RISCVCPU *cpu = env_archcpu(env);
>      int ctr_index;
> @@ -127,10 +134,6 @@ static RISCVException ctr(CPURISCVState *env,
> int csrno)
>  
>      if ((csrno >= CSR_CYCLE && csrno <= CSR_INSTRET) ||
>          (csrno >= CSR_CYCLEH && csrno <= CSR_INSTRETH)) {
> -        if (!riscv_cpu_cfg(env)->ext_zicntr) {
> -            return RISCV_EXCP_ILLEGAL_INST;
> -        }
> -
>          goto skip_ext_pmu_check;
>      }
>  
> -- 
> 2.43.0

Reply via email to