Skip to content

Commit 9e4ab6c

Browse files
brooniectmarinas
authored andcommitted
arm64/sme: Implement vector length configuration prctl()s
As for SVE provide a prctl() interface which allows processes to configure their SME vector length. Signed-off-by: Mark Brown <[email protected]> Reviewed-by: Catalin Marinas <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Catalin Marinas <[email protected]>
1 parent 12f1bac commit 9e4ab6c

File tree

6 files changed

+61
-1
lines changed

6 files changed

+61
-1
lines changed

arch/arm64/include/asm/fpsimd.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,8 @@ static inline int sme_max_virtualisable_vl(void)
288288
}
289289

290290
extern unsigned int sme_get_vl(void);
291+
extern int sme_set_current_vl(unsigned long arg);
292+
extern int sme_get_current_vl(void);
291293

292294
#else
293295

@@ -299,6 +301,8 @@ static inline void sme_setup(void) { }
299301
static inline unsigned int sme_get_vl(void) { return 0; }
300302
static inline int sme_max_vl(void) { return 0; }
301303
static inline int sme_max_virtualisable_vl(void) { return 0; }
304+
static inline int sme_set_current_vl(unsigned long arg) { return -EINVAL; }
305+
static inline int sme_get_current_vl(void) { return -EINVAL; }
302306

303307
#endif /* ! CONFIG_ARM64_SME */
304308

arch/arm64/include/asm/processor.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -355,9 +355,11 @@ extern void __init minsigstksz_setup(void);
355355
*/
356356
#include <asm/fpsimd.h>
357357

358-
/* Userspace interface for PR_SVE_{SET,GET}_VL prctl()s: */
358+
/* Userspace interface for PR_S[MV]E_{SET,GET}_VL prctl()s: */
359359
#define SVE_SET_VL(arg) sve_set_current_vl(arg)
360360
#define SVE_GET_VL() sve_get_current_vl()
361+
#define SME_SET_VL(arg) sme_set_current_vl(arg)
362+
#define SME_GET_VL() sme_get_current_vl()
361363

362364
/* PR_PAC_RESET_KEYS prctl */
363365
#define PAC_RESET_KEYS(tsk, arg) ptrauth_prctl_reset_keys(tsk, arg)

arch/arm64/include/asm/thread_info.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ int arch_dup_task_struct(struct task_struct *dst,
8282
#define TIF_SVE_VL_INHERIT 24 /* Inherit SVE vl_onexec across exec */
8383
#define TIF_SSBD 25 /* Wants SSB mitigation */
8484
#define TIF_TAGGED_ADDR 26 /* Allow tagged user addresses */
85+
#define TIF_SME_VL_INHERIT 28 /* Inherit SME vl_onexec across exec */
8586

8687
#define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
8788
#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)

arch/arm64/kernel/fpsimd.c

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,8 @@ static unsigned int vec_vl_inherit_flag(enum vec_type type)
149149
switch (type) {
150150
case ARM64_VEC_SVE:
151151
return TIF_SVE_VL_INHERIT;
152+
case ARM64_VEC_SME:
153+
return TIF_SME_VL_INHERIT;
152154
default:
153155
WARN_ON_ONCE(1);
154156
return 0;
@@ -807,6 +809,36 @@ int sve_get_current_vl(void)
807809
return vec_prctl_status(ARM64_VEC_SVE, 0);
808810
}
809811

812+
#ifdef CONFIG_ARM64_SME
813+
/* PR_SME_SET_VL */
814+
int sme_set_current_vl(unsigned long arg)
815+
{
816+
unsigned long vl, flags;
817+
int ret;
818+
819+
vl = arg & PR_SME_VL_LEN_MASK;
820+
flags = arg & ~vl;
821+
822+
if (!system_supports_sme() || is_compat_task())
823+
return -EINVAL;
824+
825+
ret = vec_set_vector_length(current, ARM64_VEC_SME, vl, flags);
826+
if (ret)
827+
return ret;
828+
829+
return vec_prctl_status(ARM64_VEC_SME, flags);
830+
}
831+
832+
/* PR_SME_GET_VL */
833+
int sme_get_current_vl(void)
834+
{
835+
if (!system_supports_sme() || is_compat_task())
836+
return -EINVAL;
837+
838+
return vec_prctl_status(ARM64_VEC_SME, 0);
839+
}
840+
#endif /* CONFIG_ARM64_SME */
841+
810842
static void vec_probe_vqs(struct vl_info *info,
811843
DECLARE_BITMAP(map, SVE_VQ_MAX))
812844
{

include/uapi/linux/prctl.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,15 @@ struct prctl_mm_map {
272272
# define PR_SCHED_CORE_SCOPE_THREAD_GROUP 1
273273
# define PR_SCHED_CORE_SCOPE_PROCESS_GROUP 2
274274

275+
/* arm64 Scalable Matrix Extension controls */
276+
/* Flag values must be in sync with SVE versions */
277+
#define PR_SME_SET_VL 63 /* set task vector length */
278+
# define PR_SME_SET_VL_ONEXEC (1 << 18) /* defer effect until exec */
279+
#define PR_SME_GET_VL 64 /* get task vector length */
280+
/* Bits common to PR_SME_SET_VL and PR_SME_GET_VL */
281+
# define PR_SME_VL_LEN_MASK 0xffff
282+
# define PR_SME_VL_INHERIT (1 << 17) /* inherit across exec */
283+
275284
#define PR_SET_VMA 0x53564d41
276285
# define PR_SET_VMA_ANON_NAME 0
277286

kernel/sys.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,12 @@
117117
#ifndef SVE_GET_VL
118118
# define SVE_GET_VL() (-EINVAL)
119119
#endif
120+
#ifndef SME_SET_VL
121+
# define SME_SET_VL(a) (-EINVAL)
122+
#endif
123+
#ifndef SME_GET_VL
124+
# define SME_GET_VL() (-EINVAL)
125+
#endif
120126
#ifndef PAC_RESET_KEYS
121127
# define PAC_RESET_KEYS(a, b) (-EINVAL)
122128
#endif
@@ -2541,6 +2547,12 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3,
25412547
case PR_SVE_GET_VL:
25422548
error = SVE_GET_VL();
25432549
break;
2550+
case PR_SME_SET_VL:
2551+
error = SME_SET_VL(arg2);
2552+
break;
2553+
case PR_SME_GET_VL:
2554+
error = SME_GET_VL();
2555+
break;
25442556
case PR_GET_SPECULATION_CTRL:
25452557
if (arg3 || arg4 || arg5)
25462558
return -EINVAL;

0 commit comments

Comments
 (0)