extern void fpsimd_preserve_current_state(void);
 extern void fpsimd_restore_current_state(void);
 extern void fpsimd_update_current_state(struct user_fpsimd_state const *state);
+extern void fpsimd_kvm_prepare(void);
 
 extern void fpsimd_bind_state_to_cpu(struct user_fpsimd_state *state,
                                     void *sve_state, unsigned int sve_vl,
 
                sve_to_fpsimd(current);
 }
 
+/*
+ * Called by KVM when entering the guest.
+ */
+void fpsimd_kvm_prepare(void)
+{
+       if (!system_supports_sve())
+               return;
+
+       /*
+        * KVM does not save host SVE state since we can only enter
+        * the guest from a syscall so the ABI means that only the
+        * non-saved SVE state needs to be saved.  If we have left
+        * SVE enabled for performance reasons then update the task
+        * state to be FPSIMD only.
+        */
+       get_cpu_fpsimd_context();
+
+       if (test_and_clear_thread_flag(TIF_SVE))
+               sve_to_fpsimd(current);
+
+       put_cpu_fpsimd_context();
+}
+
 /*
  * Associate current's FPSIMD context with this cpu
  * The caller must have ownership of the cpu FPSIMD context before calling
 
 void kvm_arch_vcpu_load_fp(struct kvm_vcpu *vcpu)
 {
        BUG_ON(!current->mm);
-       BUG_ON(test_thread_flag(TIF_SVE));
 
        if (!system_supports_fpsimd())
                return;
 
+       fpsimd_kvm_prepare();
+
        vcpu->arch.fp_state = FP_STATE_HOST_OWNED;
 
        vcpu_clear_flag(vcpu, HOST_SVE_ENABLED);