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
寫入暫存器的點陣圖無效。