[PATCH v1 23/38] arm64/sme: Implement ZA context switching

Jonathan Cameron Jonathan.Cameron at Huawei.com
Mon Oct 11 05:27:25 PDT 2021


On Thu, 30 Sep 2021 19:11:29 +0100
Mark Brown <broonie at kernel.org> wrote:

> Allocate space for storing ZA on first access to SME and use that to save
> and restore ZA state when context switching. We do this by using the vector
> form of the LDR and STR ZA instructions, these do not require streaming
> mode and have implementation recommendations that they avoid contention
> issues in shared SMCU implementations.
> 
> Since ZA is architecturally guaranteed to be zeroed when enabled we do not
> need to explicitly zero ZA, either we will be restoring from a saved copy
> or trapping on first use of SME so we know that ZA must be disabled.
> 
> Signed-off-by: Mark Brown <broonie at kernel.org>

sme_alloc() forwards definition should be in the next patch.
> ---
>  arch/arm64/include/asm/fpsimd.h       |  5 ++++-
>  arch/arm64/include/asm/fpsimdmacros.h | 22 ++++++++++++++++++++++
>  arch/arm64/include/asm/processor.h    |  1 +
>  arch/arm64/kernel/entry-fpsimd.S      | 22 ++++++++++++++++++++++
>  arch/arm64/kernel/fpsimd.c            | 16 ++++++++++------
>  arch/arm64/kvm/fpsimd.c               |  2 +-
>  6 files changed, 60 insertions(+), 8 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/fpsimd.h b/arch/arm64/include/asm/fpsimd.h
> index 43737ca91f1a..45f7153067bb 100644
> --- a/arch/arm64/include/asm/fpsimd.h
> +++ b/arch/arm64/include/asm/fpsimd.h
> @@ -47,7 +47,7 @@ extern void fpsimd_update_current_state(struct user_fpsimd_state const *state);
>  
>  extern void fpsimd_bind_state_to_cpu(struct user_fpsimd_state *state,
>  				     void *sve_state, unsigned int sve_vl,
> -				     unsigned int sme_vl);
> +				     void *za_state, unsigned int sme_vl);
>  
>  extern void fpsimd_flush_task_state(struct task_struct *target);
>  extern void fpsimd_save_and_flush_cpu_state(void);
> @@ -90,6 +90,8 @@ extern void sve_flush_live(bool flush_ffr, unsigned long vq_minus_1);
>  extern unsigned int sve_get_vl(void);
>  extern void sve_set_vq(unsigned long vq_minus_1);
>  extern void sme_set_vq(unsigned long vq_minus_1);
> +extern void sme_save_state(void *state, unsigned int vq_minus_1);
> +extern void sme_load_state(void const *state, unsigned int vq_minus_1);
>  
>  struct arm64_cpu_capabilities;
>  extern void sve_kernel_enable(const struct arm64_cpu_capabilities *__unused);
> @@ -119,6 +121,7 @@ static inline unsigned int __bit_to_vq(unsigned int bit)
>  extern size_t sve_state_size(struct task_struct const *task);
>  
>  extern void sve_alloc(struct task_struct *task);
> +extern void sme_alloc(struct task_struct *task);

Should be in the next patch where this function is introduced.

>  extern void fpsimd_release_task(struct task_struct *task);
>  extern void fpsimd_sync_to_sve(struct task_struct *task);
>  extern void sve_sync_to_fpsimd(struct task_struct *task);



More information about the linux-arm-kernel mailing list