]> Git Repo - J-linux.git/commitdiff
KVM: arm64: Exclude FP ownership from kvm_vcpu_arch
authorMarc Zyngier <[email protected]>
Fri, 1 Mar 2024 17:42:31 +0000 (17:42 +0000)
committerMarc Zyngier <[email protected]>
Fri, 12 Apr 2024 12:58:59 +0000 (13:58 +0100)
In retrospect, it is fairly obvious that the FP state ownership
is only meaningful for a given CPU, and that locating this
information in the vcpu was just a mistake.

Move the ownership tracking into the host data structure, and
rename it from fp_state to fp_owner, which is a better description
(name suggested by Mark Brown).

Reviewed-by: Mark Brown <[email protected]>
Signed-off-by: Marc Zyngier <[email protected]>
arch/arm64/include/asm/kvm_emulate.h
arch/arm64/include/asm/kvm_host.h
arch/arm64/kvm/arm.c
arch/arm64/kvm/fpsimd.c
arch/arm64/kvm/hyp/include/hyp/switch.h
arch/arm64/kvm/hyp/nvhe/hyp-main.c
arch/arm64/kvm/hyp/nvhe/switch.c
arch/arm64/kvm/hyp/vhe/switch.c

index 975af30af31fa239524ccd5a52aa453e8675835d..3d65d9413608f3aa88e7621f422f77aae0f5442c 100644 (file)
@@ -588,7 +588,7 @@ static __always_inline u64 kvm_get_reset_cptr_el2(struct kvm_vcpu *vcpu)
                val = (CPACR_EL1_FPEN_EL0EN | CPACR_EL1_FPEN_EL1EN);
 
                if (!vcpu_has_sve(vcpu) ||
-                   (vcpu->arch.fp_state != FP_STATE_GUEST_OWNED))
+                   (*host_data_ptr(fp_owner) != FP_STATE_GUEST_OWNED))
                        val |= CPACR_EL1_ZEN_EL1EN | CPACR_EL1_ZEN_EL0EN;
                if (cpus_have_final_cap(ARM64_SME))
                        val |= CPACR_EL1_SMEN_EL1EN | CPACR_EL1_SMEN_EL0EN;
@@ -596,7 +596,7 @@ static __always_inline u64 kvm_get_reset_cptr_el2(struct kvm_vcpu *vcpu)
                val = CPTR_NVHE_EL2_RES1;
 
                if (vcpu_has_sve(vcpu) &&
-                   (vcpu->arch.fp_state == FP_STATE_GUEST_OWNED))
+                   (*host_data_ptr(fp_owner) == FP_STATE_GUEST_OWNED))
                        val |= CPTR_EL2_TZ;
                if (cpus_have_final_cap(ARM64_SME))
                        val &= ~CPTR_EL2_TSM;
index 21730d5ac00630fb61f8d3ea424f95de9d7c19a7..2b63fdfad5b28d96cf9d987f0731784a6f0ca14a 100644 (file)
@@ -545,6 +545,13 @@ struct kvm_host_data {
        struct kvm_cpu_context host_ctxt;
        struct user_fpsimd_state *fpsimd_state; /* hyp VA */
 
+       /* Ownership of the FP regs */
+       enum {
+               FP_STATE_FREE,
+               FP_STATE_HOST_OWNED,
+               FP_STATE_GUEST_OWNED,
+       } fp_owner;
+
        /*
         * host_debug_state contains the host registers which are
         * saved and restored during world switches.
@@ -622,13 +629,6 @@ struct kvm_vcpu_arch {
        /* Exception Information */
        struct kvm_vcpu_fault_info fault;
 
-       /* Ownership of the FP regs */
-       enum {
-               FP_STATE_FREE,
-               FP_STATE_HOST_OWNED,
-               FP_STATE_GUEST_OWNED,
-       } fp_state;
-
        /* Configuration flags, set once and for all before the vcpu can run */
        u8 cflags;
 
index a24287c3ba9912d444e08dfe7c20c73cd53df206..66d8112da26802c45e840b3cfcf237efed401ba4 100644 (file)
@@ -378,12 +378,6 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu)
 
        vcpu->arch.mmu_page_cache.gfp_zero = __GFP_ZERO;
 
-       /*
-        * Default value for the FP state, will be overloaded at load
-        * time if we support FP (pretty likely)
-        */
-       vcpu->arch.fp_state = FP_STATE_FREE;
-
        /* Set up the timer */
        kvm_timer_vcpu_init(vcpu);
 
index d30dffc800b6a02bf2a16b49d7cfefaabd1916e5..7507dcc4e553bbb9bac54059535e1500e9c187c1 100644 (file)
@@ -84,7 +84,7 @@ void kvm_arch_vcpu_load_fp(struct kvm_vcpu *vcpu)
         * guest in kvm_arch_vcpu_ctxflush_fp() and override this to
         * FP_STATE_FREE if the flag set.
         */
-       vcpu->arch.fp_state = FP_STATE_HOST_OWNED;
+       *host_data_ptr(fp_owner) = FP_STATE_HOST_OWNED;
        *host_data_ptr(fpsimd_state) = kern_hyp_va(&current->thread.uw.fpsimd_state);
 
        vcpu_clear_flag(vcpu, HOST_SVE_ENABLED);
@@ -109,7 +109,7 @@ void kvm_arch_vcpu_load_fp(struct kvm_vcpu *vcpu)
                 * been saved, this is very unlikely to happen.
                 */
                if (read_sysreg_s(SYS_SVCR) & (SVCR_SM_MASK | SVCR_ZA_MASK)) {
-                       vcpu->arch.fp_state = FP_STATE_FREE;
+                       *host_data_ptr(fp_owner) = FP_STATE_FREE;
                        fpsimd_save_and_flush_cpu_state();
                }
        }
