[PATCH 3/5] arm64/sme: Support disabling streaming mode via ptrace on SME only systems

Mark Brown posted 5 patches 1 month, 2 weeks ago
[PATCH 3/5] arm64/sme: Support disabling streaming mode via ptrace on SME only systems
Posted by Mark Brown 1 month, 2 weeks ago
Currently it is not possible to disable streaming mode via ptrace on SME
only systems, the interface for doing this is to write via NT_ARM_SVE but
such writes will be rejected on a system without SVE support. Enable this
functionality by allowing userspace to write SVE_PT_REGS_FPSIMD format data
via NT_ARM_SVE with the vector length set to 0 on SME only systems. Such
writes currently error since we require that a vector length is specified
which should minimise the risk that existing software is relying on current
behaviour.

Reads are not supported since I am not aware of any use case for this and
there is some risk that an existing userspace application may be confused if
it reads NT_ARM_SVE on a system without SVE. Existing kernels will return
FPSIMD formatted register state from NT_ARM_SVE if full SVE state is not
stored, for example if the task has not used SVE. Returning a vector length
of 0 would create a risk that software would try to do things like allocate
space for register state with zero sizes, while returning a vector length of
128 bits would look like SVE is supported. It seems safer to just not make
the changes to add read support.

It remains possible for userspace to detect a SME only system via the ptrace
interface only since reads of NT_ARM_SSVE and NT_ARM_ZA will succeed while
reads of NT_ARM_SVE will fail. Read/write access to the FPSIMD registers in
non-streaming mode is available via REGSET_FPR.

sve_set_common() already avoids allocating SVE storage when doing a FPSIMD
formatted write and allocating SME storage when doing a NT_ARM_SVE write so
we change the function to validate the new case and skip setting a vector
length for it.

The aim is to make a minimally invasive change, no operation that would
previously have succeeded will be affected, and we use a previously
defined interface in new circumstances rather than define completely new
ABI.

Signed-off-by: Mark Brown <broonie@kernel.org>
---
 Documentation/arch/arm64/sve.rst |  5 +++++
 arch/arm64/kernel/ptrace.c       | 40 +++++++++++++++++++++++++++++++++-------
 2 files changed, 38 insertions(+), 7 deletions(-)

diff --git a/Documentation/arch/arm64/sve.rst b/Documentation/arch/arm64/sve.rst
index 28152492c29c..a61c9d0efe4d 100644
--- a/Documentation/arch/arm64/sve.rst
+++ b/Documentation/arch/arm64/sve.rst
@@ -402,6 +402,11 @@ The regset data starts with struct user_sve_header, containing:
   streaming mode and any SETREGSET of NT_ARM_SSVE will enter streaming mode
   if the target was not in streaming mode.
 
