@@ -17,6 +17,7 @@
struct sigcontext {
struct user_regs_struct sc_regs;
union __riscv_fp_state sc_fpregs;
+ struct __riscv_v_state sc_vregs;
};
#endif /* _UAPI_ASM_RISCV_SIGCONTEXT_H */
@@ -83,6 +83,40 @@ static long save_fp_state(struct pt_regs *regs,
#define restore_fp_state(task, regs) (0)
#endif
+#ifdef CONFIG_VECTOR
+static long restore_v_state(struct pt_regs *regs,
+ struct __riscv_v_state *sc_vregs)
+{
+ long err;
+ struct __riscv_v_state __user *state = sc_vregs;
+
+ err = __copy_from_user(¤t->thread.vstate, state, sizeof(*state));
+ if (unlikely(err))
+ return err;
+
+ vstate_restore(current, regs);
+
+ return err;
+}
+
+static long save_v_state(struct pt_regs *regs,
+ struct __riscv_v_state *sc_vregs)
+{
+ long err;
+ struct __riscv_v_state __user *state = sc_vregs;
+
+ vstate_save(current, regs);
+ err = __copy_to_user(state, ¤t->thread.vstate, sizeof(*state));
+ if (unlikely(err))
+ return err;
+
+ return err;
+}
+#else
+#define save_v_state(task, regs) (0)
+#define restore_v_state(task, regs) (0)
+#endif
+
static long restore_sigcontext(struct pt_regs *regs,
struct sigcontext __user *sc)
{
@@ -92,6 +126,9 @@ static long restore_sigcontext(struct pt_regs *regs,
/* Restore the floating-point state. */
if (has_fpu)
err |= restore_fp_state(regs, &sc->sc_fpregs);
+ /* Restore the vector state. */
+ if (has_vector)
+ err |= restore_v_state(regs, &sc->sc_vregs);
return err;
}
@@ -145,6 +182,9 @@ static long setup_sigcontext(struct rt_sigframe __user *frame,
/* Save the floating-point state. */
if (has_fpu)
err |= save_fp_state(regs, &sc->sc_fpregs);
+ /* Save the vector state. */
+ if (has_vector)
+ err |= save_v_state(regs, &sc->sc_vregs);
return err;
}