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 <broonie@kernel.org> Reviewed-by: Catalin Marinas <catalin.marinas@arm.com> Link: https://lore.kernel.org/r/20220419112247.711548-12-broonie@kernel.org Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
This commit is contained in:
parent
12f1bacfc5
commit
9e4ab6c891
@ -288,6 +288,8 @@ static inline int sme_max_virtualisable_vl(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
extern unsigned int sme_get_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
|
#else
|
||||||
|
|
||||||
@ -299,6 +301,8 @@ static inline void sme_setup(void) { }
|
|||||||
static inline unsigned int sme_get_vl(void) { return 0; }
|
static inline unsigned int sme_get_vl(void) { return 0; }
|
||||||
static inline int sme_max_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_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 */
|
#endif /* ! CONFIG_ARM64_SME */
|
||||||
|
|
||||||
|
@ -355,9 +355,11 @@ extern void __init minsigstksz_setup(void);
|
|||||||
*/
|
*/
|
||||||
#include <asm/fpsimd.h>
|
#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_SET_VL(arg) sve_set_current_vl(arg)
|
||||||
#define SVE_GET_VL() sve_get_current_vl()
|
#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 */
|
/* PR_PAC_RESET_KEYS prctl */
|
||||||
#define PAC_RESET_KEYS(tsk, arg) ptrauth_prctl_reset_keys(tsk, arg)
|
#define PAC_RESET_KEYS(tsk, arg) ptrauth_prctl_reset_keys(tsk, arg)
|
||||||
|
@ -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_SVE_VL_INHERIT 24 /* Inherit SVE vl_onexec across exec */
|
||||||
#define TIF_SSBD 25 /* Wants SSB mitigation */
|
#define TIF_SSBD 25 /* Wants SSB mitigation */
|
||||||
#define TIF_TAGGED_ADDR 26 /* Allow tagged user addresses */
|
#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_SIGPENDING (1 << TIF_SIGPENDING)
|
||||||
#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
|
#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
|
||||||
|
@ -149,6 +149,8 @@ static unsigned int vec_vl_inherit_flag(enum vec_type type)
|
|||||||
switch (type) {
|
switch (type) {
|
||||||
case ARM64_VEC_SVE:
|
case ARM64_VEC_SVE:
|
||||||
return TIF_SVE_VL_INHERIT;
|
return TIF_SVE_VL_INHERIT;
|
||||||
|
case ARM64_VEC_SME:
|
||||||
|
return TIF_SME_VL_INHERIT;
|
||||||
default:
|
default:
|
||||||
WARN_ON_ONCE(1);
|
WARN_ON_ONCE(1);
|
||||||
return 0;
|
return 0;
|
||||||
@ -807,6 +809,36 @@ int sve_get_current_vl(void)
|
|||||||
return vec_prctl_status(ARM64_VEC_SVE, 0);
|
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,
|
static void vec_probe_vqs(struct vl_info *info,
|
||||||
DECLARE_BITMAP(map, SVE_VQ_MAX))
|
DECLARE_BITMAP(map, SVE_VQ_MAX))
|
||||||
{
|
{
|
||||||
|
@ -272,6 +272,15 @@ struct prctl_mm_map {
|
|||||||
# define PR_SCHED_CORE_SCOPE_THREAD_GROUP 1
|
# define PR_SCHED_CORE_SCOPE_THREAD_GROUP 1
|
||||||
# define PR_SCHED_CORE_SCOPE_PROCESS_GROUP 2
|
# 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 0x53564d41
|
||||||
# define PR_SET_VMA_ANON_NAME 0
|
# define PR_SET_VMA_ANON_NAME 0
|
||||||
|
|
||||||
|
12
kernel/sys.c
12
kernel/sys.c
@ -117,6 +117,12 @@
|
|||||||
#ifndef SVE_GET_VL
|
#ifndef SVE_GET_VL
|
||||||
# define SVE_GET_VL() (-EINVAL)
|
# define SVE_GET_VL() (-EINVAL)
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef SME_SET_VL
|
||||||
|
# define SME_SET_VL(a) (-EINVAL)
|
||||||
|
#endif
|
||||||
|
#ifndef SME_GET_VL
|
||||||
|
# define SME_GET_VL() (-EINVAL)
|
||||||
|
#endif
|
||||||
#ifndef PAC_RESET_KEYS
|
#ifndef PAC_RESET_KEYS
|
||||||
# define PAC_RESET_KEYS(a, b) (-EINVAL)
|
# define PAC_RESET_KEYS(a, b) (-EINVAL)
|
||||||
#endif
|
#endif
|
||||||
@ -2541,6 +2547,12 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3,
|
|||||||
case PR_SVE_GET_VL:
|
case PR_SVE_GET_VL:
|
||||||
error = SVE_GET_VL();
|
error = SVE_GET_VL();
|
||||||
break;
|
break;
|
||||||
|
case PR_SME_SET_VL:
|
||||||
|
error = SME_SET_VL(arg2);
|
||||||
|
break;
|
||||||
|
case PR_SME_GET_VL:
|
||||||
|
error = SME_GET_VL();
|
||||||
|
break;
|
||||||
case PR_GET_SPECULATION_CTRL:
|
case PR_GET_SPECULATION_CTRL:
|
||||||
if (arg3 || arg4 || arg5)
|
if (arg3 || arg4 || arg5)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
Loading…
Reference in New Issue
Block a user