From a08391468f2fcc251ecac861d59a904a65018d64 Mon Sep 17 00:00:00 2001 From: Mark Rutland Date: Mon, 10 Feb 2025 19:52:20 +0000 Subject: [PATCH] BACKPORT: KVM: arm64: Remove host FPSIMD saving for non-protected KVM [ 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. [tabba@ Kept user_fpsimd_state as to not break the KMI.] Bug: 411040189 Change-Id: I0088db7c5f75c9331956867040b8eb69976aabf8 Signed-off-by: Mark Rutland Reviewed-by: Mark Brown Tested-by: Mark Brown Acked-by: Will Deacon Cc: Catalin Marinas Cc: Fuad Tabba Cc: Marc Zyngier Cc: Oliver Upton Reviewed-by: Oliver Upton Link: https://lore.kernel.org/r/20250210195226.1215254-3-mark.rutland@arm.com Signed-off-by: Marc Zyngier Signed-off-by: Mark Brown Signed-off-by: Greg Kroah-Hartman Signed-off-by: Fuad Tabba --- arch/arm64/include/asm/kvm_host.h | 3 ++- arch/arm64/include/asm/kvm_hyp.h | 2 +- arch/arm64/kvm/fpsimd.c | 2 -- arch/arm64/kvm/hyp/include/hyp/switch.h | 4 ++-- arch/arm64/kvm/hyp/nvhe/pkvm.c | 3 --- 5 files changed, 5 insertions(+), 9 deletions(-) diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h index 1ad2a045f8e7..b894dc38e205 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -488,7 +488,8 @@ 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 */ + /* DO NOT USE: Removed upstream. Kept to not break the KMI. */ + struct user_fpsimd_state *host_fpsimd_state; struct { /* {Break,watch}point registers */ diff --git a/arch/arm64/include/asm/kvm_hyp.h b/arch/arm64/include/asm/kvm_hyp.h index 5f16c6f800a6..b0ed038ff4e9 100644 --- a/arch/arm64/include/asm/kvm_hyp.h +++ b/arch/arm64/include/asm/kvm_hyp.h @@ -122,7 +122,7 @@ void __noreturn __host_enter(struct kvm_cpu_context *host_ctxt); struct user_fpsimd_state *get_host_fpsimd_state(struct kvm_vcpu *vcpu); struct kvm_host_sve_state *get_host_sve_state(struct kvm_vcpu *vcpu); #else -#define get_host_fpsimd_state(vcpu) (vcpu)->arch.host_fpsimd_state +#define get_host_fpsimd_state(vcpu) NULL #define get_host_sve_state(vcpu) NULL #endif diff --git a/arch/arm64/kvm/fpsimd.c b/arch/arm64/kvm/fpsimd.c index 43bec87ee74d..552434b96595 100644 --- a/arch/arm64/kvm/fpsimd.c +++ b/arch/arm64/kvm/fpsimd.c @@ -37,8 +37,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); - return 0; } diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h index 087a3cef4116..221d2b72a513 100644 --- a/arch/arm64/kvm/hyp/include/hyp/switch.h +++ b/arch/arm64/kvm/hyp/include/hyp/switch.h @@ -175,7 +175,7 @@ static void kvm_hyp_handle_fpsimd_host(struct kvm_vcpu *vcpu) * 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())) { + if (system_supports_sve()) { struct kvm_host_sve_state *sve_state = get_host_sve_state(vcpu); sve_state->zcr_el1 = read_sysreg_el1(SYS_ZCR); @@ -243,7 +243,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 (is_protected_kvm_enabled() && vcpu->arch.fp_state == FP_STATE_HOST_OWNED) kvm_hyp_handle_fpsimd_host(vcpu); /* Restore the guest state */ diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c index b3acb60a2d6c..85227166252a 100644 --- a/arch/arm64/kvm/hyp/nvhe/pkvm.c +++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c @@ -54,9 +54,6 @@ static void *__get_host_fpsimd_bytes(void) struct user_fpsimd_state *get_host_fpsimd_state(struct kvm_vcpu *vcpu) { - if (likely(!is_protected_kvm_enabled())) - return vcpu->arch.host_fpsimd_state; - WARN_ON(system_supports_sve()); return __get_host_fpsimd_bytes(); }