Scalable Matrix Extension support for AArch64 Linux

This document outlines briefly the interface provided to userspace by Linux inorder to support use of the ARM Scalable Matrix Extension (SME).

This is an outline of the most important features and issues only and notintended to be exhaustive. It should be read in conjunction with the SVEdocumentation inScalable Vector Extension support for AArch64 Linux which provides details on the Streaming SVE modeincluded in SME.

This document does not aim to describe the SME architecture or programmer’smodel. To aid understanding, a minimal description of relevant programmer’smodel features for SME is included in Appendix A.

1. General

  • PSTATE.SM, PSTATE.ZA, the streaming mode vector length, the ZA and (whenpresent) ZTn register state and TPIDR2_EL0 are tracked per thread.

  • The presence of SME is reported to userspace via HWCAP2_SME in the aux vectorAT_HWCAP2 entry. Presence of this flag implies the presence of the SMEinstructions and registers, and the Linux-specific system interfacesdescribed in this document. SME is reported in /proc/cpuinfo as “sme”.

  • The presence of SME2 is reported to userspace via HWCAP2_SME2 in theaux vector AT_HWCAP2 entry. Presence of this flag implies the presence ofthe SME2 instructions and ZT0, and the Linux-specific system interfacesdescribed in this document. SME2 is reported in /proc/cpuinfo as “sme2”.

  • Support for the execution of SME instructions in userspace can also bedetected by reading the CPU ID register ID_AA64PFR1_EL1 using an MRSinstruction, and checking that the value of the SME field is nonzero. [3]

    It does not guarantee the presence of the system interfaces described in thefollowing sections: software that needs to verify that those interfaces arepresent must check for HWCAP2_SME instead.

  • There are a number of optional SME features, presence of these is reportedthrough AT_HWCAP2 through:

    HWCAP2_SME_I16I64HWCAP2_SME_F64F64HWCAP2_SME_I8I32HWCAP2_SME_F16F32HWCAP2_SME_B16F32HWCAP2_SME_F32F32HWCAP2_SME_FA64HWCAP2_SME2

    This list may be extended over time as the SME architecture evolves.

    These extensions are also reported via the CPU ID register ID_AA64SMFR0_EL1,which userspace can read using an MRS instruction. SeeARM64 ELF hwcaps andARM64 CPU Feature Registers for details.

  • Debuggers should restrict themselves to interacting with the target via theNT_ARM_SVE, NT_ARM_SSVE, NT_ARM_ZA and NT_ARM_ZT regsets. The recommendedway of detecting support for these regsets is to connect to a target processfirst and then attempt a

    ptrace(PTRACE_GETREGSET, pid, NT_ARM_<regset>, &iov).

  • Whenever ZA register values are exchanged in memory between userspace andthe kernel, the register value is encoded in memory as a series of horizontalvectors from 0 to VL/8-1 stored in the same endianness invariant format as isused for SVE vectors.

  • On thread creation PSTATE.ZA and TPIDR2_EL0 are preserved unless CLONE_VMis specified, in which case PSTATE.ZA is set to 0 and TPIDR2_EL0 is set to 0.

2. Vector lengths

SME defines a second vector length similar to the SVE vector length whichcontrols the size of the streaming mode SVE vectors and the ZA matrix array.The ZA matrix is square with each side having as many bytes as a streamingmode SVE vector.

3. System call behaviour

  • On syscall PSTATE.ZA is preserved, if PSTATE.ZA==1 then the contents of theZA matrix and ZTn (if present) are preserved.

  • On syscall PSTATE.SM will be cleared and the SVE registers will be handledas per the standard SVE ABI.

  • None of the SVE registers, ZA or ZTn are used to pass arguments toor receive results from any syscall.

  • On process creation (eg, clone()) the newly created process will havePSTATE.SM cleared.

  • All other SME state of a thread, including the currently configured vectorlength, the state of the PR_SME_VL_INHERIT flag, and the deferred vectorlength (if any), is preserved across all syscalls, subject to the specificexceptions for execve() described in section 6.

