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
