Message ID | 20200629133556.39825-7-broonie@kernel.org (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | arm64/sve: First steps towards optimizing syscalls | expand |
On Mon, Jun 29, 2020 at 02:35:54PM +0100, Mark Brown wrote: > From: Julien Grall <julien.grall@arm.com> > > In a follow-up patch, we may save the FPSIMD rather than the full SVE > state when the state has to be zeroed on return to userspace (e.g > during a syscall). > > Introduce an helper to load SVE vectors from FPSIMD state and zero the rest > of SVE registers. > > Signed-off-by: Julien Grall <julien.grall@arm.com> > Reviewed-by: Dave Martin <Dave.Martin@arm.com> > Signed-off-by: Mark Brown <broonie@kernel.org> > --- > arch/arm64/include/asm/fpsimd.h | 2 ++ > arch/arm64/kernel/entry-fpsimd.S | 17 +++++++++++++++++ > 2 files changed, 19 insertions(+) > > diff --git a/arch/arm64/include/asm/fpsimd.h b/arch/arm64/include/asm/fpsimd.h > index 958f642e930d..bec5f14b622a 100644 > --- a/arch/arm64/include/asm/fpsimd.h > +++ b/arch/arm64/include/asm/fpsimd.h > @@ -70,6 +70,8 @@ extern void sve_save_state(void *state, u32 *pfpsr); > extern void sve_load_state(void const *state, u32 const *pfpsr, > unsigned long vq_minus_1); > extern void sve_flush_live(void); > +extern void sve_load_from_fpsimd_state(struct user_fpsimd_state const *state, > + unsigned long vq_minus_1); > extern unsigned int sve_get_vl(void); > > struct arm64_cpu_capabilities; > diff --git a/arch/arm64/kernel/entry-fpsimd.S b/arch/arm64/kernel/entry-fpsimd.S > index fdf7a5a35c63..5b1a9adfb00b 100644 > --- a/arch/arm64/kernel/entry-fpsimd.S > +++ b/arch/arm64/kernel/entry-fpsimd.S > @@ -48,6 +48,23 @@ SYM_FUNC_START(sve_get_vl) > ret > SYM_FUNC_END(sve_get_vl) > > +/* > + * Load SVE state from FPSIMD state. > + * > + * x0 = pointer to struct fpsimd_state > + * x1 = VQ - 1 > + * > + * Each SVE vector will be loaded with the first 128-bits taken from FPSIMD > + * and the rest zeroed. All the other SVE registers will be zeroed. > + */ > +SYM_FUNC_START(sve_load_from_fpsimd_state) > + sve_load_vq x1, x2, x3 > + fpsimd_restore x0, 8 > + _for n, 0, 15, _sve_pfalse \n > + _sve_wrffr 0 FWIW, trivial nit that I guess I didn't spot previously: tab before 0 here? Mind you, the spacing is already a bit off in this file. Cheers ---Dave
diff --git a/arch/arm64/include/asm/fpsimd.h b/arch/arm64/include/asm/fpsimd.h index 958f642e930d..bec5f14b622a 100644 --- a/arch/arm64/include/asm/fpsimd.h +++ b/arch/arm64/include/asm/fpsimd.h @@ -70,6 +70,8 @@ extern void sve_save_state(void *state, u32 *pfpsr); extern void sve_load_state(void const *state, u32 const *pfpsr, unsigned long vq_minus_1); extern void sve_flush_live(void); +extern void sve_load_from_fpsimd_state(struct user_fpsimd_state const *state, + unsigned long vq_minus_1); extern unsigned int sve_get_vl(void); struct arm64_cpu_capabilities; diff --git a/arch/arm64/kernel/entry-fpsimd.S b/arch/arm64/kernel/entry-fpsimd.S index fdf7a5a35c63..5b1a9adfb00b 100644 --- a/arch/arm64/kernel/entry-fpsimd.S +++ b/arch/arm64/kernel/entry-fpsimd.S @@ -48,6 +48,23 @@ SYM_FUNC_START(sve_get_vl) ret SYM_FUNC_END(sve_get_vl) +/* + * Load SVE state from FPSIMD state. + * + * x0 = pointer to struct fpsimd_state + * x1 = VQ - 1 + * + * Each SVE vector will be loaded with the first 128-bits taken from FPSIMD + * and the rest zeroed. All the other SVE registers will be zeroed. + */ +SYM_FUNC_START(sve_load_from_fpsimd_state) + sve_load_vq x1, x2, x3 + fpsimd_restore x0, 8 + _for n, 0, 15, _sve_pfalse \n + _sve_wrffr 0 + ret +SYM_FUNC_END(sve_load_from_fpsimd_state) + /* Zero all SVE registers but the first 128-bits of each vector */ SYM_FUNC_START(sve_flush_live) sve_flush