+* On systems that do not support SVE it is permitted to use SETREGSET to
+  write SVE_PT_REGS_FPSIMD formatted data via NT_ARM_SVE, in this case the
+  vector length should be specified as 0. This allows streaming mode to be
+  disabled on systems with SME but not SVE.
+
 * If any register data is provided along with SVE_PT_VL_ONEXEC then the
   registers data will be interpreted with the current vector length, not
   the vector length configured for use on exec.
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
index 4b001121c72d..b9bdd83fbbca 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c
@@ -912,13 +912,39 @@ static int sve_set_common(struct task_struct *target,
 		return -EINVAL;
 
 	/*
-	 * Apart from SVE_PT_REGS_MASK, all SVE_PT_* flags are consumed by
-	 * vec_set_vector_length(), which will also validate them for us:
+	 * On systems without SVE we accept FPSIMD format writes with
+	 * a VL of 0 to allow exiting streaming mode, otherwise a VL
+	 * is required.
 	 */
-	ret = vec_set_vector_length(target, type, header.vl,
-		((unsigned long)header.flags & ~SVE_PT_REGS_MASK) << 16);
-	if (ret)
-		return ret;
+	if (header.vl) {
+		/*
+		 * If the system does not support SVE we can't
+		 * configure a SVE VL.
+		 */
+		if (!system_supports_sve() && type == ARM64_VEC_SVE)
+			return -EINVAL;
+
+		/*
+		 * Apart from SVE_PT_REGS_MASK, all SVE_PT_* flags are
+		 * consumed by vec_set_vector_length(), which will
+		 * also validate them for us:
+		 */
+		ret = vec_set_vector_length(target, type, header.vl,
+					    ((unsigned long)header.flags & ~SVE_PT_REGS_MASK) << 16);
+		if (ret)
+			return ret;
+	} else {
+		/* If the system supports SVE we require a VL. */
+		if (system_supports_sve())
+			return -EINVAL;
+
+		/*
+		 * Only FPSIMD formatted data with no flags set is
+		 * supported.
+		 */
+		if (header.flags != SVE_PT_REGS_FPSIMD)
+			return -EINVAL;
+	}
 
 	/* Allocate SME storage if necessary, preserving any existing ZA/ZT state */
 	if (type == ARM64_VEC_SME) {
@@ -1016,7 +1042,7 @@ static int sve_set(struct task_struct *target,
 		   unsigned int pos, unsigned int count,
 		   const void *kbuf, const void __user *ubuf)
 {
-	if (!system_supports_sve())
+	if (!system_supports_sve() && !system_supports_sme())
 		return -EINVAL;
 
 	return sve_set_common(target, regset, pos, count, kbuf, ubuf,

-- 
2.39.5
Re: [PATCH 3/5] arm64/sme: Support disabling streaming mode via ptrace on SME only systems
Posted by Will Deacon 2 weeks, 1 day ago
On Wed, Aug 20, 2025 at 07:29:05PM +0100, Mark Brown wrote:
> Currently it is not possible to disable streaming mode via ptrace on SME
> only systems, the interface for doing this is to write via NT_ARM_SVE but
> such writes will be rejected on a system without SVE support. Enable this
> functionality by allowing userspace to write SVE_PT_REGS_FPSIMD format data
> via NT_ARM_SVE with the vector length set to 0 on SME only systems. Such
> writes currently error since we require that a vector length is specified
> which should minimise the risk that existing software is relying on current
> behaviour.
> 
> Reads are not supported since I am not aware of any use case for this and
> there is some risk that an existing userspace application may be confused if
> it reads NT_ARM_SVE on a system without SVE. Existing kernels will return
> FPSIMD formatted register state from NT_ARM_SVE if full SVE state is not
> stored, for example if the task has not used SVE. Returning a vector length
> of 0 would create a risk that software would try to do things like allocate
> space for register state with zero sizes, while returning a vector length of
> 128 bits would look like SVE is supported. It seems safer to just not make
> the changes to add read support.
> 
> It remains possible for userspace to detect a SME only system via the ptrace
> interface only since reads of NT_ARM_SSVE and NT_ARM_ZA will succeed while
> reads of NT_ARM_SVE will fail. Read/write access to the FPSIMD registers in
> non-streaming mode is available via REGSET_FPR.
> 
> sve_set_common() already avoids allocating SVE storage when doing a FPSIMD
> formatted write and allocating SME storage when doing a NT_ARM_SVE write so
> we change the function to validate the new case and skip setting a vector
> length for it.
> 
> The aim is to make a minimally invasive change, no operation that would
> previously have succeeded will be affected, and we use a previously
> defined interface in new circumstances rather than define completely new
> ABI.
> 
> Signed-off-by: Mark Brown <broonie@kernel.org>
> ---
>  Documentation/arch/arm64/sve.rst |  5 +++++
>  arch/arm64/kernel/ptrace.c       | 40 +++++++++++++++++++++++++++++++++-------
>  2 files changed, 38 insertions(+), 7 deletions(-)

It would be good to have an Ack from the userspace side (GDB?) so that
we know that the minimal ABI change you're proposing is sufficient.

In the meantime, I'll pick up the first two selftests as they are
independent of this part.

Will
Re: [PATCH 3/5] arm64/sme: Support disabling streaming mode via ptrace on SME only systems
Posted by Mark Brown 2 weeks, 1 day ago
On Thu, Sep 18, 2025 at 12:48:35PM +0100, Will Deacon wrote:

> It would be good to have an Ack from the userspace side (GDB?) so that
> we know that the minimal ABI change you're proposing is sufficient.

Yes, we need confirmation from the userspace side before this is merged.
I've had some informal feedback from some of the Arm people that was
positive but they needed to do some more thorough validation, and we
need feedback from people outside Arm too.

> In the meantime, I'll pick up the first two selftests as they are
> independent of this part.

Thanks.
Re: [PATCH 3/5] arm64/sme: Support disabling streaming mode via ptrace on SME only systems
Posted by Randy Dunlap 1 month, 2 weeks ago

On 8/20/25 11:29 AM, Mark Brown wrote:
> diff --git a/Documentation/arch/arm64/sve.rst b/Documentation/arch/arm64/sve.rst
> index 28152492c29c..a61c9d0efe4d 100644
> --- a/Documentation/arch/arm64/sve.rst
> +++ b/Documentation/arch/arm64/sve.rst
> @@ -402,6 +402,11 @@ The regset data starts with struct user_sve_header, containing:
>    streaming mode and any SETREGSET of NT_ARM_SSVE will enter streaming mode
>    if the target was not in streaming mode.
>  
> +* On systems that do not support SVE it is permitted to use SETREGSET to
> +  write SVE_PT_REGS_FPSIMD formatted data via NT_ARM_SVE, in this case the

s/,/;/
or
                                                 NT_ARM_SVE. In this case

> +  vector length should be specified as 0. This allows streaming mode to be
> +  disabled on systems with SME but not SVE.
> +
>  * If any register data is provided along with SVE_PT_VL_ONEXEC then the
>    registers data will be interpreted with the current vector length, not
>    the vector length configured for use on exec.

-- 
~Randy