extern void fpsimd_update_current_state(struct user_fpsimd_state const *state);
 
 extern void fpsimd_bind_task_to_cpu(void);
-extern void fpsimd_bind_state_to_cpu(struct user_fpsimd_state *state);
+extern void fpsimd_bind_state_to_cpu(struct user_fpsimd_state *state,
+                                    void *sve_state, unsigned int sve_vl);
 
 extern void fpsimd_flush_task_state(struct task_struct *target);
 extern void fpsimd_flush_cpu_state(void);
 
  */
 struct fpsimd_last_state_struct {
        struct user_fpsimd_state *st;
+       void *sve_state;
+       unsigned int sve_vl;
 };
 
 static DEFINE_PER_CPU(struct fpsimd_last_state_struct, fpsimd_last_state);
  */
 void fpsimd_save(void)
 {
-       struct user_fpsimd_state *st = __this_cpu_read(fpsimd_last_state.st);
+       struct fpsimd_last_state_struct const *last =
+               this_cpu_ptr(&fpsimd_last_state);
        /* set by fpsimd_bind_task_to_cpu() or fpsimd_bind_state_to_cpu() */
 
        WARN_ON(!in_softirq() && !irqs_disabled());
 
        if (!test_thread_flag(TIF_FOREIGN_FPSTATE)) {
                if (system_supports_sve() && test_thread_flag(TIF_SVE)) {
-                       if (WARN_ON(sve_get_vl() != current->thread.sve_vl)) {
+                       if (WARN_ON(sve_get_vl() != last->sve_vl)) {
                                /*
                                 * Can't save the user regs, so current would
                                 * re-enter user with corrupt state.
                                return;
                        }
 
-                       sve_save_state(sve_pffr(¤t->thread), &st->fpsr);
+                       sve_save_state((char *)last->sve_state +
+                                               sve_ffr_offset(last->sve_vl),
+                                      &last->st->fpsr);
                } else
-                       fpsimd_save_state(st);
+                       fpsimd_save_state(last->st);
        }
 }
 
                this_cpu_ptr(&fpsimd_last_state);
 
        last->st = ¤t->thread.uw.fpsimd_state;
+       last->sve_state = current->thread.sve_state;
+       last->sve_vl = current->thread.sve_vl;
        current->thread.fpsimd_cpu = smp_processor_id();
 
        if (system_supports_sve()) {
        }
 }
 
-void fpsimd_bind_state_to_cpu(struct user_fpsimd_state *st)
+void fpsimd_bind_state_to_cpu(struct user_fpsimd_state *st, void *sve_state,
+                             unsigned int sve_vl)
 {
        struct fpsimd_last_state_struct *last =
                this_cpu_ptr(&fpsimd_last_state);
        WARN_ON(!in_softirq() && !irqs_disabled());
 
        last->st = st;
+       last->sve_state = sve_state;
+       last->sve_vl = sve_vl;
 }
 
 /*
 
 #include <linux/sched.h>
 #include <linux/thread_info.h>
 #include <linux/kvm_host.h>
+#include <asm/fpsimd.h>
 #include <asm/kvm_asm.h>
 #include <asm/kvm_host.h>
 #include <asm/kvm_mmu.h>
        WARN_ON_ONCE(!irqs_disabled());
 
        if (vcpu->arch.flags & KVM_ARM64_FP_ENABLED) {
-               fpsimd_bind_state_to_cpu(&vcpu->arch.ctxt.gp_regs.fp_regs);
+               fpsimd_bind_state_to_cpu(&vcpu->arch.ctxt.gp_regs.fp_regs,
+                                        NULL, SVE_VL_MIN);
+
                clear_thread_flag(TIF_FOREIGN_FPSTATE);
                clear_thread_flag(TIF_SVE);
        }