内核与 HYP 之间的内部 ABI¶
本文件记录了当 Linux 作为管理程序(例如 KVM)运行时,Linux 内核与管理程序层之间的交互。它不涵盖内核作为客户机(在 Xen、KVM 或任何其他管理程序下)运行时的内核与管理程序交互,也不涵盖内核用作主机时的任何管理程序特定交互。
注意:KVM/arm 已从内核中移除。但此处描述的 API 仍然有效,因为它允许内核在 HYP 启动时执行 kexec。如有必要,其他管理程序也可以使用它。
在 arm 和 arm64(不带 VHE)上,内核不在管理程序模式下运行,但仍需要与之交互,允许安装或卸载内置管理程序。
为了实现这一点,内核必须在 HYP (arm) 或 EL2 (arm64) 启动,使其能够安装一组存根(stubs),然后降级到 SVC/EL1。这些存根通过使用 'hvc #0' 指令访问,并且只作用于单个 CPU。
除非另有说明,任何内置管理程序都必须实现这些函数(参见 arch/arm{,64}/include/asm/virt.h)
r0/x0 = HVC_SET_VECTORS r1/x1 = vectors
将 HVBAR/VBAR_EL2 设置为“vectors”以启用管理程序。“vectors”必须是物理地址,并符合架构的对齐要求。仅由初始存根实现,而不是由 Linux 管理程序实现。
r0/x0 = HVC_RESET_VECTORS
关闭 HYP/EL2 MMU,并将 HVBAR/VBAR_EL2 重置为初始存根的异常向量值。这有效地禁用了现有的管理程序。
r0/x0 = HVC_SOFT_RESTART r1/x1 = restart address x2 = x0's value when entering the next payload (arm64) x3 = x1's value when entering the next payload (arm64) x4 = x2's value when entering the next payload (arm64)
屏蔽所有异常,禁用 MMU,清除 I+D 位,将参数移动到位(仅限 arm64),然后在 HYP/EL2 状态下跳转到重启地址。此管理程序调用预计不会返回给其调用者。
x0 = HVC_FINALISE_EL2 (arm64 only)
根据命令行选项完成 EL2 的配置,包括尝试通过启用 VHE 模式将内核的异常级别从 EL1 升级到 EL2。这取决于 CPU 支持 VHE、EL2 MMU 已关闭,以及 VHE 未被任何其他方式禁用(例如,命令行选项)。
r0/x0 的任何其他值都会触发特定于管理程序的处理,此处未作记录。
存根管理程序调用的返回值由 r0/x0 保存,成功时为 0,错误时为 HVC_STUB_ERR。存根管理程序允许破坏任何调用者保存的寄存器(arm64 上的 x0-x18,arm 上的 r0-r3 和 ip)。因此建议使用函数调用来执行管理程序调用。