FROMGIT: arm64/fpsimd: Factor out {sve,sme}_state_size() helpers

In subsequent patches we'll need to determine the SVE/SME state size for
a given SVE VL and SME VL regardless of whether a task is currently
configured with those VLs. Split the sizing logic out of
sve_state_size() and sme_state_size() so that we don't need to open-code
this logic elsewhere.

At the same time, apply minor cleanups:

* Move sve_state_size() into fpsimd.h, matching the placement of
  sme_state_size().

* Remove the feature checks from sve_state_size(). We only call
  sve_state_size() when at least one of SVE and SME are supported, and
  when either of the two is not supported, the task's corresponding
  SVE/SME vector length will be zero.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Marc Zyngier <maz@kernel.org>
Cc: Mark Brown <broonie@kernel.org>
Cc: Will Deacon <will@kernel.org>
Link: https://lore.kernel.org/r/20250508132644.1395904-8-mark.rutland@arm.com
Signed-off-by: Will Deacon <will@kernel.org>
(cherry picked from commit 8738288a08b8367cd2a9f656498d7490e4473036
 https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git
 for-next/sme-fixes)
Bug: 393087661
Signed-off-by: Will Deacon <willdeacon@google.com>
Change-Id: Ic91fd98e53df7cf0f53454b13459f8be36249e3e
This commit is contained in:
Mark Rutland
2025-05-08 14:26:27 +01:00
committed by Will Deacon
parent f0f4be3921
commit 73106ecef5
2 changed files with 37 additions and 26 deletions

View File

@@ -294,7 +294,22 @@ static inline bool sve_vq_available(unsigned int vq)
return vq_available(ARM64_VEC_SVE, vq);
}
size_t sve_state_size(struct task_struct const *task);
static inline size_t __sve_state_size(unsigned int sve_vl, unsigned int sme_vl)
{
unsigned int vl = max(sve_vl, sme_vl);
return SVE_SIG_REGS_SIZE(sve_vq_from_vl(vl));
}
/*
* Return how many bytes of memory are required to store the full SVE
* state for task, given task's currently configured vector length.
*/
static inline size_t sve_state_size(struct task_struct const *task)
{
unsigned int sve_vl = task_get_sve_vl(task);
unsigned int sme_vl = task_get_sme_vl(task);
return __sve_state_size(sve_vl, sme_vl);
}
#else /* ! CONFIG_ARM64_SVE */
@@ -335,6 +350,11 @@ static inline void vec_update_vq_map(enum vec_type t) { }
static inline int vec_verify_vq_map(enum vec_type t) { return 0; }
static inline void sve_setup(void) { }
static inline size_t __sve_state_size(unsigned int sve_vl, unsigned int sme_vl)
{
return 0;
}
static inline size_t sve_state_size(struct task_struct const *task)
{
return 0;
@@ -387,6 +407,16 @@ extern int sme_set_current_vl(unsigned long arg);
extern int sme_get_current_vl(void);
extern void sme_suspend_exit(void);
static inline size_t __sme_state_size(unsigned int sme_vl)
{
size_t size = ZA_SIG_REGS_SIZE(sve_vq_from_vl(sme_vl));
if (system_supports_sme2())
size += ZT_SIG_REG_SIZE;
return size;
}
/*
* Return how many bytes of memory are required to store the full SME
* specific state for task, given task's currently configured vector
@@ -394,15 +424,7 @@ extern void sme_suspend_exit(void);
*/
static inline size_t sme_state_size(struct task_struct const *task)
{
unsigned int vl = task_get_sme_vl(task);
size_t size;
size = ZA_SIG_REGS_SIZE(sve_vq_from_vl(vl));
if (system_supports_sme2())
size += ZT_SIG_REG_SIZE;
return size;
return __sme_state_size(task_get_sme_vl(task));
}
#else
@@ -423,6 +445,11 @@ static inline int sme_set_current_vl(unsigned long arg) { return -EINVAL; }
static inline int sme_get_current_vl(void) { return -EINVAL; }
static inline void sme_suspend_exit(void) { }
static inline size_t __sme_state_size(unsigned int sme_vl)
{
return 0;
}
static inline size_t sme_state_size(struct task_struct const *task)
{
return 0;

View File

@@ -719,22 +719,6 @@ static void sve_free(struct task_struct *task)
__sve_free(task);
}
/*
* Return how many bytes of memory are required to store the full SVE
* state for task, given task's currently configured vector length.
*/
size_t sve_state_size(struct task_struct const *task)
{
unsigned int vl = 0;
if (system_supports_sve())
vl = task_get_sve_vl(task);
if (system_supports_sme())
vl = max(vl, task_get_sme_vl(task));
return SVE_SIG_REGS_SIZE(sve_vq_from_vl(vl));
}
/*
* Ensure that task->thread.sve_state is allocated and sufficiently large.
*