@@ -125,7 +125,7 @@ void kvm_arch_vcpu_load_fp(struct kvm_vcpu *vcpu)
 void kvm_arch_vcpu_ctxflush_fp(struct kvm_vcpu *vcpu)
 {
        if (test_thread_flag(TIF_FOREIGN_FPSTATE))
-               vcpu->arch.fp_state = FP_STATE_FREE;
+               *host_data_ptr(fp_owner) = FP_STATE_FREE;
 }
 
 /*
@@ -141,7 +141,7 @@ void kvm_arch_vcpu_ctxsync_fp(struct kvm_vcpu *vcpu)
 
        WARN_ON_ONCE(!irqs_disabled());
 
-       if (vcpu->arch.fp_state == FP_STATE_GUEST_OWNED) {
+       if (*host_data_ptr(fp_owner) == FP_STATE_GUEST_OWNED) {
 
                /*
                 * Currently we do not support SME guests so SVCR is
@@ -195,7 +195,7 @@ void kvm_arch_vcpu_put_fp(struct kvm_vcpu *vcpu)
                isb();
        }
 
-       if (vcpu->arch.fp_state == FP_STATE_GUEST_OWNED) {
+       if (*host_data_ptr(fp_owner) == FP_STATE_GUEST_OWNED) {
                if (vcpu_has_sve(vcpu)) {
                        __vcpu_sys_reg(vcpu, ZCR_EL1) = read_sysreg_el1(SYS_ZCR);
 
index 6def6ad8dd483e45d6819db2d3a3ee37c9a64e1e..2629420d0659d9f5ddc7670571a623106e39bb96 100644 (file)
@@ -42,7 +42,7 @@ extern struct kvm_exception_table_entry __stop___kvm_ex_table;
 /* Check whether the FP regs are owned by the guest */
 static inline bool guest_owns_fp_regs(struct kvm_vcpu *vcpu)
 {
-       return vcpu->arch.fp_state == FP_STATE_GUEST_OWNED;
+       return *host_data_ptr(fp_owner) == FP_STATE_GUEST_OWNED;
 }
 
 /* Save the 32-bit only FPSIMD system register state */
@@ -376,7 +376,7 @@ static bool kvm_hyp_handle_fpsimd(struct kvm_vcpu *vcpu, u64 *exit_code)
        isb();
 
        /* Write out the host state if it's in the registers */
-       if (vcpu->arch.fp_state == FP_STATE_HOST_OWNED)
+       if (*host_data_ptr(fp_owner) == FP_STATE_HOST_OWNED)
                __fpsimd_save_state(*host_data_ptr(fpsimd_state));
 
        /* Restore the guest state */
@@ -389,7 +389,7 @@ static bool kvm_hyp_handle_fpsimd(struct kvm_vcpu *vcpu, u64 *exit_code)
        if (!(read_sysreg(hcr_el2) & HCR_RW))
                write_sysreg(__vcpu_sys_reg(vcpu, FPEXC32_EL2), fpexc32_el2);
 
-       vcpu->arch.fp_state = FP_STATE_GUEST_OWNED;
+       *host_data_ptr(fp_owner) = FP_STATE_GUEST_OWNED;
 
        return true;
 }
index c5f625dc1f07efc6e71723c1e8e48c15f90e1ca7..26561c562f7a2333ea755bbd270ebb7c755bd0ec 100644 (file)
@@ -39,7 +39,6 @@ static void flush_hyp_vcpu(struct pkvm_hyp_vcpu *hyp_vcpu)
        hyp_vcpu->vcpu.arch.cptr_el2    = host_vcpu->arch.cptr_el2;
 
        hyp_vcpu->vcpu.arch.iflags      = host_vcpu->arch.iflags;
-       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);
 
@@ -63,7 +62,6 @@ static void sync_hyp_vcpu(struct pkvm_hyp_vcpu *hyp_vcpu)
        host_vcpu->arch.fault           = hyp_vcpu->vcpu.arch.fault;
 
        host_vcpu->arch.iflags          = hyp_vcpu->vcpu.arch.iflags;
-       host_vcpu->arch.fp_state        = hyp_vcpu->vcpu.arch.fp_state;
 
        host_cpu_if->vgic_hcr           = hyp_cpu_if->vgic_hcr;
        for (i = 0; i < hyp_cpu_if->used_lrs; ++i)
index 544a419b9a39534557def0d059c32f0707abb375..1f82d531a4945de77a631a74d9076e760ade633d 100644 (file)
@@ -337,7 +337,7 @@ int __kvm_vcpu_run(struct kvm_vcpu *vcpu)
 
        __sysreg_restore_state_nvhe(host_ctxt);
 
-       if (vcpu->arch.fp_state == FP_STATE_GUEST_OWNED)
+       if (*host_data_ptr(fp_owner) == FP_STATE_GUEST_OWNED)
                __fpsimd_save_fpexc32(vcpu);
 
        __debug_switch_to_host(vcpu);
index 14b7a6bc590907d8d3b6d4d3cfc809a385ab20cc..b92f9fe2d50e92a0d416546f3da186448736c967 100644 (file)
@@ -258,7 +258,7 @@ static int __kvm_vcpu_run_vhe(struct kvm_vcpu *vcpu)
 
        sysreg_restore_host_state_vhe(host_ctxt);
 
-       if (vcpu->arch.fp_state == FP_STATE_GUEST_OWNED)
+       if (*host_data_ptr(fp_owner) == FP_STATE_GUEST_OWNED)
                __fpsimd_save_fpexc32(vcpu);
 
        __debug_switch_to_host(vcpu);
This page took 0.061081 seconds and 4 git commands to generate.