As a placeholder while SME guests were not supported we provide a u64 in struct kvm_vcpu_arch for the host kernel's floating point save code to use when managing KVM guests. In order to support KVM guests we will need to replace this with a proper KVM system register, do so and update the system register definition to make it accessible to the guest if it has SME.
Signed-off-by: Mark Brown broonie@kernel.org --- arch/arm64/include/asm/kvm_host.h | 2 +- arch/arm64/kvm/fpsimd.c | 8 +++++--- arch/arm64/kvm/sys_regs.c | 2 +- 3 files changed, 7 insertions(+), 5 deletions(-)
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h index 36bf9d7e92e1..690c439b5e2a 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -356,6 +356,7 @@ enum vcpu_sysreg { MDCCINT_EL1, /* Monitor Debug Comms Channel Interrupt Enable Reg */ OSLSR_EL1, /* OS Lock Status Register */ DISR_EL1, /* Deferred Interrupt Status Register */ + SVCR, /* Scalable Vector Control Register */
/* Performance Monitors Registers */ PMCR_EL0, /* Control Register */ @@ -518,7 +519,6 @@ struct kvm_vcpu_arch { void *sve_state; enum fp_type fp_type; unsigned int max_vl[ARM64_VEC_MAX]; - u64 svcr;
/* Stage 2 paging state used by the hardware on next switch */ struct kvm_s2_mmu *hw_mmu; diff --git a/arch/arm64/kvm/fpsimd.c b/arch/arm64/kvm/fpsimd.c index a402a072786a..1be18d719fce 100644 --- a/arch/arm64/kvm/fpsimd.c +++ b/arch/arm64/kvm/fpsimd.c @@ -145,14 +145,16 @@ void kvm_arch_vcpu_ctxsync_fp(struct kvm_vcpu *vcpu) if (vcpu->arch.fp_state == FP_STATE_GUEST_OWNED) {
/* - * Currently we do not support SME guests so SVCR is - * always 0 and we just need a variable to point to. + * We peer into the registers since SVCR is saved as + * part of the floating point state, determining which + * registers exist and their size, so is saved by + * fpsimd_save(). */ fp_state.st = &vcpu->arch.ctxt.fp_regs; fp_state.sve_state = vcpu->arch.sve_state; fp_state.sve_vl = vcpu->arch.max_vl[ARM64_VEC_SVE]; fp_state.sme_state = NULL; - fp_state.svcr = &vcpu->arch.svcr; + fp_state.svcr = &(vcpu->arch.ctxt.sys_regs[SVCR]); fp_state.fp_type = &vcpu->arch.fp_type;
if (vcpu_has_sve(vcpu)) diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c index b618bcab526e..f908aa3fb606 100644 --- a/arch/arm64/kvm/sys_regs.c +++ b/arch/arm64/kvm/sys_regs.c @@ -2336,7 +2336,7 @@ static const struct sys_reg_desc sys_reg_descs[] = { .get_user = get_id_reg, .visibility = sme_visibility }, { SYS_DESC(SYS_CSSELR_EL1), access_csselr, reset_unknown, CSSELR_EL1 }, { SYS_DESC(SYS_CTR_EL0), access_ctr }, - { SYS_DESC(SYS_SVCR), undef_access }, + { SYS_DESC(SYS_SVCR), NULL, reset_val, SVCR, 0, .visibility = sme_visibility },
{ PMU_SYS_REG(PMCR_EL0), .access = access_pmcr, .reset = reset_pmcr, .reg = PMCR_EL0, .get_user = get_pmcr, .set_user = set_pmcr },