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
写入寄存器的位图无效。