KVM: arm64: Exclude host_fpsimd_state pointer from kvm_vcpu_arch
authorMarc Zyngier <maz@kernel.org>
Fri, 1 Mar 2024 12:06:44 +0000 (12:06 +0000)
committerMarc Zyngier <maz@kernel.org>
Fri, 12 Apr 2024 12:58:31 +0000 (13:58 +0100)
As the name of the field indicates, host_fpsimd_state is strictly
a host piece of data, and we reset this pointer on each PID change.

So let's move it where it belongs, and set it at load-time. Although
this is slightly more often, it is a well defined life-cycle which
matches other pieces of data.

Reviewed-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Marc Zyngier <maz@kernel.org>
arch/arm64/include/asm/kvm_host.h
arch/arm64/kvm/fpsimd.c
arch/arm64/kvm/hyp/include/hyp/switch.h
arch/arm64/kvm/hyp/nvhe/hyp-main.c

index a04e69fb28840fee622bb69c24ea3f5d69f28f61..21730d5ac00630fb61f8d3ea424f95de9d7c19a7 100644 (file)
@@ -543,6 +543,7 @@ struct kvm_cpu_context {
  */
 struct kvm_host_data {
        struct kvm_cpu_context host_ctxt;
+       struct user_fpsimd_state *fpsimd_state; /* hyp VA */
 
        /*
         * host_debug_state contains the host registers which are
@@ -662,7 +663,6 @@ struct kvm_vcpu_arch {
        struct kvm_guest_debug_arch vcpu_debug_state;
        struct kvm_guest_debug_arch external_debug_state;
 
-       struct user_fpsimd_state *host_fpsimd_state;    /* hyp VA */
        struct task_struct *parent_task;
 
        /* VGIC state */
index 826307e19e3a5d8ba7ed7704a7457e66e19d948b..d30dffc800b6a02bf2a16b49d7cfefaabd1916e5 100644 (file)
@@ -49,8 +49,6 @@ int kvm_arch_vcpu_run_map_fp(struct kvm_vcpu *vcpu)
        if (ret)
                return ret;
 
-       vcpu->arch.host_fpsimd_state = kern_hyp_va(fpsimd);
-
        /*
         * We need to keep current's task_struct pinned until its data has been
         * unshared with the hypervisor to make sure it is not re-used by the
@@ -87,6 +85,7 @@ void kvm_arch_vcpu_load_fp(struct kvm_vcpu *vcpu)
         * FP_STATE_FREE if the flag set.
         */
        vcpu->arch.fp_state = FP_STATE_HOST_OWNED;
+       *host_data_ptr(fpsimd_state) = kern_hyp_va(&current->thread.uw.fpsimd_state);
 
        vcpu_clear_flag(vcpu, HOST_SVE_ENABLED);
        if (read_sysreg(cpacr_el1) & CPACR_EL1_ZEN_EL0EN)
index 7d7de0245ed0f317462c3adeb591afc399f522cc..6def6ad8dd483e45d6819db2d3a3ee37c9a64e1e 100644 (file)
@@ -377,7 +377,7 @@ static bool kvm_hyp_handle_fpsimd(struct kvm_vcpu *vcpu, u64 *exit_code)
 
        /* Write out the host state if it's in the registers */
        if (vcpu->arch.fp_state == FP_STATE_HOST_OWNED)
-               __fpsimd_save_state(vcpu->arch.host_fpsimd_state);
+               __fpsimd_save_state(*host_data_ptr(fpsimd_state));
 
        /* Restore the guest state */
        if (sve_guest)
index 2385fd03ed87c6c0450a1c2dbe830e95ce235ecc..c5f625dc1f07efc6e71723c1e8e48c15f90e1ca7 100644 (file)
@@ -42,7 +42,6 @@ static void flush_hyp_vcpu(struct pkvm_hyp_vcpu *hyp_vcpu)
        hyp_vcpu->vcpu.arch.fp_state    = host_vcpu->arch.fp_state;
 
        hyp_vcpu->vcpu.arch.debug_ptr   = kern_hyp_va(host_vcpu->arch.debug_ptr);
-       hyp_vcpu->vcpu.arch.host_fpsimd_state = host_vcpu->arch.host_fpsimd_state;
 
        hyp_vcpu->vcpu.arch.vsesr_el2   = host_vcpu->arch.vsesr_el2;