资讯动态

Linux 内核 SME 支持指南:AArch64 可扩展矩阵扩展的用户态接口全解析

发布时间:2026/9/12 4:20:44 来源:尧图企业网站定制
Linux 内核 SME 支持指南AArch64 可扩展矩阵扩展的用户态接口全解析【免费下载链接】linuxLinux kernel source tree项目地址: https://gitcode.com/GitHub_Trending/li/linux本文围绕 Linux 内核为 ARM Scalable Matrix ExtensionSME提供的用户态接口展开覆盖特性检测HWCAP2_SME、Streaming SVE 模式、ZA/ZT 寄存器状态管理、系统调用与信号处理语义、prctl/ptrace 扩展以及 coredump 与运行时配置。读者读完后可以完整掌握在 AArch64 Linux 上检测 SME 硬件、配置流式向量长度SVL、通过信号帧与调试接口读写 ZA/ZT 状态的实战方法并理解其与 SVE 文档 sve.rst 中 Streaming SVE 模式的衔接关系。1. 概述SME 为 AArch64 Linux 带来了什么ARM 可扩展矩阵扩展SME在 ARMv8-A以及后续 ARMv9体系结构之上新增了流式模式streaming mode、ZA 矩阵寄存器以及在 SME2 中ZT 寄存器面向矩阵运算与 AI/ML 工作负载。Linux 内核在 AArch64 上为 SME 提供了完整的用户态支持包括线程级状态跟踪、信号帧扩展、prctl/ptrace 接口、ELF coredump 以及系统级默认向量长度配置。内核态的实现分布在 arch/arm64/kernel/fpsimd.c状态分配与向量长度管理、arch/arm64/kernel/signal.c信号帧编解码与 arch/arm64/kernel/ptrace.c调试接口等文件中。SME 文档本身并不试图描述 SME 的完整体系结构或编程模型而是聚焦 Linux 提供给用户态的接口约定建议与 sve.rst 配合阅读后者详细说明了 SME 所包含的 Streaming SVE 模式。1.1 逐线程跟踪的状态以下状态在内核中按线程thread粒度跟踪PSTATE.SM流式模式标志PSTATE.ZAZA 矩阵使能标志流式模式向量长度streaming mode vector length即 SVLZA 寄存器以及若支持时ZTn 寄存器状态TPIDR2_EL0系统寄存器这些状态随线程创建、调度与切换由内核保存和恢复。1.2 SME 与 SME2 的存在性报告SME 的存在通过 aux vector 的AT_HWCAP2条目中的HWCAP2_SME位报告给用户态。该标志的存在意味着 SME 指令、寄存器以及本文档描述的所有 Linux 特有系统接口均可用。/proc/cpuinfo中相应显示为sme。SME2 的存在则通过HWCAP2_SME2报告同样写入/proc/cpuinfo的sme2标志位其含义是 SME2 指令与 ZT0 寄存器以及相关系统接口均可用。相关位定义见 arch/arm64/include/uapi/asm/hwcap.h。此外还可以通过 MRS 指令读取 CPU ID 寄存器ID_AA64PFR1_EL1检查其 SME 字段是否为非零值来判断用户态能否执行 SME 指令。但这不能保证本文档下述系统接口一定存在——需要验证这些接口的软件必须检查HWCAP2_SME。1.3 可选 SME 特性SME 有一系列可选特性通过AT_HWCAP2中的下列位报告HWCAP2_SME_I16I64 HWCAP2_SME_F64F64 HWCAP2_SME_I8I32 HWCAP2_SME_F16F32 HWCAP2_SME_B16F32 HWCAP2_SME_F32F32 HWCAP2_SME_FA64 HWCAP2_SME2该列表会随 SME 体系结构演进而扩展。从当前内核源码看SME 特性家族已进一步扩充到HWCAP2_SME2P1、HWCAP2_SME_I16I32、HWCAP2_SME_BI32I32、HWCAP2_SME_B16B16、HWCAP2_SME_F16F16、HWCAP2_SME_LUTV2、HWCAP2_SME_F8F16、HWCAP2_SME_F8F32、HWCAP2_SME_SF8FMA、HWCAP2_SME_SF8DP4、HWCAP2_SME_SF8DP2等见 hwcap.h 与 elf_hwcaps.rst。这些扩展同样可通过 MRS 读取ID_AA64SMFR0_EL1获取详细能力信息可参考 elf_hwcaps.txt 与 cpu-feature-registers.rst。1.4 调试器注意事项调试器应当只通过NT_ARM_SVE、NT_ARM_SSVE、NT_ARM_ZA和NT_ARM_ZT这几个 regset 与被调试目标交互。推荐的检测这些 regset 是否受支持的方式是先连接到目标进程然后尝试执行ptrace(PTRACE_GETREGSET, pid, NT_ARM_regset, iov)通过返回值判断该 regset 是否可用。1.5 ZA 寄存器值的内存编码每当 ZA 寄存器值在内核与用户态之间通过内存交换时寄存器值被编码为一系列水平向量horizontal vectors编号从 0 到 VL/8-1采用与 SVE 向量相同的端序不变endianness-invariant格式。换言之ZA 矩阵按行存储每行长度等于流式模式向量长度。1.6 线程创建时的状态继承创建线程clone时PSTATE.ZA与TPIDR2_EL0默认被保留但若指定了CLONE_VM则PSTATE.ZA被清零、TPIDR2_EL0也被清零。2. 向量长度SVL 与 VL 的关系SME 定义了一个与 SVE 向量长度类似的第二向量长度它控制流式模式下 SVE 向量的大小以及 ZA 矩阵数组的大小。ZA 矩阵是方阵其每边的字节数等于一个流式模式 SVE 向量的字节数即 SVL。因此非流式 SVE 向量长度VL与流式模式向量长度SVL相互独立两者在同一个系统上支持的向量长度集合也没有任何必然关系内核沿用 SVE 文档中的约定VL 表示 Z 寄存器以字节计的大小VQ 表示以 128 位为单位的大小VL 16 × VQ见 sve.rst有关sve_vl_valid()、sve_vq_from_vl()等辅助宏定义在 arch/arm64/include/uapi/asm/sigcontext.h 中。3. 系统调用行为SME 对系统调用的影响可以概括为以下几条明确的 ABI 规则PSTATE.ZA 在系统调用期间被保留如果进入系统调用时PSTATE.ZA1则 ZA 矩阵和 ZTn若存在的内容被保留。PSTATE.SM 在系统调用期间被清除进入系统调用后处理器退出流式模式SVE 寄存器按标准 SVE ABI 处理即除 V0..V31 的 [127:0] 位之外Z 寄存器高位与谓词寄存器在返回时清零。任何 SVE 寄存器、ZA 或 ZTn 都不用于传递系统调用参数或接收结果。进程创建如 clone()时新进程的PSTATE.SM被清除。线程的其他所有 SME 状态——包括当前配置的向量长度、PR_SME_VL_INHERIT标志状态以及若存在的延迟向量长度——在所有系统调用中均被保留唯一的例外是第 6 节描述的execve()特殊情况。4. 信号处理Signal delivery信号处理程序被调用时处理器状态按如下规则重置PSTATE.SM0、PSTATE.ZA0、TPIDR2_EL00新增信号帧记录TPIDR2_MAGIC其格式为struct tpidr2_context用于让信号处理程序访问TPIDR2_EL0。该结构的定义位于 arch/arm64/include/uapi/asm/sigcontext.hTPIDR2_MAGIC值为0x54504902新增信号帧记录za_context编码信号投递时的 ZA 寄存器内容其 magic 为ZA_MAGIC0x54366345结构体定义见 sigcontext.h。关于 ZA 信号帧记录有以下关键语义ZA 记录始终包含基本元数据特别是线程的向量长度存于za_context.vlZA 矩阵可能包含在记录中也可能不包含取决于PSTATE.ZA的值。寄存器数据存在的充要条件是za_context.head.size ZA_SIG_CONTEXT_SIZE(sve_vq_from_vl(za_context.vl))此时PSTATE.ZA 1若矩阵数据存在记录的其余部分具有依赖 vl 的大小与布局可使用ZA_SIG_*宏族访问这些宏定义在 sigcontext.h例如ZA_SIG_REGS_SIZE(vq)计算矩阵数据大小ZA_SIG_ZAV_OFFSET(vq, n)定位第 n 个水平向量矩阵以一系列水平向量的形式存储格式与 SVE 向量相同若 ZA 上下文过大、放不进sigcontext.__reserved[]内核会在栈上额外分配空间并在__reserved[]中写入extra_context记录来引用该空间za_context随后被写入额外空间extra_context的机制说明见 sigcontext.h若系统支持 ZTn 且PSTATE.ZA1则还会生成 ZTn 的信号帧记录。ZT 记录 magic 为ZT_MAGIC0x5a544e01由标准信号帧头加struct zt_context组成zt_context.nregs指明系统支持的 ZTn 寄存器个数其后跟随 nregs 个每寄存器 64 字节的数据块。相关宏ZT_SIG_REGS_SIZE(n)与ZT_SIG_CONTEXT_SIZE(n)见 sigcontext.h。5. 信号返回Signal return从信号处理程序返回sigreturn时内核依据信号帧中的记录执行以下规则若信号帧中没有za_context记录或记录存在但不含寄存器数据按第 4 节判定则 ZA 被禁用若za_context存在且包含矩阵数据则PSTATE.ZA被置 1ZA 以指定数据填充向量长度不能在信号返回时改变若信号帧中za_context.vl与当前向量长度不匹配本次信号返回被视为非法导致强制SIGSEGV若系统不支持 ZTn或PSTATE.ZA0则信号帧中出现 ZTn 记录是非法的同样导致强制SIGSEGV。这些约束与 SVE 的sve_context.vl规则一致见 sve.rst保证内核在返回路径上无需做向量长度换算。6. prctl 扩展管理 SME 向量长度内核新增了两个 prctl() 调用供程序管理 SME流式模式向量长度相关常量定义于 include/uapi/linux/prctl.h#define PR_SME_SET_VL 63 #define PR_SME_GET_VL 64 #define PR_SME_SET_VL_ONEXEC (1 18) #define PR_SME_VL_INHERIT (1 17)6.1 prctl(PR_SME_SET_VL, unsigned long arg)设置调用线程的向量长度及相关标志其中arg vl | flags。调用进程的其他线程不受影响。vl为期望的向量长度必须满足sve_vl_valid(vl)支持以下 flags标志含义PR_SME_VL_INHERIT在execve()时继承当前向量长度否则execve()时向量长度被重置为系统默认值见第 9 节PR_SME_SET_VL_ONEXEC将本次向量长度变更延迟到该线程的下一次execve()。等效于在该线程下一次execve()之后立即隐式执行prctl(PR_SME_SET_VL, arg ~PR_SME_SET_VL_ONEXEC)。这允许以不同的向量长度启动新程序同时避免对调用者有运行时副作用。不带该标志时变更立即生效返回值成功时返回非负值出错返回负值。EINVAL表示SME 不受支持、请求的向量长度非法或标志非法。成功时的语义调用线程的向量长度或下一次execve()时应用的延迟向量长度取决于 arg 中是否含PR_SME_SET_VL_ONEXEC被设置为系统支持且小于等于 vl 的最大值若vl SVE_VL_MAX则设置为系统支持的最大值调用线程此前任何未决的延迟向量长度变更被取消返回值描述最终配置编码方式与PR_SME_GET_VL相同若 arg 不含PR_SME_SET_VL_ONEXEC返回值中的向量长度是线程新的当前向量长度否则是将在下一次execve()时应用的延迟向量长度改变向量长度会导致 ZA、ZTn、P0..P15、FFR 以及 Z0..Z31 中除 bits [127:0] 之外的所有位变为未指定值包括流式与非流式 SVE 状态。以等于线程当前向量长度的 vl 调用PR_SME_SET_VL或带PR_SME_SET_VL_ONEXEC标志调用不视为向量长度改变改变向量长度会导致 PSTATE.ZA 被清除。同样上述两种非变更调用不会清除 PSTATE.ZA。6.2 prctl(PR_SME_GET_VL)获取调用线程的向量长度。返回值可 OR 上PR_SME_VL_INHERIT标志表示向量长度将在execve()时被继承没有方法可以获知是否存在未决的延迟向量长度变更在典型用法中这种情况只出现在fork()/vfork()与对应execve()之间提取向量长度时将返回值与PR_SME_VL_LEN_MASK按位与即可返回值成功返回非负值出错返回负值。EINVAL表示 SME 不受支持。7. ptrace 扩展访问 ZA 与 ZTn 状态针对调试器与运行时内核新增了以下 regset用于PTRACE_GETREGSET与PTRACE_SETREGSET数值定义见 include/uapi/linux/elf.hNT_ARM_SSVE 0x40b /* ARM Streaming SVE registers */ NT_ARM_ZA 0x40c /* ARM SME ZA registers */ NT_ARM_ZT 0x40d /* ARM SME ZT registers */NT_ARM_SSVE用于访问流式模式 SVE 状态详见 sve.rstNT_ARM_ZA用于访问 ZA 状态。7.1 NT_ARM_ZA regset 布局regset 数据以struct user_za_header开头定义见 arch/arm64/include/uapi/asm/ptrace.h包含字段含义size完整 regset 的字节数依赖 vl未来可能依赖其他因素。若PTRACE_GETREGSET请求的数据量小于 size调用者可分配更大的缓冲区重试max_size目标线程的 regset 可以增长到的最大字节数。即使目标线程改变向量长度等regset 也不会超过该值vl目标线程当前的流式向量长度字节max_vl目标线程可能的最大流式向量长度flags零个或多个下列标志语义与对应的PR_SET_VL_*标志相同SME_PT_VL_INHERIT、SME_PT_VL_ONEXEC仅 SETREGSET 有效补充要点改变向量长度和/或标志的效果与PR_SME_SET_VL文档化行为等价调用者若需确知 SETREGSET 实际设置的 VL必须再次执行 GETREGSET除非事先已知所请求的 VL 受支持数据载荷的大小与布局取决于头字段ZA_PT_ZA*()宏族如ZA_PT_ZA_OFFSET、ZA_PT_ZA_SIZE(vq)、ZA_PT_SIZE(vq)见 ptrace.h用于访问数据。ZA 数组按 SVL/8 字节的水平向量 ZAV 序列存储从向量 0 开始采用端序不变布局对 SETREGSET允许省略载荷此时只改变向量长度与标志并将PSTATE.ZA置 0连同这些变更的后果。若提供了载荷则PSTATE.ZA被置 1对 SETREGSET若请求的 VL 不受支持效果与省略载荷相同但会报告EIO错误内核不会尝试将载荷数据转换到实际设置的向量长度的布局需要调用者自行转换载荷布局后重试写入不完整载荷的效果未定义。7.2 NT_ARM_ZT regsetNT_ARM_ZT用于访问 ZTn 状态该 regset 由单个 512 位寄存器组成当PSTATE.ZA0时读取NT_ARM_ZT报告 ZTn 的所有位为 0写入NT_ARM_ZT会将PSTATE.ZA置 1若在提供SME_PT_VL_ONEXEC的同时提供了寄存器数据则寄存器数据以当前向量长度解释而不是以 exec 时配置的向量长度解释。8. ELF coredump 扩展每个被 dump 进程的每个线程其 coredump 中会追加以下 notesNT_ARM_SSVEnote内容等价于生成 coredump 时对相应线程执行PTRACE_GETREGSET所读到的数据NT_ARM_ZAnote内容等价于对每个线程执行PTRACE_GETREGSETNT_ARM_ZA读到的数据NT_ARM_ZTnote内容等价于对每个线程执行PTRACE_GETREGSETNT_ARM_ZT读到的数据NT_ARM_TLSnote 扩展为两个寄存器第二个寄存器在支持 SME 的系统上包含TPIDR2_EL0否则读为 0、写入被忽略。9. 系统运行时配置默认向量长度为缓解信号帧扩展带来的 ABI 影响内核为管理员、发行版维护者和开发者提供了策略机制用于设置用户态进程的默认向量长度/proc/sys/abi/sme_default_vector_length向该文件写入整数的文本表示即把系统默认向量长度设置为该值并按照与PR_SME_SET_VL相同的规则舍入到受支持的值设置结果可通过重新打开并读取该文件来确认开机时默认向量长度初始设置为32 或系统支持的最大向量长度中较小且受支持的值这决定了 init 进程PID 1的初始向量长度对比 SVE 默认值为 64见 sve.rst读取该文件返回当前系统默认向量长度。内核侧该 sysctl 由 arch/arm64/kernel/fpsimd.c 中的sme_default_vl_table注册procname 为sme_default_vector_lengthmode 0644处理器为vec_proc_do_default_vl且仅在CONFIG_ARM64_SME CONFIG_SYSCTL且system_supports_sme()为真时注册。execve() 时的向量长度规则每次execve()时新进程的向量长度被设置为系统默认向量长度除非满足以下任一条件调用线程设置了PR_SME_VL_INHERIT等价于SME_PT_VL_INHERIT存在通过PR_SME_SET_VL_ONEXEC或SME_PT_VL_ONEXEC建立的未决延迟向量长度变更。注意修改系统默认向量长度不会影响任何不执行execve()的既有进程或线程的向量长度。附录 A. SME 编程模型要点informative本节给出与本文档相关的 SME 对 ARMv8-A 编程模型增补的最小描述仅供理解使用不完整、也不替代任何体系结构规范。A.1 寄存器与状态在 A64 状态下SME 新增了以下内容流式模式streaming mode在该模式下正常 FPSIMD 与 SVE 功能的一个子集可用。受支持的 EL0 软件可以随时进入和退出流式模式。为获得最佳系统性能强烈建议软件仅在活跃使用流式模式时才启用它新的向量长度控制流式模式下 ZA 与 Z 寄存器的大小与非流式SVE 使用的向量长度相互独立。系统对两种模式各自支持的向量长度集合之间没有任何关系要求。流式模式向量长度记作SVLZA 矩阵寄存器一个 SVL×SVL 位的方阵。多数 ZA 操作要求启用流式模式但 ZA 可以在不进入流式模式的情况下使能以便加载、保存和保留数据。同样建议仅在活跃使用时才启用 ZAZT0 寄存器SME2 引入一个 512 位寄存器与 ZA 一样在PSTATE.ZA置位时可访问PSTATE 中两个新的 1 位字段可通过SMSTART/SMSTOP指令或访问 SVCR 系统寄存器控制PSTATE.ZA为 1 时 ZA 矩阵可访问且包含有效数据为 0 时 ZA 不可访问。当PSTATE.ZA从 0 变为 1 时ZA 所有位被清零PSTATE.SM为 1 时 PE 处于流式模式。当PSTATE.SM改变时两种模式下均有效的那部分浮点寄存器位是否保留是实现定义的其他位将被清零。A.2 与 SVE 文档的衔接SME 中的流式模式使用与 SVE 相同的 Z/V 寄存器但采用独立的向量长度并且通过信号帧中sve_context.flags的SVE_SIG_FLAG_SM标志值为 0x1见 sigcontext.h标识记录描述的是流式数据。涉及 Streaming SVE 的寄存器访问、调试器 regset 语义如NT_ARM_SSVE与NT_ARM_SVE的流式/非流式切换规则均以 sve.rst 为准。参考资料[1] arch/arm64/include/uapi/asm/sigcontext.h —— AArch64 Linux 信号 ABI 定义[2] arch/arm64/include/uapi/asm/ptrace.h —— AArch64 Linux ptrace ABI 定义[3] Documentation/arch/arm64/cpu-feature-registers.rst配套文档Documentation/arch/arm64/sve.rstSVE/Streaming SVE、Documentation/arch/arm64/elf_hwcaps.rstHWCAP 位说明内核实现状态分配与 sysctl 见 arch/arm64/kernel/fpsimd.c信号帧编解码见 arch/arm64/kernel/signal.cptrace regset 见 arch/arm64/kernel/ptrace.c【免费下载链接】linuxLinux kernel source tree项目地址: https://gitcode.com/GitHub_Trending/li/linux创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价