From 476f56087fd1cf3be2604f7498817af8bb6a569b Mon Sep 17 00:00:00 2001 From: Fuad Tabba Date: Mon, 13 Jan 2025 10:47:39 +0000 Subject: [PATCH] BACKPORT: FROMGIT: KVM: arm64: Calculate cptr_el2 traps on activating traps Similar to VHE, calculate the value of cptr_el2 from scratch on activate traps. This removes the need to store cptr_el2 in every vcpu structure. Moreover, some traps, such as whether the guest owns the fp registers, need to be set on every vcpu run. Bug: 357781595 Link: https://lore.kernel.org/all/20241216105057.579031-13-tabba@google.com/ (cherry picked from commit 2fd5b4b0e7b440602455b79977bfa64dea101e6c https://git.kernel.org/pub/scm/linux/kernel/git/kvmarm/kvmarm.git/ next) [tabba@: partial backport of missing changes] Reported-by: James Clark Fixes: 5294afdbf45a ("KVM: arm64: Exclude FP ownership from kvm_vcpu_arch") Change-Id: I7ad7b0ded7b4dd8a0d2b074a845fc6a983cbe8f9 Signed-off-by: Fuad Tabba --- arch/arm64/kvm/hyp/nvhe/switch.c | 53 +++++++++++++++----------------- 1 file changed, 24 insertions(+), 29 deletions(-) diff --git a/arch/arm64/kvm/hyp/nvhe/switch.c b/arch/arm64/kvm/hyp/nvhe/switch.c index 197fef06f88c..309c8c210151 100644 --- a/arch/arm64/kvm/hyp/nvhe/switch.c +++ b/arch/arm64/kvm/hyp/nvhe/switch.c @@ -110,40 +110,35 @@ static void __deactivate_pvm_traps_hfgxtr(struct kvm_vcpu *vcpu) static void __activate_cptr_traps(struct kvm_vcpu *vcpu) { - u64 val = kvm_get_reset_cptr_el2(vcpu); + u64 val = CPTR_EL2_TAM; /* Same bit irrespective of E2H */ - val |= CPTR_EL2_TAM; /* Same bit irrespective of E2H */ - val |= has_hvhe() ? CPACR_EL1_TTA : CPTR_EL2_TTA; - if (cpus_have_final_cap(ARM64_SME)) { - if (has_hvhe()) - val &= ~CPACR_ELx_SMEN; - else - val |= CPTR_EL2_TSM; - } + if (has_hvhe()) { + val |= CPACR_ELx_TTA; - if (!guest_owns_fp_regs()) { - if (has_hvhe()) - val &= ~(CPACR_ELx_FPEN | CPACR_ELx_ZEN); - else - val |= CPTR_EL2_TFP | CPTR_EL2_TZ; - - __activate_traps_fpsimd32(vcpu); - } - - if (vcpu_is_protected(vcpu)) { - struct kvm *kvm = vcpu->kvm; - - if (!kvm_has_feat(kvm, ID_AA64PFR0_EL1, AMU, IMP)) - val |= CPTR_EL2_TAM; - - if (!vcpu_has_sve(vcpu)) { - if (has_hvhe()) - val &= ~CPACR_ELx_ZEN; - else - val |= CPTR_EL2_TZ; + if (guest_owns_fp_regs()) { + val |= CPACR_ELx_FPEN; + if (vcpu_has_sve(vcpu)) + val |= CPACR_ELx_ZEN; } + } else { + val |= CPTR_EL2_TTA | CPTR_NVHE_EL2_RES1; + + /* + * Always trap SME since it's not supported in KVM. + * TSM is RES1 if SME isn't implemented. + */ + val |= CPTR_EL2_TSM; + + if (!vcpu_has_sve(vcpu) || !guest_owns_fp_regs()) + val |= CPTR_EL2_TZ; + + if (!guest_owns_fp_regs()) + val |= CPTR_EL2_TFP; } + if (!guest_owns_fp_regs()) + __activate_traps_fpsimd32(vcpu); + kvm_write_cptr_el2(val); }