4. Signal handling

  • Signal handlers are invoked with PSTATE.SM=0, PSTATE.ZA=0, and TPIDR2_EL0=0.

  • A new signal frame record TPIDR2_MAGIC is added formatted as astructtpidr2_context to allow access to TPIDR2_EL0 from signal handlers.

  • A new signal frame record za_context encodes the ZA register contents onsignal delivery. [1]

  • The signal frame record for ZA always contains basic metadata, in particularthe thread’s vector length (in za_context.vl).

  • The ZA matrix may or may not be included in the record, depending onthe value of PSTATE.ZA. The registers are present if and only if:za_context.head.size >= ZA_SIG_CONTEXT_SIZE(sve_vq_from_vl(za_context.vl))in which case PSTATE.ZA == 1.

  • If matrix data is present, the remainder of the record has a vl-dependentsize and layout. Macros ZA_SIG_* are defined [1] to facilitate access tothem.

  • The matrix is stored as a series of horizontal vectors in the same format asis used for SVE vectors.

  • If the ZA context is too big to fit in sigcontext.__reserved[], then extraspace is allocated on the stack, an extra_context record is written in__reserved[] referencing this space. za_context is then written in theextra space. Refer to [1] for further details about this mechanism.

  • If ZTn is supported and PSTATE.ZA==1 then a signal frame record for ZTn willbe generated.

  • The signal record for ZTn has magic ZT_MAGIC (0x5a544e01) and consists of astandard signal frame header followed by astructzt_context specifyingthe number of ZTn registers supported by the system, then zt_context.nregsblocks of 64 bytes of data per register.

5. Signal return

When returning from a signal handler:

  • If there is no za_context record in the signal frame, or if the record ispresent but contains no register data as described in the previous section,then ZA is disabled.

  • If za_context is present in the signal frame and contains matrix data thenPSTATE.ZA is set to 1 and ZA is populated with the specified data.

  • The vector length cannot be changed via signal return. If za_context.vl inthe signal frame does not match the current vector length, the signal returnattempt is treated as illegal, resulting in a forced SIGSEGV.

  • If ZTn is not supported or PSTATE.ZA==0 then it is illegal to have asignal frame record for ZTn, resulting in a forced SIGSEGV.

6. prctl extensions

Some newprctl() calls are added to allow programs to manage the SME vectorlength:

prctl(PR_SME_SET_VL, unsigned long arg)

Sets the vector length of the calling thread and related flags, wherearg == vl | flags. Other threads of the calling process are unaffected.

vl is the desired vector length, where sve_vl_valid(vl) must be true.

flags:

PR_SME_VL_INHERIT

Inherit the current vector length across execve(). Otherwise, thevector length is reset to the system default at execve(). (SeeSection 9.)

PR_SME_SET_VL_ONEXEC

Defer the requested vector length change until the next execve()performed by this thread.

The effect is equivalent to implicit execution of the followingcall immediately after the next execve() (if any) by the thread:

prctl(PR_SME_SET_VL, arg & ~PR_SME_SET_VL_ONEXEC)

This allows launching of a new program with a different vectorlength, while avoiding runtime side effects in the caller.

Without PR_SME_SET_VL_ONEXEC, the requested change takes effectimmediately.

Return value: a nonnegative on success, or a negative value on error:
EINVAL: SME not supported, invalid vector length requested, or

invalid flags.

