]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
KVM: arm64: Remove host FPSIMD saving for non-protected KVM
authorMark Rutland <mark.rutland@arm.com>
Fri, 21 Mar 2025 00:10:12 +0000 (00:10 +0000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 28 Mar 2025 21:04:58 +0000 (22:04 +0100)
[ Upstream commit 8eca7f6d5100b6997df4f532090bc3f7e0203bef ]

Now that the host eagerly saves its own FPSIMD/SVE/SME state,
non-protected KVM never needs to save the host FPSIMD/SVE/SME state,
and the code to do this is never used. Protected KVM still needs to
save/restore the host FPSIMD/SVE state to avoid leaking guest state to
the host (and to avoid revealing to the host whether the guest used
FPSIMD/SVE/SME), and that code needs to be retained.

Remove the unused code and data structures.

To avoid the need for a stub copy of kvm_hyp_save_fpsimd_host() in the
VHE hyp code, the nVHE/hVHE version is moved into the shared switch
header, where it is only invoked when KVM is in protected mode.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Reviewed-by: Mark Brown <broonie@kernel.org>
Tested-by: Mark Brown <broonie@kernel.org>
Acked-by: Will Deacon <will@kernel.org>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Fuad Tabba <tabba@google.com>
Cc: Marc Zyngier <maz@kernel.org>
Cc: Oliver Upton <oliver.upton@linux.dev>
Reviewed-by: Oliver Upton <oliver.upton@linux.dev>
Link: https://lore.kernel.org/r/20250210195226.1215254-3-mark.rutland@arm.com
Signed-off-by: Marc Zyngier <maz@kernel.org>
[CPACR_EL1_ZEN -> CPACR_ELx_ZEN -- broonie]
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
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 6762dadce45deb657b6e8df3e14dc9fbef884f1d..0b39888e86d6d40fea56bb6cb8ccdbaf480d0d55 100644 (file)
@@ -613,23 +613,13 @@ struct kvm_host_data {
        struct kvm_cpu_context host_ctxt;
 
        /*
-        * All pointers in this union are hyp VA.
+        * Hyp VA.
         * sve_state is only used in pKVM and if system_supports_sve().
         */
-       union {
-               struct user_fpsimd_state *fpsimd_state;
-               struct cpu_sve_state *sve_state;
-       };
-
-       union {
-               /* HYP VA pointer to the host storage for FPMR */
-               u64     *fpmr_ptr;
-               /*
-                * Used by pKVM only, as it needs to provide storage
-                * for the host
-                */
-               u64     fpmr;
-       };
+       struct cpu_sve_state *sve_state;
+
+       /* Used by pKVM only. */
+       u64     fpmr;
 
        /* Ownership of the FP regs */
        enum {
index 591f512ab072963424f4b2287a1a572fc72bd639..78acbd589968771674f6cecaea6d9254eaeb6b8a 100644 (file)
@@ -2468,14 +2468,6 @@ static void finalize_init_hyp_mode(void)
                        per_cpu_ptr_nvhe_sym(kvm_host_data, cpu)->sve_state =
                                kern_hyp_va(sve_state);
                }
-       } else {
-               for_each_possible_cpu(cpu) {
-                       struct user_fpsimd_state *fpsimd_state;
-
-                       fpsimd_state = &per_cpu_ptr_nvhe_sym(kvm_host_data, cpu)->host_ctxt.fp_regs;
-                       per_cpu_ptr_nvhe_sym(kvm_host_data, cpu)->fpsimd_state =
-                               kern_hyp_va(fpsimd_state);
-               }
        }
 }
 
index efb54ed60fe1d1d8a904b10a4a4bd3c820d9dac5..2ee6bde85235581d6bc9cba7e578c55875b5d5a1 100644 (file)
@@ -64,8 +64,6 @@ void kvm_arch_vcpu_load_fp(struct kvm_vcpu *vcpu)
         */
        fpsimd_save_and_flush_cpu_state();
        *host_data_ptr(fp_owner) = FP_STATE_FREE;
-       *host_data_ptr(fpsimd_state) = NULL;
-       *host_data_ptr(fpmr_ptr) = NULL;
 
        vcpu_clear_flag(vcpu, HOST_SVE_ENABLED);
        if (read_sysreg(cpacr_el1) & CPACR_EL1_ZEN_EL0EN)
index 34f53707892dfe7bba41620e7adb65f1f8376018..7601d741bc2ae77ca9f359e4901926a5feac48b9 100644 (file)
@@ -375,7 +375,28 @@ static inline void __hyp_sve_save_host(void)
                         true);
 }
 
