Commit 9e4ab6c8 authored by Mark Brown's avatar Mark Brown Committed by Catalin Marinas
Browse files

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: default avatarMark Brown <broonie@kernel.org>
Reviewed-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
Link: https://lore.kernel.org/r/20220419112247.711548-12-broonie@kernel.org


Signed-off-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
parent 12f1bacf
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -288,6 +288,8 @@ static inline int sme_max_virtualisable_vl(void)
}

extern unsigned int sme_get_vl(void);
extern int sme_set_current_vl(unsigned long arg);
extern int sme_get_current_vl(void);

#else

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

#endif /* ! CONFIG_ARM64_SME */

+3 −1
Original line number Diff line number Diff line
@@ -355,9 +355,11 @@ extern void __init minsigstksz_setup(void);
 */
#include <asm/fpsimd.h>

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

/* PR_PAC_RESET_KEYS prctl */
#define PAC_RESET_KEYS(tsk, arg)	ptrauth_prctl_reset_keys(tsk, arg)
+1 −0
Original line number Diff line number Diff line
@@ -82,6 +82,7 @@ int arch_dup_task_struct(struct task_struct *dst,
#define TIF_SVE_VL_INHERIT	24	/* Inherit SVE vl_onexec across exec */
#define TIF_SSBD		25	/* Wants SSB mitigation */
#define TIF_TAGGED_ADDR		26	/* Allow tagged user addresses */
#define TIF_SME_VL_INHERIT	28	/* Inherit SME vl_onexec across exec */

#define _TIF_SIGPENDING		(1 << TIF_SIGPENDING)
#define _TIF_NEED_RESCHED	(1 << TIF_NEED_RESCHED)
+32 −0
Original line number Diff line number Diff line
@@ -149,6 +149,8 @@ static unsigned int vec_vl_inherit_flag(enum vec_type type)
	switch (type) {
	case ARM64_VEC_SVE:
		return TIF_SVE_VL_INHERIT;
	case ARM64_VEC_SME:
		return TIF_SME_VL_INHERIT;
	default:
		WARN_ON_ONCE(1);
		return 0;
@@ -807,6 +809,36 @@ int sve_get_current_vl(void)
	return vec_prctl_status(ARM64_VEC_SVE, 0);
}

#ifdef CONFIG_ARM64_SME
/* PR_SME_SET_VL */
int sme_set_current_vl(unsigned long arg)
{
	unsigned long vl, flags;
	int ret;

	vl = arg & PR_SME_VL_LEN_MASK;
	flags = arg & ~vl;

	if (!system_supports_sme() || is_compat_task())
		return -EINVAL;

	ret = vec_set_vector_length(current, ARM64_VEC_SME, vl, flags);
	if (ret)
		return ret;

	return vec_prctl_status(ARM64_VEC_SME, flags);
}

/* PR_SME_GET_VL */
int sme_get_current_vl(void)
{
	if (!system_supports_sme() || is_compat_task())
		return -EINVAL;

	return vec_prctl_status(ARM64_VEC_SME, 0);
}
#endif /* CONFIG_ARM64_SME */

static void vec_probe_vqs(struct vl_info *info,
			  DECLARE_BITMAP(map, SVE_VQ_MAX))
{
+9 −0
Original line number Diff line number Diff line
@@ -272,6 +272,15 @@ struct prctl_mm_map {
# define PR_SCHED_CORE_SCOPE_THREAD_GROUP	1
# define PR_SCHED_CORE_SCOPE_PROCESS_GROUP	2

/* arm64 Scalable Matrix Extension controls */
/* Flag values must be in sync with SVE versions */
#define PR_SME_SET_VL			63	/* set task vector length */
# define PR_SME_SET_VL_ONEXEC		(1 << 18) /* defer effect until exec */
#define PR_SME_GET_VL			64	/* get task vector length */
/* Bits common to PR_SME_SET_VL and PR_SME_GET_VL */
# define PR_SME_VL_LEN_MASK		0xffff
# define PR_SME_VL_INHERIT		(1 << 17) /* inherit across exec */

#define PR_SET_VMA		0x53564d41
# define PR_SET_VMA_ANON_NAME		0

Loading