From 0532339bb0bc75736944382c70780884f7c7df36 Mon Sep 17 00:00:00 2001 From: Fuad Tabba Date: Wed, 22 Mar 2023 13:13:10 +0000 Subject: [PATCH] ANDROID: KVM: arm64: Specialize deactivate fpsimd traps on guest fpsimd trap The code for deactivating traps, to be able to update the fpsimd registers, is the only code in this file that is n/vhe specific. Move it to specialized functions. This is also needed for the subsequent patch, since the logic for deciding which traps to enable/disable will get more complex. No functional change intended. Signed-off-by: Fuad Tabba Bug: 267291591 Change-Id: Ia0477450aa9319a46a91b3c31c1910ad02fbe246 --- arch/arm64/kvm/hyp/include/hyp/switch.h | 17 +++-------------- arch/arm64/kvm/hyp/nvhe/switch.c | 10 ++++++++++ arch/arm64/kvm/hyp/vhe/switch.c | 10 ++++++++++ 3 files changed, 23 insertions(+), 14 deletions(-) diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h index d07eb99a5c97..8ed46a7db619 100644 --- a/arch/arm64/kvm/hyp/include/hyp/switch.h +++ b/arch/arm64/kvm/hyp/include/hyp/switch.h @@ -150,6 +150,8 @@ static inline void __hyp_sve_restore_guest(struct kvm_vcpu *vcpu) static void kvm_hyp_handle_fpsimd_host(struct kvm_vcpu *vcpu); +static void __deactivate_fpsimd_traps(struct kvm_vcpu *vcpu); + /* * We trap the first access to the FP/SIMD to save the host context and * restore the guest context lazily. @@ -160,7 +162,6 @@ static bool kvm_hyp_handle_fpsimd(struct kvm_vcpu *vcpu, u64 *exit_code) { bool sve_guest; u8 esr_ec; - u64 reg; if (!system_supports_fpsimd()) return false; @@ -175,19 +176,7 @@ static bool kvm_hyp_handle_fpsimd(struct kvm_vcpu *vcpu, u64 *exit_code) /* Valid trap. Switch the context: */ /* First disable enough traps to allow us to update the registers */ - if (has_vhe()) { - reg = CPACR_EL1_FPEN_EL0EN | CPACR_EL1_FPEN_EL1EN; - if (sve_guest) - reg |= CPACR_EL1_ZEN_EL0EN | CPACR_EL1_ZEN_EL1EN; - - sysreg_clear_set(cpacr_el1, 0, reg); - } else { - reg = CPTR_EL2_TFP; - if (sve_guest) - reg |= CPTR_EL2_TZ; - - sysreg_clear_set(cptr_el2, reg, 0); - } + __deactivate_fpsimd_traps(vcpu); isb(); /* Write out the host state if it's in the registers */ diff --git a/arch/arm64/kvm/hyp/nvhe/switch.c b/arch/arm64/kvm/hyp/nvhe/switch.c index 0615c57d0f03..553db97cab8e 100644 --- a/arch/arm64/kvm/hyp/nvhe/switch.c +++ b/arch/arm64/kvm/hyp/nvhe/switch.c @@ -108,6 +108,16 @@ static void __deactivate_traps(struct kvm_vcpu *vcpu) write_sysreg(__kvm_hyp_host_vector, vbar_el2); } +static void __deactivate_fpsimd_traps(struct kvm_vcpu *vcpu) +{ + u64 reg = CPTR_EL2_TFP; + + if (vcpu_has_sve(vcpu)) + reg |= CPTR_EL2_TZ; + + sysreg_clear_set(cptr_el2, reg, 0); +} + /* Save VGICv3 state on non-VHE systems */ static void __hyp_vgic_save_state(struct kvm_vcpu *vcpu) { diff --git a/arch/arm64/kvm/hyp/vhe/switch.c b/arch/arm64/kvm/hyp/vhe/switch.c index 53a18f0846e1..055012df3db9 100644 --- a/arch/arm64/kvm/hyp/vhe/switch.c +++ b/arch/arm64/kvm/hyp/vhe/switch.c @@ -102,6 +102,16 @@ void deactivate_traps_vhe_put(struct kvm_vcpu *vcpu) __deactivate_traps_common(vcpu); } +static void __deactivate_fpsimd_traps(struct kvm_vcpu *vcpu) +{ + u64 reg = CPACR_EL1_FPEN_EL0EN | CPACR_EL1_FPEN_EL1EN; + + if (vcpu_has_sve(vcpu)) + reg |= CPACR_EL1_ZEN_EL0EN | CPACR_EL1_ZEN_EL1EN; + + sysreg_clear_set(cpacr_el1, 0, reg); +} + static void kvm_hyp_handle_fpsimd_host(struct kvm_vcpu *vcpu) { __fpsimd_save_state(vcpu->arch.host_fpsimd_state);