核心與 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)。因此建議使用函式呼叫來執行管理程式呼叫。