Power Architecture 64 位 Linux 系统调用 ABI

syscall

调用

系统调用通过 `sc` 指令进行,并在 `sc` 指令之后的指令处继续执行返回。

如果 AT_HWCAP2 ELF 辅助向量中出现 PPC_FEATURE2_SCV,则 `scv 0` 指令是一种替代方法,它可能提供更好的性能,但调用序列有一些差异。

系统调用调用序列[1]与 Power Architecture 64 位 ELF ABI 规范 C 函数调用序列相匹配,包括寄存器保存规则,但有以下差异。

参数

系统调用号在 r0 中指定。

一个系统调用最多有 6 个整数参数,通过 r3-r8 传递。

返回值

  • 对于 `sc` 指令,返回值和错误条件都会返回。cr0.SO 是错误条件,r3 是返回值。当 cr0.SO 清除时,系统调用成功,r3 是返回值。当 cr0.SO 设置时,系统调用失败,r3 是错误值(通常对应于 errno)。

  • 对于 `scv 0` 指令,如果返回值是 -4095..-1(即,它作为无符号比较 >= -MAX_ERRNO (-4095)),则表示失败,在这种情况下,错误值是返回值的相反数。

堆栈

系统调用不会修改调用者的堆栈帧。例如,不会使用调用者的堆栈帧 LR 和 CR 保存字段。

寄存器保存规则

寄存器保存规则与 ELF ABI 调用序列匹配,但有一些差异。

对于 `sc` 指令,与 ELF ABI 的差异如下:

寄存器

保存规则

目的

r0

易失

(系统调用号。)

r3

易失

(参数 1 和返回值。)

r4-r8

易失

(参数 2-6。)

cr0

易失

(cr0.SO 是返回错误条件。)

cr1, cr5-7

非易失

lr

非易失

对于 `scv 0` 指令,与 ELF ABI 的差异如下:

寄存器

保存规则

目的

r0

易失

(系统调用号。)

r3

易失

(参数 1 和返回值。)

r4-r8

易失

(参数 2-6。)

所有浮点和向量数据寄存器以及控制和状态寄存器都是非易失的。

事务内存

如果处理器处于事务或挂起事务状态,则系统调用行为可能会发生变化,并且系统调用可能会影响事务的行为。

如果在进行系统调用时处理器处于挂起状态,则系统调用将正常执行,并将正常返回。系统调用将在挂起状态下执行,因此其副作用将根据通常的事务内存语义持久化。系统调用可能会或可能不会导致硬件注销该事务。

如果在进行系统调用时处理器处于事务状态,则行为取决于 AT_HWCAP2 ELF 辅助向量中是否存在 PPC_FEATURE2_HTM_NOSC。

  • 如果存在(对于较新的内核是这种情况),则将不会执行系统调用,并且内核将在 TEXASR SPR 中使用失败代码 TM_CAUSE_SYSCALL | TM_CAUSE_PERSISTENT 注销该事务。

  • 如果不存在(较旧的内核),则内核将挂起事务状态,并且系统调用将像挂起状态系统调用一样继续进行,并且在返回调用者之前恢复事务状态。这种情况未明确定义或支持,因此不应依赖此行为。

`scv 0` 系统调用将始终表现为 PPC_FEATURE2_HTM_NOSC。

ptrace

当跟踪系统调用 (PTRACE_SYSCALL) 时,pt_regs.trap 值包含系统调用类型,可用于区分 `sc` 和 `scv 0` 系统调用,并且可以解释不同的寄存器约定。

如果 (pt_regs.trap & 0xfff0) 的值为 0xc00,则表示系统调用是使用 `sc` 指令执行的;如果值为 0x3000,则表示系统调用是使用 `scv 0` 指令执行的。

vsyscall

vsyscall 调用序列与系统调用调用序列匹配,但有以下差异。一些 vsyscall 可能具有不同的调用序列。

参数和返回值

r0 不用作输入。vsyscall 由其地址选择。

堆栈

vsyscall 可能使用或不使用调用者的堆栈帧保存区域。

寄存器保存规则

r0

易失

cr1, cr5-7

易失

lr

易失

调用

vsyscall 通过分支带链接指令到 vsyscall 函数地址执行。

事务内存

vsyscall 将在与调用者相同的事务状态下运行。vsyscall 可能会或可能不会导致硬件注销该事务。