From 6a858aa97f684d20e06aa45beefc246d08478816 Mon Sep 17 00:00:00 2001 From: Fuad Tabba Date: Thu, 14 Nov 2024 15:24:18 +0000 Subject: [PATCH] ANDROID: 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 the cptr_el2 value in every vcpu structure. Moreover, trapping depending on whether the guest owns the fp registers cannot be pre-calculated. Change-Id: I309d6f0333174ca3c07e70a3d3c836dd398c8196 Bug: 357781595 Signed-off-by: Fuad Tabba --- arch/arm64/include/asm/kvm_host.h | 1 - arch/arm64/kvm/arm.c | 1 - arch/arm64/kvm/hyp/nvhe/pkvm.c | 43 ----------------------------- arch/arm64/kvm/hyp/nvhe/switch.c | 46 +++++++++++++++++++++---------- 4 files changed, 32 insertions(+), 59 deletions(-) diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h index f7c47d3905fb..4fac97183cd4 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -779,7 +779,6 @@ struct kvm_vcpu_arch { u64 hcr_el2; u64 hcrx_el2; u64 mdcr_el2; - u64 cptr_el2; /* Exception Information */ struct kvm_vcpu_fault_info fault; diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c index 8b1d208e4c2e..b6ea77a97ada 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -1641,7 +1641,6 @@ static int kvm_arch_vcpu_ioctl_vcpu_init(struct kvm_vcpu *vcpu, } vcpu_reset_hcr(vcpu); - vcpu->arch.cptr_el2 = kvm_get_reset_cptr_el2(vcpu); /* * Handle the "start in power-off" case. diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c index 2af4cc680e4a..261424177f0d 100644 --- a/arch/arm64/kvm/hyp/nvhe/pkvm.c +++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c @@ -98,47 +98,6 @@ static void pvm_init_traps_hcr(struct kvm_vcpu *vcpu) vcpu->arch.hcr_el2 &= ~hcr_clear; } -static void pvm_init_traps_cptr(struct kvm_vcpu *vcpu) -{ - struct kvm *kvm = vcpu->kvm; - u64 cptr_clear = 0; - u64 cptr_set = 0; - - if (!has_hvhe()) { - cptr_set |= CPTR_NVHE_EL2_RES1; - cptr_clear |= CPTR_NVHE_EL2_RES0; - } - - if (!kvm_has_feat(kvm, ID_AA64PFR0_EL1, AMU, IMP)) - cptr_set |= CPTR_EL2_TAM; - - /* SVE support can be toggled per-vcpu. */ - if (!vcpu_has_sve(vcpu)) { - if (has_hvhe()) - cptr_clear |= CPACR_ELx_ZEN; - else - cptr_set |= CPTR_EL2_TZ; - } - - /* No SME supprot in KVM. */ - BUG_ON(kvm_has_feat(kvm, ID_AA64PFR1_EL1, SME, IMP)); - if (has_hvhe()) - cptr_clear |= CPACR_ELx_SMEN; - else - cptr_set |= CPTR_EL2_TSM; - - /* Trap Trace */ - if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, TraceVer, IMP)) { - if (has_hvhe()) - cptr_set |= CPACR_EL1_TTA; - else - cptr_set |= CPTR_EL2_TTA; - } - - vcpu->arch.cptr_el2 |= cptr_set; - vcpu->arch.cptr_el2 &= ~cptr_clear; -} - static void pvm_init_traps_mdcr(struct kvm_vcpu *vcpu) { struct kvm *kvm = vcpu->kvm; @@ -212,7 +171,6 @@ static int pkvm_vcpu_init_traps(struct pkvm_hyp_vcpu *hyp_vcpu) struct kvm_vcpu *vcpu = &hyp_vcpu->vcpu; int ret; - vcpu->arch.cptr_el2 = kvm_get_reset_cptr_el2(vcpu); vcpu->arch.mdcr_el2 = 0; pkvm_vcpu_reset_hcr(vcpu); @@ -225,7 +183,6 @@ static int pkvm_vcpu_init_traps(struct pkvm_hyp_vcpu *hyp_vcpu) return ret; pvm_init_traps_hcr(vcpu); - pvm_init_traps_cptr(vcpu); pvm_init_traps_mdcr(vcpu); return 0; diff --git a/arch/arm64/kvm/hyp/nvhe/switch.c b/arch/arm64/kvm/hyp/nvhe/switch.c index 2844d4c9cce9..94fe9365dee2 100644 --- a/arch/arm64/kvm/hyp/nvhe/switch.c +++ b/arch/arm64/kvm/hyp/nvhe/switch.c @@ -108,22 +108,10 @@ static void __deactivate_pvm_traps_hfgxtr(struct kvm_vcpu *vcpu) write_sysreg_s(ctxt_sys_reg(hctxt, HAFGRTR_EL2), SYS_HAFGRTR_EL2); } -static void __activate_traps(struct kvm_vcpu *vcpu) +static void __activate_cptr_traps(struct kvm_vcpu *vcpu) { - u64 val; + u64 val = kvm_get_reset_cptr_el2(vcpu); - ___activate_traps(vcpu, vcpu->arch.hcr_el2); - __activate_traps_common(vcpu); - - if (unlikely(vcpu_is_protected(vcpu))) { - __activate_pvm_traps_hcrx(vcpu); - __activate_pvm_traps_hfgxtr(vcpu); - } else { - __activate_traps_hcrx(vcpu); - __activate_traps_hfgxtr(vcpu); - } - - val = vcpu->arch.cptr_el2; 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)) { @@ -142,7 +130,37 @@ static void __activate_traps(struct kvm_vcpu *vcpu) __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; + } + } + kvm_write_cptr_el2(val); +} + +static void __activate_traps(struct kvm_vcpu *vcpu) +{ + ___activate_traps(vcpu, vcpu->arch.hcr_el2); + __activate_traps_common(vcpu); + __activate_cptr_traps(vcpu); + + if (unlikely(vcpu_is_protected(vcpu))) { + __activate_pvm_traps_hcrx(vcpu); + __activate_pvm_traps_hfgxtr(vcpu); + } else { + __activate_traps_hcrx(vcpu); + __activate_traps_hfgxtr(vcpu); + } + write_sysreg(__this_cpu_read(kvm_hyp_vector), vbar_el2); if (cpus_have_final_cap(ARM64_WORKAROUND_SPECULATIVE_AT)) {