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:
committed by
Will Deacon
parent
f0f4be3921
commit
73106ecef5
@@ -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;
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user