arm64/sve: Add prctl controls for userspace vector length management
This patch adds two arm64-specific prctls, to permit userspace to control its vector length: * PR_SVE_SET_VL: set the thread's SVE vector length and vector length inheritance mode. * PR_SVE_GET_VL: get the same information. Although these prctls resemble instruction set features in the SVE architecture, they provide additional control: the vector length inheritance mode is Linux-specific and nothing to do with the architecture, and the architecture does not permit EL0 to set its own vector length directly. Both can be used in portable tools without requiring the use of SVE instructions. Signed-off-by: Dave Martin <Dave.Martin@arm.com> Reviewed-by: Catalin Marinas <catalin.marinas@arm.com> Cc: Alex Bennée <alex.bennee@linaro.org> [will: Fixed up prctl constants to avoid clash with PDEATHSIG] Signed-off-by: Will Deacon <will.deacon@arm.com>
This commit is contained in:

committed by
Will Deacon

orang tua
43d4da2c45
melakukan
2d2123bc7c
@@ -29,6 +29,7 @@
|
||||
#include <linux/irqflags.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/percpu.h>
|
||||
#include <linux/prctl.h>
|
||||
#include <linux/preempt.h>
|
||||
#include <linux/prctl.h>
|
||||
#include <linux/ptrace.h>
|
||||
@@ -558,6 +559,55 @@ out:
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Encode the current vector length and flags for return.
|
||||
* This is only required for prctl(): ptrace has separate fields
|
||||
*
|
||||
* flags are as for sve_set_vector_length().
|
||||
*/
|
||||
static int sve_prctl_status(unsigned long flags)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (flags & PR_SVE_SET_VL_ONEXEC)
|
||||
ret = current->thread.sve_vl_onexec;
|
||||
else
|
||||
ret = current->thread.sve_vl;
|
||||
|
||||
if (test_thread_flag(TIF_SVE_VL_INHERIT))
|
||||
ret |= PR_SVE_VL_INHERIT;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* PR_SVE_SET_VL */
|
||||
int sve_set_current_vl(unsigned long arg)
|
||||
{
|
||||
unsigned long vl, flags;
|
||||
int ret;
|
||||
|
||||
vl = arg & PR_SVE_VL_LEN_MASK;
|
||||
flags = arg & ~vl;
|
||||
|
||||
if (!system_supports_sve())
|
||||
return -EINVAL;
|
||||
|
||||
ret = sve_set_vector_length(current, vl, flags);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return sve_prctl_status(flags);
|
||||
}
|
||||
|
||||
/* PR_SVE_GET_VL */
|
||||
int sve_get_current_vl(void)
|
||||
{
|
||||
if (!system_supports_sve())
|
||||
return -EINVAL;
|
||||
|
||||
return sve_prctl_status(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Bitmap for temporary storage of the per-CPU set of supported vector lengths
|
||||
* during secondary boot.
|
||||
|
Reference in New Issue
Block a user