summaryrefslogtreecommitdiffstats
path: root/arch/arm64/kvm/fpsimd.c
diff options
context:
space:
mode:
authorMarc Zyngier <maz@kernel.org>2021-03-11 18:29:55 +0000
committerMarc Zyngier <maz@kernel.org>2021-03-18 14:23:12 +0000
commit8c8010d69c1322734a272eb95dbbf42b5190e565 (patch)
treeb67366c7598da31074f57b7de4e569fff294dde7 /arch/arm64/kvm/fpsimd.c
parentbeed09067b428a7e84a53b05c1de1f93c8460e91 (diff)
downloadlinux-stable-8c8010d69c1322734a272eb95dbbf42b5190e565.tar.gz
linux-stable-8c8010d69c1322734a272eb95dbbf42b5190e565.tar.bz2
linux-stable-8c8010d69c1322734a272eb95dbbf42b5190e565.zip
KVM: arm64: Save/restore SVE state for nVHE
Implement the SVE save/restore for nVHE, following a similar logic to that of the VHE implementation: - the SVE state is switched on trap from EL1 to EL2 - no further changes to ZCR_EL2 occur as long as the guest isn't preempted or exit to userspace - ZCR_EL2 is reset to its default value on the first SVE access from the host EL1, and ZCR_EL1 restored to the default guest value in vcpu_put() Acked-by: Will Deacon <will@kernel.org> Signed-off-by: Marc Zyngier <maz@kernel.org>
Diffstat (limited to 'arch/arm64/kvm/fpsimd.c')
-rw-r--r--arch/arm64/kvm/fpsimd.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/arch/arm64/kvm/fpsimd.c b/arch/arm64/kvm/fpsimd.c
index 14ea05c5134a..5621020b28de 100644
--- a/arch/arm64/kvm/fpsimd.c
+++ b/arch/arm64/kvm/fpsimd.c
@@ -121,11 +121,17 @@ void kvm_arch_vcpu_put_fp(struct kvm_vcpu *vcpu)
local_irq_save(flags);
if (vcpu->arch.flags & KVM_ARM64_FP_ENABLED) {
- if (guest_has_sve)
+ if (guest_has_sve) {
__vcpu_sys_reg(vcpu, ZCR_EL1) = read_sysreg_el1(SYS_ZCR);
+ /* Restore the VL that was saved when bound to the CPU */
+ if (!has_vhe())
+ sve_cond_update_zcr_vq(vcpu_sve_max_vq(vcpu) - 1,
+ SYS_ZCR_EL1);
+ }
+
fpsimd_save_and_flush_cpu_state();
- } else if (host_has_sve) {
+ } else if (has_vhe() && host_has_sve) {
/*
* The FPSIMD/SVE state in the CPU has not been touched, and we
* have SVE (and VHE): CPACR_EL1 (alias CPTR_EL2) has been