From 0dcae57ee0711f4ff1d340ceb8d5baa4f324cb48 Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Thu, 7 Jul 2022 15:51:36 +0100 Subject: [PATCH] Revert "ANDROID: KVM: arm64: pkvm: Lazy host FP save/restore" This reverts commit dc2fae63383a281d470dcbc95e9b29ca1d2c1a1f. Bug: 233587962 Signed-off-by: Will Deacon Change-Id: Ie48002bf23295cf0bc9177837024002445263b07 --- arch/arm64/kvm/hyp/nvhe/hyp-main.c | 72 +++++------------------------- 1 file changed, 10 insertions(+), 62 deletions(-) diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c index f53a9bd97e73..6c6a9be69290 100644 --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c @@ -337,43 +337,12 @@ static void sync_shadow_state(struct kvm_vcpu *shadow_vcpu, u32 exit_reason) struct pkvm_loaded_state { /* loaded vcpu is HYP VA */ - struct kvm_vcpu *vcpu; - bool is_shadow; - - /* - * Host FPSIMD state. Written to when the guest accesses its - * own FPSIMD state, and read when the guest state is live and - * that it needs to be switched back to the host. - * - * Only valid when the KVM_ARM64_FP_ENABLED flag is set in the - * shadow structure. - */ - struct user_fpsimd_state host_fpsimd_state; + struct kvm_vcpu *vcpu; + bool is_shadow; }; static DEFINE_PER_CPU(struct pkvm_loaded_state, loaded_state); -static void fpsimd_host_restore(void) -{ - sysreg_clear_set(cptr_el2, CPTR_EL2_TZ | CPTR_EL2_TFP, 0); - isb(); - - if (unlikely(is_protected_kvm_enabled())) { - struct pkvm_loaded_state *state = this_cpu_ptr(&loaded_state); - - if (state->is_shadow) { - __fpsimd_save_state(&state->vcpu->arch.ctxt.fp_regs); - __fpsimd_restore_state(&state->host_fpsimd_state); - - state->vcpu->arch.flags &= ~KVM_ARM64_FP_ENABLED; - state->vcpu->arch.flags |= KVM_ARM64_FP_HOST; - } - } - - if (system_supports_sve()) - sve_cond_update_zcr_vq(ZCR_ELx_LEN_MASK, SYS_ZCR_EL2); -} - static void handle___pkvm_vcpu_load(struct kvm_cpu_context *host_ctxt) { DECLARE_REG(struct kvm_vcpu *, vcpu, host_ctxt, 1); @@ -395,8 +364,8 @@ static void handle___pkvm_vcpu_load(struct kvm_cpu_context *host_ctxt) state->is_shadow = state->vcpu != vcpu; if (state->is_shadow) { - state->vcpu->arch.host_fpsimd_state = &state->host_fpsimd_state; - state->vcpu->arch.flags |= KVM_ARM64_FP_HOST; + /* FIXME: we can't trust the validity of these pointers */ + state->vcpu->arch.host_fpsimd_state = vcpu->arch.host_fpsimd_state; /* Propagate WFx trapping flags, trap ptrauth */ state->vcpu->arch.hcr_el2 &= ~(HCR_TWE | HCR_TWI | @@ -407,20 +376,10 @@ static void handle___pkvm_vcpu_load(struct kvm_cpu_context *host_ctxt) static void handle___pkvm_vcpu_put(struct kvm_cpu_context *host_ctxt) { - DECLARE_REG(struct kvm_vcpu *, vcpu, host_ctxt, 1); + struct pkvm_loaded_state *state = this_cpu_ptr(&loaded_state); - if (unlikely(is_protected_kvm_enabled())) { - struct pkvm_loaded_state *state = this_cpu_ptr(&loaded_state); - - if (state->vcpu && state->is_shadow && - state->vcpu->arch.pkvm.host_vcpu == kern_hyp_va(vcpu)) { - if (state->vcpu->arch.flags & KVM_ARM64_FP_ENABLED) - fpsimd_host_restore(); - - /* "It's over and done with..." */ - state->vcpu = NULL; - } - } + /* "It's over and done with..." */ + state->vcpu = NULL; } static void handle___kvm_vcpu_run(struct kvm_cpu_context *host_ctxt) @@ -438,18 +397,6 @@ static void handle___kvm_vcpu_run(struct kvm_cpu_context *host_ctxt) if (state->is_shadow) sync_shadow_state(state->vcpu, ret); - - if (state->vcpu->arch.flags & KVM_ARM64_FP_ENABLED) { - /* - * The guest has used the FP, trap all accesses - * from the host (both FP and SVE). - */ - u64 reg = CPTR_EL2_TFP; - if (system_supports_sve()) - reg |= CPTR_EL2_TZ; - - sysreg_clear_set(cptr_el2, 0, reg); - } } else { ret = __kvm_vcpu_run(kern_hyp_va(vcpu)); } @@ -775,9 +722,10 @@ void handle_trap(struct kvm_cpu_context *host_ctxt) case ESR_ELx_EC_SMC64: handle_host_smc(host_ctxt); break; - case ESR_ELx_EC_FP_ASIMD: case ESR_ELx_EC_SVE: - fpsimd_host_restore(); + sysreg_clear_set(cptr_el2, CPTR_EL2_TZ, 0); + isb(); + sve_cond_update_zcr_vq(ZCR_ELx_LEN_MASK, SYS_ZCR_EL2); break; case ESR_ELx_EC_IABT_LOW: case ESR_ELx_EC_DABT_LOW: