Arm 架构支持

(重定向自 )
跳转到:导航搜索

对于非 openSUSE 相关的概述,您可以查看

在 openSUSE 上,各种 arm 功能可以

  • 已支持:
    • 如果软件包版本支持,并且选项在构建时已启用(并且您的硬件支持它)
  • 不支持:
    • 如果软件包版本不支持
    • 如果选项在构建时被禁用

ARMv8.0 强制功能

ARMv8.0 - FP(浮点)

版本:15.1+ 默认启用。


ARMv8.0 - SIMD(单指令多数据)

版本:15.1+ 默认启用。


附加/可选 ARMv8 功能

以下选项对于 ARMv8.0 是可选的,或者属于后续架构(8.1、8.2 等)。其中一些选项可以在运行时检测,并且仅在可用时使用,开销很小,因此可以安全地启用,但另一些选项会破坏旧硬件,默认情况下未启用,但如果需要,可以手动使用。

ARMv8.1 - CRC32

版本:15.1+ 默认禁用。


CRC32 是 ARMv8.0 中的可选扩展,在 ARMv8.1 中是强制性的,用于计算循环冗余校验 (CRC)。使用 GCC 时,需要将 +crc 传递给 -march 标志。

如果您的硬件支持,您应该在内核日志中找到以下行

CPU features: detected: CRC32 instructions

ARMv8.1 - PAN(特权访问永不)

版本:15.1+ 默认启用。


PAN 是一种额外的安全机制,用于防止潜在的软件攻击。它阻止内核或虚拟机监视器直接访问用户空间 (EL0) 内存。此选项将导致任何未受保护的(未使用 copy_to_user 等)内存访问因权限错误而失败。

如果您的硬件支持,您应该在内核日志中找到以下行

CPU features: detected: Privileged Access Never

ARMv8.1 - LSE(大型系统扩展)原子操作

版本:Tumbleweed 默认完全启用。


原子指令可以用作替代方案,以替代加载-独占/存储-独占 (ldx/stx) 指令 (ARMv8.0),以改进非常大的系统中原子内存更新的实现。LSE 原子操作通常比旧原子操作更公平。此外,LSE 原子操作已被发现更快(平均时间更短)并且性能更一致(运行之间的方差也更低)。

使用 GCC 9.3.1+,您可以使用 -moutline-atomics-mno-outline-atomics 在运行时选择正确的路径来启用/禁用行内原子操作。

使用 GCC 10.1+,默认情况下启用行内原子操作,因此 Tumbleweed 自 20200602 快照以来已启用。

使用 GCC13,LSE(和 LSE2)已添加到 libatomic,这会禁用行内原子操作,并为 1-8 字节原子操作使用 LSE ifuncs(以及为 16 字节原子操作使用 LSE2 ifuncs)。

如果您想使用 qemu 进行测试,而您的主机不支持它,请使用 -cpu max 并禁用 kvm(速度慢),请注意您需要 qemu 3.0 或更高版本

如果您的硬件支持,您应该在内核日志中找到以下行

CPU features: detected: LSE atomic instructions

ARMv8.2 - SVE(可扩展向量扩展)

版本:15.1+ 默认禁用,需要 gcc8 显式选项。


SVE 是 AArch64 的下一代 SIMD 指令集,包括可扩展的向量长度。

使用 GCC8+,您可以通过将 +sve 添加到 -march=xyz-mcpu=xyz 来启用 SVE 支持。由于 SVE 仅受 ARMv8.2+ 硬件支持,因此默认情况下未启用。

如果您想使用 qemu 进行测试,而您的主机不支持它,请使用 -cpu max 并禁用 kvm(速度慢),请注意您需要 qemu 3.1 或更高版本

如果您的硬件支持,您应该在内核日志中找到以下行

CPU features: detected: Scalable Vector Extension
SVE: maximum available vector length 256 bytes per vector
SVE: default vector length 64 bytes per vector

ARMv8.2 - FP16/FPHP(半精度浮点)

版本:15.1+ 默认禁用,需要 gcc7 显式选项。


FP16 是一种半精度浮点格式(在 16 位上),ARMv8.2 上是可选的。

使用 GCC7+,您可以通过将 +fp16 添加到 -march=xyz-mcpu=xyz 来启用 FP16 支持。由于 FP16 仅受某些 ARMv8.2+ 硬件支持,因此默认情况下未启用。

ARMv8.3 - PAuth(指针认证)

在 ARMv8.3 硬件及更高版本上,它允许使用密钥对指针进行签名和认证。指针认证的目的是减轻 ROP 攻击和其他潜在的缓冲区溢出式攻击。

有关更多信息,您可以观看 SUSE Labs 2019 发布的关于指针认证的视频:https://www.youtube.com/watch?v=iW3mXDSijSQ

如果您的硬件支持,您应该在内核日志中找到以下行

CPU features: detected: Address authentication (architected algorithm)
CPU features: detected: Generic authentication (architected algorithm)

如果您想使用 qemu 进行测试,而您的主机不支持它,请使用 -M virt -cpu max 并禁用 kvm(速度慢),请注意您需要 qemu 4.0 或更高版本。为了提高指针认证算法的速度,您可以使用 -M virt -cpu max,pauth-impdef=true

内核 5.12 添加了使用 arm64.nopauth 禁用指针认证的功能。请参阅:commit f8da5752

指针认证 - 用户空间支持

版本:15.2+ 默认禁用。

版本:Tumbleweed 默认启用。


Tumbleweed 和 Leap 15.2 内核上启用用户空间支持。要使用它,您只需要将 -mbranch-protection=pac-ret[+leaf]-mbranch-protection=standard(也启用 BTI)选项传递给 GCC(旧的 GCC 可以使用 -msign-return-address,但 GCC9 中已弃用)。

强烈建议使用 elfutils 0.181GCC 10.2 及更高版本 来启用指针认证,因为它们包含必需的修复程序!

-mbranch-protection=standard 已在 2020 年 11 月 20 日星期五为 aarch64 在 Factory 中启用。包含此选项的第一个 Tumbleweed 快照是 snapshot 20201129。如果软件包无法使用此选项正确构建,请将其报告给上游。作为解决方法,您可以删除此选项,如 llvm7 中所做的那样:https://build.opensuse.org/request/show/850379

指针认证 - 内核空间支持

版本:Tumbleweed 默认启用


内核空间支持已合并到内核 5.7 中,因此 Leap 尚不支持它,但它在 Tumbleweed 上默认启用,自 20200612 快照以来。

ARMv8.3/8.4 - NV(嵌套虚拟化)

ARMv8.3+ 上的嵌套虚拟化补丁尚未包含在上游内核中。

ARMv8.4 - LSE2(大型系统扩展)原子操作

版本:Tumbleweed 默认完全启用。


GCC13 将对 libatomic 的 LSE 和 LSE2 的支持添加到 libatomic。这将禁用行内原子操作,并为 1-8 字节原子操作使用 LSE ifuncs,为 16 字节原子操作使用 LSE2 ifuncs。在 Neoverse V1 上,由于避免了锁,16 字节原子操作速度提高了约 4 倍。

Qemu 尚未支持它(版本 7.2.0)

如果您的硬件支持,您应该在内核日志中找到以下行

CPU features: detected: LSE2 atomic instructions


ARMv8.5 - BTI(分支目标识别)

版本:Tumbleweed 默认启用(在内核和用户空间中)


在 ARMv8.5 硬件及更高版本上,它允许使用密钥对分支目标进行签名和认证。

初始支持已添加到 GCC 9,但强烈建议使用 GCC 10.2 及更高版本或 LLVM 10.0.1 及更高版本来启用 BTI,因为它们包含许多修复程序!

您可以通过将 -mbranch-protection=bti-mbranch-protection=standardstandard 也启用指针认证和 GCS(如果可用))添加到 GCC 来启用 BTI 支持。自 2020 年 8 月 21 日的快照(内核 5.8)以来,已在内核配置中启用。

如果您的硬件支持,您应该在内核日志中找到以下行

CPU features: detected: Branch Target Identification

对于用户空间,-mbranch-protection=standard 已在 2020 年 11 月 20 日星期五为 aarch64 在 Factory 中启用。包含此选项的第一个 Tumbleweed 快照是 snapshot 20201129。如果软件包无法使用此选项正确构建,请将其报告给上游。作为解决方法,您可以删除此选项,如 llvm7 中所做的那样:https://build.opensuse.org/request/show/850110

内核 5.12 添加了使用 arm64.nobti 禁用 BTI 的功能。请参阅:commit 93ad55b7852

如果您想使用 qemu 进行测试,而您的主机不支持它,请使用 -M virt -cpu max 并禁用 kvm(速度慢),请注意您需要 qemu 4.0 或更高版本

ARMv8.5 - MTE(内存标记扩展)

Arm MTE 实现了对内存的锁定和密钥访问。可以对内存设置锁,并在内存访问期间提供密钥。如果密钥与锁匹配,则允许访问。如果不匹配,则报告错误。

更多详细信息请参阅 Arm_Memory_Tagging_Extension_Whitepaper.pdf

MTE 将允许 标记。目前只有 标记准备就绪。

堆标记

堆标记启用需要内核配置更新

  • CONFIG_ARM64_MTE 在 5.10+ 中:用户空间启用 标记(Tumbleweed 自 20210108 快照以来)
  • CONFIG_KASAN_HW_TAGS 在 5.11+ 版本中:内核启用堆标签(仅同步)。在 5.13+ 版本中,已添加 KASan 的 MTE 异步支持。异步速度更快,但无法精确识别非法访问。
用户空间支持

版本:Tumbleweed 用户空间自 快照 20210223 起启用


glibc 2.33+(Tumbleweed 中的快照 20210221 起)会检查 hwcap 以根据硬件功能使用或不使用它。glibc 2.34 将包含一些性能增强:http://patches-tcwg.linaro.org/cover/50130/
您还需要为 glibc 设置一个环境变量

export GLIBC_TUNABLES=”glibc.mem.tagging=X”

其中 X 的值根据上游文档设置

This tunable takes a value between 0 and 255 and acts as a bitmask
that enables various capabilities.

Bit 0 (the least significant bit) causes the malloc subsystem to allocate
tagged memory, with each allocation being assigned a random tag.

Bit 1 enables precise faulting mode for tag violations on systems that
support deferred tag violation reporting.  This may cause programs
to run more slowly.

Other bits are currently reserved.

您还需要为 Python 设置另一个环境变量

  • Python pymalloc 尚不兼容 MTE,因此 Python 不应使用 pymalloc,而应使用 glibc malloc。为此,您可以设置 PYTHONMALLOC 环境变量
 export PYTHONMALLOC=malloc

上游错误报告:https://bugs.python.org/issue43593


请注意,需要 GCC10+ 和 LLVM9+ 才能使用 MTE 编译 glibc/内核。

如果您的硬件支持,您应该在内核日志中找到以下行

CPU features: detected: Memory Tagging Extension

如果您想使用 qemu 进行测试,请注意您需要 qemu 5.1 或更高版本。然后,您需要使用 -M virt,mte=on -cpu max 显式启用它,并禁用 kvm(速度慢)。

您可以尝试以下用 C 编写的简单测试程序:(不需要 gcc 选项,因为它使用 glibc 中已启用的功能)

#include <stdlib.h>
 
/* Generate an MTE fault for a UAF (Use-After-Free):
 * - Use qemu with '-machine virt,mte=on -cpu max' _without_ kvm
 * - export GLIBC_TUNABLES="glibc.mem.tagging=X"
 *   where X has the following meanings:
 *     0        Disabled (default)
 *     1        asynchronous mode - useful to at least test and understand
 *     3        synchronous mode - what we probably want for openSUSE
 *   Details on: https://sourceware.org/pipermail/libc-alpha/attachments/20201218/cf93aeb4/attachment.bin
 */
 
int main(){
        int* a;
        a = malloc(sizeof(int));
        *a = 42;
        free(a);
        *a = 24; /* Should fail here */
        return 0;
}
内核支持

版本:Tumbleweed 内核支持自 快照 20210504 起在 kernel-debug 中启用


内核中的 MTE 支持是通过带有硬件标签的 KASAN 完成的。这在 Tumbleweed 中作为 kernel-debug 启用的一部分启用。

请注意,需要 GCC10+ 和 LLVM9+ 才能使用 MTE 编译 glibc/内核。

如果您的硬件支持,您应该在内核日志中找到以下行

[ 0.000000] CPU features: detected: Memory Tagging Extension
[ 0.000000] kasan: KernelAddressSanitizer initialized

如果您想使用 qemu 进行测试,请注意您需要 qemu 5.1 或更高版本。然后,您需要使用 -M virt,mte=on -cpu max 显式启用它,并禁用 kvm(速度慢)。

KASAN 的上游文档:https://linuxkernel.org.cn/doc/html/latest/dev-tools/kasan.html

堆栈标签

不适用于 Linux。


ARMv9.x - CCA(保密计算架构)

Arm CCA 的主要功能之一是在受保护的 VM(又名 realm)中运行 Linux。
客户支持包含在内核 6.13 (CONFIG_ARM_CCA_GUEST) 中,可在 Tumbleweed 20250122+ 中使用,主机支持将在以后合并。

ARMv9.4 - GCS(受保护控制栈)

请注意,需要 GCC15+/LLVM19+、binutils 2.45+ 和内核 6.13+

受保护控制栈 (GCS) 提供对仅包含返回地址的具有限制访问权限的单独栈的支持。
这可以用作对面向返回编程 (ROP) 攻击的保护,方法是将程序使用的返回地址与存储在 GCS 中的地址进行比较。
它还可以用于有效地获取应用程序的调用栈,例如用于分析。
内核在运行时检测该功能,如果系统未实现该功能,则该功能将保持禁用状态,因此可以安全地启用它。

  • 内核端:Tumbleweed 内核启用 CONFIG_ARM64_GCS 选项(内核 6.13+)。然后,如果硬件支持 GCS,您应该从内核日志中获得以下行
 CPU features: detected: Guarded Control Stack (GCS)
  • 用户空间端:您可以使用 -mbranch-protection=gcs 选项,但 -mbranch-protection=standard 也包含它(使用 GCC15+),因此 openSUSE Tumbleweed 构建包具有 GCS 支持。默认情况下,GCS 已禁用,用户应使用 GLIBC_TUNABLES glibc.cpu.aarch64_gcs=1 以及可选的 glibc.cpu.aarch64_gcs_policy=<0|1|2> 选择加入。示例
 GLIBC_TUNABLES="glibc.cpu.aarch64_gcs=1"  /usr/bin/ls

注意:如果您想检查二进制文件是否支持 GCS,可以使用 readelf(就像您对 PAC 或 BTI 所做的那样),因为支持 GCS 的二进制文件使用可以使用 readelf 读取的 ELF 属性进行注释:readelf -n /usr/bin/ls | grep AArch64

 Properties: AArch64 feature: BTI, PAC, GCS

或者如果您的 binutils 太旧

 Properties: AArch64 feature: BTI, PAC, <unknown: 4>


外部链接

HyperV - 客户支持

在 aarch64 上,Tumbleweed 支持 HyperV 作为客户,自快照 20211125(内核 5.15)起。

由于 shim 现在已由 Microsoft 为 aarch64 签名,因此它还支持 SecureBoot,自快照 20240923 起。

Armv8.x 上的可选 32 位支持

一些 Armv8.x SoC 支持 32 位

一些 Armv8.x SoC 支持 32 位,例如 Ampere eMAGHoneyComb_LX2K 等。因此,您可以使用它在用户空间和内核中构建和运行 32 位。

如果您的硬件支持,您应该在内核日志中找到以下行

kernel: CPU features: detected: 32-bit EL0 Support
kernel: CPU features: detected: 32-bit EL1 Support


一些 Armv8.x SoC 完全不支持 32 位

一些 Armv8.x SoC 完全不支持 32 位,例如 ThunderXThunderX2 机器。


一些 Armv8.x SoC 仅在用户空间支持 32 位

一些 Armv8.x SoC,例如 N1SDP,仅在用户空间支持 32 位。

如果您的硬件支持,您应该在内核日志中找到以下行

kernel: CPU features: detected: 32-bit EL0 Support

在这样的系统上,如果您尝试使用启用了 kvm 的 32 位内核启动 qemu,您将收到以下错误

 qemu-system-aarch64: can't apply global host-arm-cpu.aarch64=off: 'aarch64' feature cannot be disabled unless KVM is enabled and 32-bit EL1 is supported

openSUSE:Factory:ARM 项目配置为使用 aarch64 内核来构建 armv6l 和 armv7l 包和镜像。

Armv6/7 信息

内核 5.7 中删除了 ARM 32 位 KVM 主机支持

ARM 32 位 KVM 主机支持已在内核 5.7 中删除,具体提交为 commit 541ad0150ca4aa663a2