arm64/sve: Implement a helper to flush SVE registers
authorJulien Grall <julien.grall@arm.com>
Fri, 28 Aug 2020 18:11:52 +0000 (19:11 +0100)
committerWill Deacon <will@kernel.org>
Mon, 21 Sep 2020 17:06:33 +0000 (18:06 +0100)
Introduce a new helper that will zero all SVE registers but the first
128-bits of each vector. This will be used by subsequent patches to
avoid costly store/maipulate/reload sequences in places like do_sve_acc().

Signed-off-by: Julien Grall <julien.grall@arm.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Reviewed-by: Dave Martin <Dave.Martin@arm.com>
Link: https://lore.kernel.org/r/20200828181155.17745-6-broonie@kernel.org
Signed-off-by: Will Deacon <will@kernel.org>
arch/arm64/include/asm/fpsimd.h
arch/arm64/include/asm/fpsimdmacros.h
arch/arm64/kernel/entry-fpsimd.S

index 59f10dd..958f642 100644 (file)
@@ -69,6 +69,7 @@ static inline void *sve_pffr(struct thread_struct *thread)
 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 unsigned int sve_get_vl(void);
 
 struct arm64_cpu_capabilities;
index feef5b3..af43367 100644 (file)
                | ((\np) << 5)
 .endm
 
+/* PFALSE P\np.B */
+.macro _sve_pfalse np
+       _sve_check_preg \np
+       .inst   0x2518e400                      \
+               | (\np)
+.endm
+
 .macro __for from:req, to:req
        .if (\from) == (\to)
                _for__body %\from
 921:
 .endm
 
+/* Preserve the first 128-bits of Znz and zero the rest. */
+.macro _sve_flush_z nz
+       _sve_check_zreg \nz
+       mov     v\nz\().16b, v\nz\().16b
+.endm
+
+.macro sve_flush
+ _for n, 0, 31, _sve_flush_z   \n
+ _for n, 0, 15, _sve_pfalse    \n
+               _sve_wrffr      0
+.endm
+
 .macro sve_save nxbase, xpfpsr, nxtmp
  _for n, 0, 31,        _sve_str_v      \n, \nxbase, \n - 34
  _for n, 0, 15,        _sve_str_p      \n, \nxbase, \n - 16
index f880dd6..fdf7a5a 100644 (file)
@@ -32,6 +32,7 @@ SYM_FUNC_START(fpsimd_load_state)
 SYM_FUNC_END(fpsimd_load_state)
 
 #ifdef CONFIG_ARM64_SVE
+
 SYM_FUNC_START(sve_save_state)
        sve_save 0, x1, 2
        ret
@@ -46,4 +47,11 @@ SYM_FUNC_START(sve_get_vl)
        _sve_rdvl       0, 1
        ret
 SYM_FUNC_END(sve_get_vl)
+
+/* Zero all SVE registers but the first 128-bits of each vector */
+SYM_FUNC_START(sve_flush_live)
+       sve_flush
+       ret
+SYM_FUNC_END(sve_flush_live)
+
 #endif /* CONFIG_ARM64_SVE */