On Thu, Oct 27, 2022 at 3:53 PM Mayuresh Chitale <mchit...@ventanamicro.com> wrote: > > Set the state of each ISA extension on the vcpu depending on what > is set in the CPU property and what is allowed by KVM for that extension. > > Signed-off-by: Mayuresh Chitale <mchit...@ventanamicro.com>
Reviewed-by: Alistair Francis <alistair.fran...@wdc.com> Alistair > --- > target/riscv/cpu.c | 11 ++++- > target/riscv/kvm.c | 88 ++++++++++++++++++++++++++++++++++------ > target/riscv/kvm_riscv.h | 2 +- > 3 files changed, 87 insertions(+), 14 deletions(-) > > diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c > index 35320a8547..e52577d59d 100644 > --- a/target/riscv/cpu.c > +++ b/target/riscv/cpu.c > @@ -1191,10 +1191,19 @@ static void riscv_isa_string_ext(RISCVCPU *cpu, char > **isa_str) > { > char *old = *isa_str; > char *new = *isa_str; > - int i; > + int i, offset; > > for (i = 0; i < ARRAY_SIZE(isa_edata_arr); i++) { > if (isa_ext_is_enabled(cpu, &isa_edata_arr[i])) { > + offset = isa_edata_arr[i].ext_enable_offset; > + if (kvm_enabled() && !kvm_riscv_ext_supported(offset)) { > +#ifndef CONFIG_USER_ONLY > + info_report("disabling %s extension for hart 0x%lx because " > + "kvm does not support it", isa_edata_arr[i].name, > + (unsigned long)cpu->env.mhartid); > +#endif > + continue; > + } > if (isa_edata_arr[i].multi_letter) { > if (cpu->cfg.short_isa_string) { > continue; > diff --git a/target/riscv/kvm.c b/target/riscv/kvm.c > index 30f21453d6..ea0715c9e4 100644 > --- a/target/riscv/kvm.c > +++ b/target/riscv/kvm.c > @@ -42,6 +42,29 @@ > #include "migration/migration.h" > #include "sysemu/runstate.h" > > +struct isa_ext_info { > + const char *name; > + target_ulong misa_bit; > + int ext_enable_offset; > +}; > + > +#define ISA_EXT_DATA_ENTRY(_name, _bit, _prop) \ > + {#_name, _bit, offsetof(struct RISCVCPUConfig, _prop)} > + > +static const struct isa_ext_info isa_info_arr[] = { > + ISA_EXT_DATA_ENTRY(a, RVA, ext_a), > + ISA_EXT_DATA_ENTRY(c, RVC, ext_c), > + ISA_EXT_DATA_ENTRY(d, RVD, ext_d), > + ISA_EXT_DATA_ENTRY(f, RVF, ext_f), > + ISA_EXT_DATA_ENTRY(h, RVH, ext_h), > + ISA_EXT_DATA_ENTRY(i, RVI, ext_i), > + ISA_EXT_DATA_ENTRY(m, RVM, ext_m), > + ISA_EXT_DATA_ENTRY(svpbmt, 0, ext_svpbmt), > + ISA_EXT_DATA_ENTRY(sstc, 0, ext_sstc), > + ISA_EXT_DATA_ENTRY(svinval, 0, ext_svinval), > + ISA_EXT_DATA_ENTRY(zihintpause, 0, ext_zihintpause), > +}; > + > static uint64_t kvm_riscv_reg_id(CPURISCVState *env, uint64_t type, > uint64_t idx) > { > @@ -394,25 +417,66 @@ void kvm_arch_init_irq_routing(KVMState *s) > { > } > > +bool kvm_riscv_ext_supported(int offset) > +{ > + int i; > + > + for (i = 0; i < KVM_RISCV_ISA_EXT_MAX; ++i) { > + if (isa_info_arr[i].ext_enable_offset == offset) { > + return true; > + } > + } > + return false; > +} > + > +static void kvm_riscv_set_isa_ext(CPUState *cs, CPURISCVState *env) > +{ > + RISCVCPU *cpu = RISCV_CPU(cs); > + unsigned long isa_ext_out; > + bool *ext_state; > + uint64_t id; > + int i, ret; > + > + env->misa_ext = 0; > + for (i = 0; i < ARRAY_SIZE(isa_info_arr); i++) { > + ext_state = (void *)&cpu->cfg + isa_info_arr[i].ext_enable_offset; > + id = kvm_riscv_reg_id(env, KVM_REG_RISCV_ISA_EXT, i); > + ret = kvm_get_one_reg(cs, id, &isa_ext_out); > + if (ret) { > + warn_report("Disabling ext %s due to failure.", > + isa_info_arr[i].name); > + *ext_state = false; > + continue; > + } > + if (isa_ext_out != (*ext_state)) { > + isa_ext_out = *ext_state; > + ret = kvm_set_one_reg(cs, id, &isa_ext_out); > + if (ret) { > + warn_report("Could not %s ext %s.", > + (isa_ext_out ? "enable" : "disable"), > + isa_info_arr[i].name); > + *ext_state = !isa_ext_out; > + } > + } > + /* > + * If the sigle letter extension is supported by KVM then set > + * the corresponding misa bit for the guest vcpu. > + */ > + if (isa_info_arr[i].misa_bit && (*ext_state)) { > + env->misa_ext |= isa_info_arr[i].misa_bit; > + } > + } > +} > + > int kvm_arch_init_vcpu(CPUState *cs) > { > - int ret = 0; > - target_ulong isa; > RISCVCPU *cpu = RISCV_CPU(cs); > CPURISCVState *env = &cpu->env; > - uint64_t id; > > qemu_add_vm_change_state_handler(kvm_riscv_vm_state_change, cs); > > - id = kvm_riscv_reg_id(env, KVM_REG_RISCV_CONFIG, > - KVM_REG_RISCV_CONFIG_REG(isa)); > - ret = kvm_get_one_reg(cs, id, &isa); > - if (ret) { > - return ret; > - } > - env->misa_ext = isa; > - > - return ret; > + kvm_riscv_set_isa_ext(cs, env); > + return 0; > } > > int kvm_arch_msi_data_to_gsi(uint32_t data) > diff --git a/target/riscv/kvm_riscv.h b/target/riscv/kvm_riscv.h > index ed281bdce0..bdcccc0da4 100644 > --- a/target/riscv/kvm_riscv.h > +++ b/target/riscv/kvm_riscv.h > @@ -21,5 +21,5 @@ > > void kvm_riscv_reset_vcpu(RISCVCPU *cpu); > void kvm_riscv_set_irq(RISCVCPU *cpu, int irq, int level); > - > +bool kvm_riscv_ext_supported(int offset); > #endif > -- > 2.34.1 > >