ARM 固件伪寄存器接口

KVM 处理客户机请求的 hypercall 服务。ARM 规范或 KVM(作为供应商服务)会定期提供新的 hypercall 服务,前提是它们从虚拟化的角度来看是有意义的。

这意味着在两个不同版本的 KVM 上启动的客户机可能会观察到两个不同的“固件”版本。如果给定的客户机绑定到特定版本的 hypercall 服务,或者如果迁移导致意外地向毫无防备的客户机公开不同的版本,则可能会导致问题。

为了解决这种情况,KVM 公开了一组“固件伪寄存器”,可以使用 GET/SET_ONE_REG 接口进行操作。这些寄存器可以由用户空间保存/恢复,并根据需要设置为方便的值。

定义了以下寄存器

  • KVM_REG_ARM_PSCI_VERSION

    KVM 实现 PSCI(电源状态协调接口)规范,以便为客户机提供诸如 CPU 开/关、重置和关机等服务。

    • 仅当 vcpu 设置了 KVM_ARM_VCPU_PSCI_0_2 功能(因此已经初始化)时有效

    • 在 GET_ONE_REG 上返回当前 PSCI 版本(默认为 KVM 实现的最高 PSCI 版本,并且与 v0.2 兼容)

    • 允许使用 SET_ONE_REG 设置 KVM 实现的任何与 v0.2 兼容的 PSCI 版本

    • 影响整个虚拟机(即使寄存器视图是每个 vcpu)

  • KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1

    保存固件支持的状态,以缓解 CVE-2017-5715,由 KVM 通过 HVC 调用提供给客户机。该解决方法在 [1] 中的 SMCCC_ARCH_WORKAROUND_1 下进行了描述。

    接受的值为

    KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1_NOT_AVAIL

    KVM 不提供针对该解决方法的固件支持。客户机的缓解状态未知。

    KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1_AVAIL

    解决方法 HVC 调用可用于客户机,并且是缓解所必需的。

    KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1_NOT_REQUIRED

    解决方法 HVC 调用可用于客户机,但在该 VCPU 上不需要。

  • KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2

    保存固件支持的状态,以缓解 CVE-2018-3639,由 KVM 通过 HVC 调用提供给客户机。该解决方法在 [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 服务。此位图将转换为客户机可用的服务。每个服务调用所有者都定义了一个寄存器,并且可以通过 GET/SET_ONE_REG 接口进行访问。

默认情况下,这些寄存器设置为支持的功能的上限。这样,用户空间可以通过 GET_ONE_REG 发现所有可用的 hypercall 服务。用户空间可以通过 SET_ONE_REG 写回所需的位图。未触及的寄存器的功能(可能是因为用户空间不知道它们)将按原样公开给客户机。

请注意,一旦任何 vCPU 至少运行一次,KVM 将不允许用户空间再配置寄存器。相反,它将返回 -EBUSY。

伪固件位图寄存器如下

  • KVM_REG_ARM_STD_BMAP

    控制 ARM 标准安全服务调用的位图。

    接受以下位

    位-0:KVM_REG_ARM_STD_BIT_TRNG_V1_0

    该位表示 ARM 真随机数生成器 (TRNG) 规范 ARM DEN0098 v1.0 下提供的服务。

  • KVM_REG_ARM_STD_HYP_BMAP

    控制 ARM 标准 Hypervisor 服务调用的位图。

    接受以下位

    位-0:KVM_REG_ARM_STD_HYP_BIT_PV_TIME

    该位表示 ARM DEN0057A 表示的准虚拟化时间服务。

  • KVM_REG_ARM_VENDOR_HYP_BMAP

    控制供应商特定的 Hypervisor 服务调用的位图。

    接受以下位

    位-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。

    位-1:KVM_REG_ARM_VENDOR_HYP_BIT_PTP

    该位表示精确时间协议 KVM 服务。

错误

-ENOENT

访问了未知寄存器。

-EBUSY

在虚拟机启动后尝试“写入”寄存器。

-EINVAL

写入寄存器的位图无效。