-static void kvm_hyp_save_fpsimd_host(struct kvm_vcpu *vcpu);
+static void kvm_hyp_save_fpsimd_host(struct kvm_vcpu *vcpu)
+{
+       /*
+        * Non-protected kvm relies on the host restoring its sve state.
+        * Protected kvm restores the host's sve state as not to reveal that
+        * fpsimd was used by a guest nor leak upper sve bits.
+        */
+       if (system_supports_sve()) {
+               __hyp_sve_save_host();
+
+               /* Re-enable SVE traps if not supported for the guest vcpu. */
+               if (!vcpu_has_sve(vcpu))
+                       cpacr_clear_set(CPACR_ELx_ZEN, 0);
+
+       } else {
+               __fpsimd_save_state(host_data_ptr(host_ctxt.fp_regs));
+       }
+
+       if (kvm_has_fpmr(kern_hyp_va(vcpu->kvm)))
+               *host_data_ptr(fpmr) = read_sysreg_s(SYS_FPMR);
+}
+
 
 /*
  * We trap the first access to the FP/SIMD to save the host context and
@@ -425,7 +446,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 (host_owns_fp_regs())
+       if (is_protected_kvm_enabled() && host_owns_fp_regs())
                kvm_hyp_save_fpsimd_host(vcpu);
 
        /* Restore the guest state */
index 6aa0b13d86e581a36ed529bcd932498045d2d6df..7262983c75fbc18ab44f52753bff1dd9167a68d3 100644 (file)
@@ -83,7 +83,7 @@ static void fpsimd_sve_sync(struct kvm_vcpu *vcpu)
        if (system_supports_sve())
                __hyp_sve_restore_host();
        else
-               __fpsimd_restore_state(*host_data_ptr(fpsimd_state));
+               __fpsimd_restore_state(host_data_ptr(host_ctxt.fp_regs));
 
        if (has_fpmr)
                write_sysreg_s(*host_data_ptr(fpmr), SYS_FPMR);
index 81d933a71310fd1132b2450cd08108e071a2cf78..3ce16f90fe6af7be21bc7b84a9d8b3905b8b08a7 100644 (file)
@@ -193,34 +193,6 @@ static bool kvm_handle_pvm_sys64(struct kvm_vcpu *vcpu, u64 *exit_code)
                kvm_handle_pvm_sysreg(vcpu, exit_code));
 }
 
-static void kvm_hyp_save_fpsimd_host(struct kvm_vcpu *vcpu)
-{
-       /*
-        * Non-protected kvm relies on the host restoring its sve state.
-        * Protected kvm restores the host's sve state as not to reveal that
-        * fpsimd was used by a guest nor leak upper sve bits.
-        */
-       if (unlikely(is_protected_kvm_enabled() && system_supports_sve())) {
-               __hyp_sve_save_host();
-
-               /* Re-enable SVE traps if not supported for the guest vcpu. */
-               if (!vcpu_has_sve(vcpu))
-                       cpacr_clear_set(CPACR_ELx_ZEN, 0);
-
-       } else {
-               __fpsimd_save_state(*host_data_ptr(fpsimd_state));
-       }
-
-       if (kvm_has_fpmr(kern_hyp_va(vcpu->kvm))) {
-               u64 val = read_sysreg_s(SYS_FPMR);
-
-               if (unlikely(is_protected_kvm_enabled()))
-                       *host_data_ptr(fpmr) = val;
-               else
-                       **host_data_ptr(fpmr_ptr) = val;
-       }
-}
-
 static const exit_handler_fn hyp_exit_handlers[] = {
        [0 ... ESR_ELx_EC_MAX]          = NULL,
        [ESR_ELx_EC_CP15_32]            = kvm_hyp_handle_cp15_32,
index 80581b1c399595fd64d0ccada498edac322480a6..e7ca0424107adec2371ae4553ebab9857c60b6d9 100644 (file)
@@ -309,14 +309,6 @@ static bool kvm_hyp_handle_eret(struct kvm_vcpu *vcpu, u64 *exit_code)
        return true;
 }
 
-static void kvm_hyp_save_fpsimd_host(struct kvm_vcpu *vcpu)
-{
-       __fpsimd_save_state(*host_data_ptr(fpsimd_state));
-
-       if (kvm_has_fpmr(vcpu->kvm))
-               **host_data_ptr(fpmr_ptr) = read_sysreg_s(SYS_FPMR);
-}
-
 static bool kvm_hyp_handle_tlbi_el2(struct kvm_vcpu *vcpu, u64 *exit_code)
 {
        int ret = -EINVAL;