From: wangyang <[email protected]>
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
Reviewed-by: Alistair Francis <[email protected]>
Signed-off-by: wangyang <[email protected]>
Message-ID: <[email protected]>
Signed-off-by: Alistair Francis <[email protected]>
---
target/riscv/cpu.c | 8 ++++++++
target/riscv/tcg/op_helper.c | 11 ++++++++++-
2 files changed, 18 insertions(+), 1 deletion(-)
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index d8f239e41d..79ddde419a 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1062,6 +1062,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 acdccd1a97..a7bd42d2c6 100644
--- a/target/riscv/tcg/op_helper.c
+++ b/target/riscv/tcg/op_helper.c
@@ -152,7 +152,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);
}
--
2.54.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not
affiliated with the servers or forums shown here and is not responsible for
the content of articles, which is written by their respective authors.