为什么 Linux 在发出系统调用时将 ARM64 中的 SVE 寄存器的高位清零?

问题描述 投票:0回答:1

在Linux 5.10 AArch64

syscall.c
源代码中,有一个函数
sve_user_discard()
,可以将SVE寄存器的[max:128]位清零。 这是代码

我无法理解这个功能的用法。谁能给我解释一下吗?

我在运行SVE程序时遇到了一个bug,最后发现根本原因是

sve_user_discard()
。这个函数使得用户空间中的SVE寄存器只保留位[127:0],这使得我的程序无法按预期工作。

linux-kernel system-calls arm64 context-switch sve
1个回答
0
投票

经过一番研究后,我发现我所需要做的就是 RTFM :')。此行为是有意为之并记录在案的。

Linux ARM64 Syscall ABI 显式重置系统调用条目上 Z 寄存器的 127 位以上、P 寄存器的所有位以及 FFR 寄存器。因此,无法在系统调用之间保留 ARM64 Linux 上的完整 SVE 状态。如果您的代码使用 SVE,则需要将其拆分,以便 SVE 仅在系统调用之间使用。即使向量长度为 128 位,您仍然会在系统调用输入时丢失 P0..P15 和 FFR 的值。

这里引用了 SVE 上的内核文档,证实了这种行为。我用粗体突出显示了有趣的部分:

3.系统调用行为

  • 在系统调用中,V0..V31 被保留(与没有 SVE 一样)。因此,位[127:0] Z0..Z31 被保留。 Z0..Z31 的所有其他位,以及 P0..P15 和 FFR 的所有位 从系统调用返回时变得未指定。

  • SVE 寄存器不用于传递参数或接收结果 任何系统调用。

  • 实际上受影响的寄存器/位将被保留或将被替换 从系统调用返回时为零,但用户空间不应使 对此的假设。 内核行为可能会因具体情况而异 基础。

© www.soinside.com 2019 - 2024. All rights reserved.