ARM 韌體偽暫存器介面

KVM 處理 guest 請求的 hypercall 服務。 ARM 規範或 KVM(作為供應商服務)會定期提供新的 hypercall 服務,如果它們從虛擬化的角度來看是有意義的。

這意味著在兩個不同版本的 KVM 上啟動的 guest 可以觀察到兩個不同的“韌體”版本。如果給定的 guest 與特定版本的 hypercall 服務相關聯,或者如果遷移導致不同的版本突然暴露給毫無戒心的 guest,這可能會導致問題。

為了解決這種情況,KVM 公開了一組“韌體偽暫存器”,可以使用 GET/SET_ONE_REG 介面來操作這些暫存器。 這些暫存器可以由使用者空間儲存/恢復,並根據需要設定為方便的值。

定義了以下暫存器

  • KVM_REG_ARM_PSCI_VERSION

    KVM 實現了 PSCI(電源狀態協調介面)規範,以便為 guest 提供諸如 CPU 開/關、重置和斷電等服務。

    • 只有當 vcpu 具有 KVM_ARM_VCPU_PSCI_0_2 功能集(因此已經初始化)時才有效

    • 返回 GET_ONE_REG 上的當前 PSCI 版本(預設為 KVM 實現的且與 v0.2 相容的最高 PSCI 版本)

    • 允許使用 SET_ONE_REG 設定 KVM 實現的且與 v0.2 相容的任何 PSCI 版本

    • 影響整個 VM(即使暫存器檢視是每個 vcpu 的)

  • KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1

    儲存韌體支援的狀態,以緩解 CVE-2017-5715,由 KVM 透過 HVC 呼叫提供給 guest。此解決方法在 [1] 中 SMCCC_ARCH_WORKAROUND_1 下進行了描述。

    接受的值為

    KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1_NOT_AVAIL

    KVM 不提供針對此解決方法的韌體支援。guest 的緩解狀態未知。

    KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1_AVAIL

    此解決方法 HVC 呼叫可用於 guest,並且是緩解所必需的。

    KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1_NOT_REQUIRED

    此解決方法 HVC 呼叫可用於 guest,但在此 VCPU 上不需要。

  • KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2

    儲存韌體支援的狀態,以緩解 CVE-2018-3639,由 KVM 透過 HVC 呼叫提供給 guest。此解決方法在 [1] 中的 SMCCC_ARCH_WORKAROUND_2 下進行了描述。

    接受的值為

    KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_AVAIL

    沒有可用的解決方法。 KVM 不提供針對此解決方法的韌體支援。

    KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_UNKNOWN

    此解決方法的狀態未知。 KVM 不提供針對此解決方法的韌體支援。

    KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_AVAIL

    此解決方法可用,並且可以由 vCPU 停用。 如果設定了 KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_ENABLED,則它對該 vCPU 處於活動狀態。

    KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_REQUIRED

    此解決方法始終在此 vCPU 上處於活動狀態,或者不需要。

點陣圖功能韌體暫存器

與上述暫存器相反,以下暫存器以功能點陣圖的形式向用戶空間公開 hypercall 服務。 此點陣圖被轉換為可用於 guest 的服務。 每個服務呼叫所有者定義了一個暫存器,可以透過 GET/SET_ONE_REG 介面進行訪問。

預設情況下,這些暫存器設定為受支援功能的上限。 這樣,使用者空間就可以透過 GET_ONE_REG 發現所有可用的 hypercall 服務。 使用者空間可以透過 SET_ONE_REG 將所需的點陣圖寫回。 未觸及的暫存器的功能(可能是因為使用者空間不知道)將按原樣暴露給 guest。

請注意,一旦任何 vCPU 至少執行過一次,KVM 將不再允許使用者空間配置暫存器。 而是返回 -EBUSY。

偽韌體點陣圖暫存器如下

  • KVM_REG_ARM_STD_BMAP

    控制 ARM 標準安全服務呼叫的點陣圖。

    接受以下位

    Bit-0: KVM_REG_ARM_STD_BIT_TRNG_V1_0

    該位表示 ARM 真隨機數生成器 (TRNG) 規範 v1.0 下提供的服務,ARM DEN0098。

  • KVM_REG_ARM_STD_HYP_BMAP

    控制 ARM 標準 Hypervisor 服務呼叫的點陣圖。

    接受以下位

    Bit-0: KVM_REG_ARM_STD_HYP_BIT_PV_TIME

    該位表示由 ARM DEN0057A 表示的半虛擬化時間服務。

  • KVM_REG_ARM_VENDOR_HYP_BMAP

    控制供應商特定的 Hypervisor 服務呼叫 [0-63] 的點陣圖。

    接受以下位

    Bit-0: KVM_REG_ARM_VENDOR_HYP_BIT_FUNC_FEAT

    該位表示 ARM_SMCCC_VENDOR_HYP_KVM_FEATURES_FUNC_ID 和 ARM_SMCCC_VENDOR_HYP_CALL_UID_FUNC_ID 函式 ID。

    Bit-1: KVM_REG_ARM_VENDOR_HYP_BIT_PTP

    該位表示精確時間協議 KVM 服務。

  • KVM_REG_ARM_VENDOR_HYP_BMAP_2

    控制供應商特定的 Hypervisor 服務呼叫 [64-127] 的點陣圖。

    接受以下位

    Bit-0: KVM_REG_ARM_VENDOR_HYP_BIT_DISCOVER_IMPL_VER

    這表示 ARM_SMCCC_VENDOR_HYP_KVM_DISCOVER_IMPL_VER_FUNC_ID 函式 ID。 這將被重置為 0。

    Bit-1: KVM_REG_ARM_VENDOR_HYP_BIT_DISCOVER_IMPL_CPUS

    這表示 ARM_SMCCC_VENDOR_HYP_KVM_DISCOVER_IMPL_CPUS_FUNC_ID 函式 ID。 這將被重置為 0。

錯誤

-ENOENT

訪問了未知暫存器。

-EBUSY

在 VM 啟動後嘗試“寫入”暫存器。

-EINVAL

寫入暫存器的點陣圖無效。