On success:

  • Either the calling thread’s vector length or the deferred vector lengthto be applied at the next execve() by the thread (dependent on whetherPR_SME_SET_VL_ONEXEC is present in arg), is set to the largest valuesupported by the system that is less than or equal to vl. If vl ==SVE_VL_MAX, the value set will be the largest value supported by thesystem.

  • Any previously outstanding deferred vector length change in the callingthread is cancelled.

  • The returned value describes the resulting configuration, encoded as forPR_SME_GET_VL. The vector length reported in this value is the newcurrent vector length for this thread if PR_SME_SET_VL_ONEXEC was notpresent in arg; otherwise, the reported vector length is the deferredvector length that will be applied at the next execve() by the callingthread.

  • Changing the vector length causes all of ZA, ZTn, P0..P15, FFR and allbits of Z0..Z31 except for Z0 bits [127:0] .. Z31 bits [127:0] to becomeunspecified, including both streaming and non-streaming SVE state.Calling PR_SME_SET_VL with vl equal to the thread’s current vectorlength, or calling PR_SME_SET_VL with the PR_SME_SET_VL_ONEXEC flag,does not constitute a change to the vector length for this purpose.

  • Changing the vector length causes PSTATE.ZA to be cleared.Calling PR_SME_SET_VL with vl equal to the thread’s current vectorlength, or calling PR_SME_SET_VL with the PR_SME_SET_VL_ONEXEC flag,does not constitute a change to the vector length for this purpose.

prctl(PR_SME_GET_VL)

Gets the vector length of the calling thread.

The following flag may be OR-ed into the result:

PR_SME_VL_INHERIT

Vector length will be inherited across execve().

There is no way to determine whether there is an outstanding deferredvector length change (which would only normally be the case between afork() orvfork() and the corresponding execve() in typical use).

To extract the vector length from the result, bitwise and it withPR_SME_VL_LEN_MASK.

Return value: a nonnegative value on success, or a negative value on error:

EINVAL: SME not supported.

7. ptrace extensions

  • A new regset NT_ARM_SSVE is defined for access to streaming mode SVEstate via PTRACE_GETREGSET and PTRACE_SETREGSET, this is documented inScalable Vector Extension support for AArch64 Linux.

  • A new regset NT_ARM_ZA is defined for ZA state for access to ZA state viaPTRACE_GETREGSET and PTRACE_SETREGSET.

    Refer to [2] for definitions.

The regset data starts withstructuser_za_header, containing:

size

Size of the complete regset, in bytes.This depends on vl and possibly on other things in the future.

If a call to PTRACE_GETREGSET requests less data than the value ofsize, the caller can allocate a larger buffer and retry in order toread the complete regset.

max_size

Maximum size in bytes that the regset can grow to for the targetthread. The regset won’t grow bigger than this even if the targetthread changes its vector length etc.

vl

Target thread’s current streaming vector length, in bytes.

max_vl

Maximum possible streaming vector length for the target thread.

flags

Zero or more of the following flags, which have the samemeaning and behaviour as the corresponding PR_SET_VL_* flags:

SME_PT_VL_INHERIT

SME_PT_VL_ONEXEC (SETREGSET only).

  • The effects of changing the vector length and/or flags are equivalent tothose documented for PR_SME_SET_VL.

    The caller must make a further GETREGSET call if it needs to know what VL isactually set by SETREGSET, unless is it known in advance that the requestedVL is supported.

  • The size and layout of the payload depends on the header fields. TheZA_PT_ZA*() macros are provided to facilitate access to the data.

  • In either case, for SETREGSET it is permissible to omit the payload, in whichcase the vector length and flags are changed and PSTATE.ZA is set to 0(along with any consequences of those changes). If a payload is providedthen PSTATE.ZA will be set to 1.

  • For SETREGSET, if the requested VL is not supported, the effect will be thesame as if the payload were omitted, except that an EIO error is reported.No attempt is made to translate the payload data to the correct layoutfor the vector length actually set. It is up to the caller to translate thepayload layout for the actual VL and retry.

  • The effect of writing a partial, incomplete payload is unspecified.

  • A new regset NT_ARM_ZT is defined for access to ZTn state viaPTRACE_GETREGSET and PTRACE_SETREGSET.

  • The NT_ARM_ZT regset consists of a single 512 bit register.

  • When PSTATE.ZA==0 reads of NT_ARM_ZT will report all bits of ZTn as 0.

  • Writes to NT_ARM_ZT will set PSTATE.ZA to 1.

  • If any register data is provided along with SME_PT_VL_ONEXEC then theregisters data will be interpreted with the current vector length, notthe vector length configured for use on exec.

