The kernel had already support LSX and LASX [1], but QEMU is disable LSX/LASX for kvm. This patch adds kvm_check_cpucfg to check CPUCFG2.
[1]: https://lore.kernel.org/all/cabgobfzhrf7e_7jk4uprmsyxty3eiuuywhc35jqncnl9s-z...@mail.gmail.com/ Signed-off-by: Song Gao <gaos...@loongson.cn> --- linux-headers/asm-loongarch/kvm.h | 1 + target/loongarch/kvm/kvm.c | 35 ++++++++++++++++++++++++------- 2 files changed, 29 insertions(+), 7 deletions(-) diff --git a/linux-headers/asm-loongarch/kvm.h b/linux-headers/asm-loongarch/kvm.h index c6ad2ee610..923d0bd382 100644 --- a/linux-headers/asm-loongarch/kvm.h +++ b/linux-headers/asm-loongarch/kvm.h @@ -79,6 +79,7 @@ struct kvm_fpu { #define LOONGARCH_REG_64(TYPE, REG) (TYPE | KVM_REG_SIZE_U64 | (REG << LOONGARCH_REG_SHIFT)) #define KVM_IOC_CSRID(REG) LOONGARCH_REG_64(KVM_REG_LOONGARCH_CSR, REG) #define KVM_IOC_CPUCFG(REG) LOONGARCH_REG_64(KVM_REG_LOONGARCH_CPUCFG, REG) +#define KVM_LOONGARCH_VCPU_CPUCFG 0 struct kvm_debug_exit_arch { }; diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c index 84bcdf5f86..41b6947c7b 100644 --- a/target/loongarch/kvm/kvm.c +++ b/target/loongarch/kvm/kvm.c @@ -537,6 +537,28 @@ static int kvm_loongarch_get_cpucfg(CPUState *cs) return ret; } +static int kvm_check_cpucfg(int id, CPUState *cs) +{ + int ret; + uint64_t val; + struct kvm_device_attr attr = { + .group = KVM_LOONGARCH_VCPU_CPUCFG, + .attr = id, + .addr = (uint64_t)&val, + }; + LoongArchCPU *cpu = LOONGARCH_CPU(cs); + CPULoongArchState *env = &cpu->env; + + ret = kvm_vcpu_ioctl(cs, KVM_HAS_DEVICE_ATTR, &attr); + + if (!ret) { + kvm_vcpu_ioctl(cs, KVM_GET_DEVICE_ATTR, &attr); + env->cpucfg[id] &= val; + } + + return ret; +} + static int kvm_loongarch_put_cpucfg(CPUState *cs) { int i, ret = 0; @@ -545,14 +567,13 @@ static int kvm_loongarch_put_cpucfg(CPUState *cs) uint64_t val; for (i = 0; i < 21; i++) { + if (i == 2) { + ret = kvm_check_cpucfg(i, cs); + if (ret) { + return ret; + } + } val = env->cpucfg[i]; - /* LSX and LASX and LBT are not supported in kvm now */ - if (i == 2) { - val &= ~(BIT(R_CPUCFG2_LSX_SHIFT) | BIT(R_CPUCFG2_LASX_SHIFT)); - val &= ~(BIT(R_CPUCFG2_LBT_X86_SHIFT) | - BIT(R_CPUCFG2_LBT_ARM_SHIFT) | - BIT(R_CPUCFG2_LBT_MIPS_SHIFT)); - } ret = kvm_set_one_reg(cs, KVM_IOC_CPUCFG(i), &val); if (ret < 0) { trace_kvm_failed_put_cpucfg(strerror(errno)); -- 2.25.1