On Tue, 2026-08-11 at 09:14 +0800, wangyang wrote:
> In user-only builds check_zicbo_envcfg() skipped the envcfg check
> entirely (#if !defined(CONFIG_USER_ONLY)), so cbo.inval/cbo.flush/
> cbo.zero retired unconditionally in linux-user even though the
> machine-level envcfg fields are never initialized.  Give the
> user-mode build a senvcfg-based gate, and initialize SENVCFG_CBZE at
> reset when ext_zicboz is enabled so cbo.zero stays usable while
> cbo.inval/cbo.flush remain illegal, matching the user-mode view of a
> typical firmware/kernel setup.
> 
> Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/4107
> Signed-off-by: wangyang <[email protected]>

Thanks!

When sending multiple patches please include a cover letter. It makes
it a lot easier to work with the patches in QEMU tooling.

I'm travelling at the moment and having some troubles applying these.
Do you mind resending them with a cover letter

Alistair

> ---
>  2 files changed, 18 insertions(+), 1 deletion(-)
> 
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 5a82e6563bf..45b7610aa4f 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -1061,6 +1061,14 @@ static void riscv_cpu_reset_hold(Object *obj,
> ResetType type)
>  #else
>      env->priv = PRV_U;
>      env->senvcfg = 0;
> +    /*
> +     * Match the user-mode view of a typical firmware/kernel setup
> where
> +     * cbo.zero is enabled for user mode; the CBCFE/CBIE bits stay
> zero,
> +     * so the cache-management operations remain illegal in user
> mode.
> +     */
> +    if (riscv_cpu_cfg(env)->ext_zicboz) {
> +        env->senvcfg |= SENVCFG_CBZE;
> +    }
>      env->menvcfg = 0;
>  #endif /* !CONFIG_USER_ONLY */
>  
> diff --git a/target/riscv/tcg/op_helper.c
> b/target/riscv/tcg/op_helper.c
> index ba3c7da375a..b9d0deacdfb 100644
> --- a/target/riscv/tcg/op_helper.c
> +++ b/target/riscv/tcg/op_helper.c
> @@ -146,7 +146,16 @@ target_ulong helper_csrrw_i128(CPURISCVState
> *env, int csr,
>  static void check_zicbo_envcfg(CPURISCVState *env, target_ulong
> envbits,
>                                  uintptr_t ra)
>  {
> -#ifndef CONFIG_USER_ONLY
> +#if defined(CONFIG_USER_ONLY)
> +    /*
> +     * linux-user: the machine-level envcfg fields are not part of
> the
> +     * user-mode environment; only the user-mode view of the
> enabling
> +     * bits (senvcfg, as initialized for the guest) applies.
> +     */
> +    if (!get_field(env->senvcfg, envbits)) {
> +        riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, ra);
> +    }
> +#else
>      if ((env->priv < PRV_M) && !get_field(env->menvcfg, envbits)) {
>          riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, ra);
>      }

Reply via email to