@@ -162,6 +162,41 @@ static void kvm_cpu_set_misa_ext_cfg(Object *obj, Visitor *v,
"enabled in the host", misa_ext_cfg->name);
}
+static void kvm_riscv_update_cpu_misa_ext(RISCVCPU *cpu, CPUState *cs)
+{
+ CPURISCVState *env = &cpu->env;
+ uint64_t id, reg;
+ int i, ret;
+
+ for (i = 0; i < ARRAY_SIZE(kvm_misa_ext_cfgs); i++) {
+ KVMCPUConfig *misa_cfg = &kvm_misa_ext_cfgs[i];
+ target_ulong misa_bit = misa_cfg->offset;
+
+ if (!misa_cfg->user_set) {
+ continue;
+ }
+
+ /* If we're here we're going to disable the MISA bit */
+ reg = 0;
+ id = kvm_riscv_reg_id(env, KVM_REG_RISCV_ISA_EXT,
+ misa_cfg->kvm_reg_id);
+ ret = kvm_set_one_reg(cs, id, ®);
+ if (ret != 0) {
+ /*
+ * We're not checking for -EINVAL because if the bit is about
+ * to be disabled, it means that it was already enabled by
+ * KVM. We determined that by fetching the 'isa' register
+ * during init() time. Any error at this point is worth
+ * aborting.
+ */
+ error_report("Unable to set KVM reg %s, error %d",
+ misa_cfg->name, ret);
+ exit(EXIT_FAILURE);
+ }
+ env->misa_ext &= ~misa_bit;
+ }
+}
+
static void kvm_riscv_add_cpu_user_properties(Object *cpu_obj)
{
int i;
@@ -632,8 +667,13 @@ int kvm_arch_init_vcpu(CPUState *cs)
if (!object_dynamic_cast(OBJECT(cpu), TYPE_RISCV_CPU_HOST)) {
ret = kvm_vcpu_set_machine_ids(cpu, cs);
+ if (ret != 0) {
+ return ret;
+ }
}
+ kvm_riscv_update_cpu_misa_ext(cpu, cs);
+
return ret;
}