]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
arm64/fpsimd: Factor out {sve,sme}_state_size() helpers
authorMark Rutland <mark.rutland@arm.com>
Thu, 8 May 2025 13:26:27 +0000 (14:26 +0100)
committerWill Deacon <will@kernel.org>
Thu, 8 May 2025 14:29:09 +0000 (15:29 +0100)
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>
arch/arm64/include/asm/fpsimd.h
arch/arm64/kernel/fpsimd.c

index c9e17d093fe2331bbc517d169b6ddf27bce974e1..b751064bbaaa18390975794eed6c96830e158215 100644 (file)
@@ -293,7 +293,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 */
 
@@ -334,6 +349,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;
@@ -386,6 +406,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
@@ -393,15 +423,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
@@ -422,6 +444,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;
index dd6480087683c4c7399942e7cc27927f80589ecf..c2603fe8dd2431af6f171e5e280fa20908b3dae4 100644 (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.
  *