This function will validate and change/disable extensions that aren't
compatible with a certain spec version. Since the function is called
at the start of riscv_cpu_validate_set_extensions(), we're disabling
extensions without guaranteeing that they aren't being turned on again
after the validation step.
Create a new riscv_cpu_disable_priv_spec_isa_exts() helper and call it
at the end of riscv_cpu_validate_set_extensions(), right before
re-calculating the misa_ext value with the current config. This will
ensure that we're not re-enabling extensions that should be disabled by
the spec rula by accident.
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
---
target/riscv/cpu.c | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index a564de01df..49f0fd2c11 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -942,7 +942,7 @@ static void riscv_cpu_validate_v(CPURISCVState *env, RISCVCPUConfig *cfg,
static void riscv_cpu_validate_priv_spec(RISCVCPU *cpu, Error **errp)
{
CPURISCVState *env = &cpu->env;
- int i, priv_version = -1;
+ int priv_version = -1;
if (cpu->cfg.priv_spec) {
if (!g_strcmp0(cpu->cfg.priv_spec, "v1.12.0")) {
@@ -962,6 +962,12 @@ static void riscv_cpu_validate_priv_spec(RISCVCPU *cpu, Error **errp)
if (priv_version >= PRIV_VERSION_1_10_0) {
env->priv_ver = priv_version;
}
+}
+
+static void riscv_cpu_disable_priv_spec_isa_exts(RISCVCPU *cpu)
+{
+ CPURISCVState *env = &cpu->env;
+ int i;
/* Force disable extensions if priv spec version does not match */
for (i = 0; i < ARRAY_SIZE(isa_edata_arr); i++) {
@@ -1183,6 +1189,12 @@ static void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
cpu->cfg.ext_zksh = true;
}
+ /*
+ * Disable isa extensions based on priv spec after we
+ * validated and set everything we need.
+ */
+ riscv_cpu_disable_priv_spec_isa_exts(cpu);
+
ext = riscv_get_misa_ext_with_cpucfg(&cpu->cfg);
env->misa_ext_mask = env->misa_ext = ext;
--
2.39.2