8. ELF coredump extensions

  • NT_ARM_SSVE notes will be added to each coredump foreach thread of the dumped process. The contents will be equivalent to thedata that would have been read if a PTRACE_GETREGSET of the correspondingtype were executed for each thread when the coredump was generated.

  • A NT_ARM_ZA note will be added to each coredump for each thread of thedumped process. The contents will be equivalent to the data that would havebeen read if a PTRACE_GETREGSET of NT_ARM_ZA were executed for each threadwhen the coredump was generated.

  • A NT_ARM_ZT note will be added to each coredump for each thread of thedumped process. The contents will be equivalent to the data that would havebeen read if a PTRACE_GETREGSET of NT_ARM_ZT were executed for each threadwhen the coredump was generated.

  • The NT_ARM_TLS note will be extended to two registers, the second registerwill contain TPIDR2_EL0 on systems that support SME and will be read aszero with writes ignored otherwise.

9. System runtime configuration

  • To mitigate the ABI impact of expansion of the signal frame, a policymechanism is provided for administrators, distro maintainers and developersto set the default vector length for userspace processes:

/proc/sys/abi/sme_default_vector_length

Writing the text representation of an integer to this file sets the systemdefault vector length to the specified value rounded to a supported valueusing the same rules as for setting vector length via PR_SME_SET_VL.

The result can be determined by reopening the file and reading itscontents.

At boot, the default vector length is initially set to 32 or the maximumsupported vector length, whichever is smaller and supported. Thisdetermines the initial vector length of the init process (PID 1).

Reading this file returns the current system default vector length.

  • At every execve() call, the new vector length of the new process is set tothe system default vector length, unless

    • PR_SME_VL_INHERIT (or equivalently SME_PT_VL_INHERIT) is set for thecalling thread, or

    • a deferred vector length change is pending, established via thePR_SME_SET_VL_ONEXEC flag (or SME_PT_VL_ONEXEC).

  • Modifying the system default vector length does not affect the vector lengthof any existing process or thread that does not make an execve() call.

Appendix A. SME programmer’s model (informative)

This section provides a minimal description of the additions made by SME to theARMv8-A programmer’s model that are relevant to this document.

Note: This section is for information only and not intended to be complete orto replace any architectural specification.

A.1. Registers

In A64 state, SME adds the following:

  • A new mode, streaming mode, in which a subset of the normal FPSIMD and SVEfeatures are available. When supported EL0 software may enter and leavestreaming mode at any time.

    For best system performance it is strongly encouraged for software to enablestreaming mode only when it is actively being used.

  • A new vector length controlling the size of ZA and the Z registers when instreaming mode, separately to the vector length used for SVE when not instreaming mode. There is no requirement that either the currently selectedvector length or the set of vector lengths supported for the two modes ina given system have any relationship. The streaming mode vector lengthis referred to as SVL.

  • A new ZA matrix register. This is a square matrix of SVLxSVL bits. Mostoperations on ZA require that streaming mode be enabled but ZA can beenabled without streaming mode in order to load, save and retain data.

    For best system performance it is strongly encouraged for software to enableZA only when it is actively being used.

  • A new ZT0 register is introduced when SME2 is present. This is a 512 bitregister which is accessible when PSTATE.ZA is set, as ZA itself is.

  • Two new 1 bit fields in PSTATE which may be controlled via the SMSTART andSMSTOP instructions or by access to the SVCR system register:

    • PSTATE.ZA, if this is 1 then the ZA matrix is accessible and has validdata while if it is 0 then ZA can not be accessed. When PSTATE.ZA ischanged from 0 to 1 all bits in ZA are cleared.

    • PSTATE.SM, if this is 1 then the PE is in streaming mode. When the valueof PSTATE.SM is changed then it is implementation defined if the subsetof the floating point register bits valid in both modes may be retained.Any other bits will be cleared.

References

[1] arch/arm64/include/uapi/asm/sigcontext.h

AArch64 Linux signal ABI definitions

[2] arch/arm64/include/uapi/asm/ptrace.h

AArch64 Linux ptrace ABI definitions

[3]ARM64 CPU Feature Registers