CPU 与拓扑
描述虚拟处理器模型、CPU 配置、处理器拓扑、特性表面,以及处理器容量的确定与校验方式。
译自microsoft/nvx · doc/design/2.2-cpu-and-topology.md。技术细节以英文原文为准。
如表 2.2 所示,每个 VM 都具有由 1、2、4 或 8 个虚拟处理器构成的不可变处理器容量,以及确定性的拓扑。
表 2.2. 处理器拓扑。
| 属性 | 契约 |
|---|---|
| NUMA 节点 | 一个 |
| CPU 插槽 | 一个 |
| 裸片 | 一个 |
| 每核心线程数 | 一个 |
| 核心数 | 等于处理器容量 |
| APIC 模式 | xAPIC |
| APIC ID | 连续,从零开始 |
2.2.1 CPU 配置
客户机看到的是一个 CPU 配置,而不是宿主直通。CPU 配置是某一厂商和某一代 CPU 的完整客户机可见 CPU 表面,由所有后端共享。在每一个受管控的 CPUID 条目中,客户机只会看到 CPU 配置中的取值,但固定的 VMM 所属字段以及时间 ABI 所属的字段除外。同一个 CPU 配置在每个后端上都给出相同的客户机行为;它并不能使快照在不同后端之间可移植。
CPU 配置是带版本的数据,具有一种规范编码和一个 SHA-256 摘要。其标识符形如 <vendor>.<generation>.v<revision>。它包含:
- CPU 厂商以及该代的 CPU 签名,以标识处理器设计及其修订(family、model、stepping)的编号区间表示。
- 一张稠密的 CPUID 表,覆盖每个基本叶和扩展叶,以及每个叶的次级索引(子叶)直到 CPU 配置的最大值;每个寄存器有一个取值和一个掩码,其中掩码位为置位表示固定该取值,为清零位表示该位归 VMM 或运行时所有。
- 客户机可能启用的扩展处理器状态保存与恢复(XSAVE)组件,例如向量寄存器,以及每个组件的大小、偏移和标志。
- 客户机物理地址宽度。
- 钉定的模型专用寄存器(MSR)取值及其掩码。
- 说明性的来源信息。
CPU 配置通过逐寄存器求交宿主指纹导出,先在每个后端内部求交,再跨后端求交。已发布的修订不可变且永不删除;规范性的变更会创建新的修订。
如表 2.3 所示,每一个 CPUID 位都恰好有一个所有者。
表 2.3. CPUID 字段的归属。
| 所有者 | 字段 |
|---|---|
| CPU 配置 | 掩码位为置位的所有受管控取值,以及钉定的 MSR |
| VMM | 逻辑处理器数量和初始 APIC ID、用于通告 APIC 的基于 MSR 的模式(x2APIC)所用的位、核心与缓存共享计数,以及处理器拓扑叶 |
| 客户机运行时状态 | 报告客户机内核是否启用了 XSAVE 和内存保护密钥的位(OSXSAVE 和 OSPKE),以及用于选择已启用的用户态与监管态组件的寄存器(XCR0 和 XSS)当前取值所对应的 XSAVE 大小 |
| 时间 ABI | 叶 0x40000000 至 0x4fffffff、0x15、0x16,以及 CPU 时间位 |
| 策略 | 对虚拟化扩展、Intel 安全飞地(SGX)、处理器追踪、缓存与内存带宽分配(resource director technology)、内存加密以及其他被排除特性置零 |
由于机器只有一个 CPU 插槽且每个虚拟处理器一个核心,每个缓存都报告“每插槽核心数 = 处理器数量减一”,L3 缓存由每个处理器共享,而每个 L1 和 L2 缓存只服务一个处理器。
2.2.1.1 有效 CPUID
有效 CPUID 是 CPU 配置、VM 拓扑和时间 ABI 身份叶的纯函数。它恰好列出受管控的条目:CPU 配置表中的每个叶和子叶;拓扑所定义的子叶处的拓扑叶,以及终止它们的子叶;以及 hypervisor 身份叶及其显式零值叶。VMM 计算它,把它记录在快照清单中,并在恢复时重新计算。因此该记录从不依赖于后端如何枚举或缓存 CPUID,同一个 CPU 配置和拓扑在每个后端上都产生相同的记录。由于该记录还固定了 VMM 自身的叶和 VMM 所属的位,改变 VMM 计算它们的方式会破坏快照兼容性。
只有探测越过已通告的最大值才能到达的条目属于保留条目:高于最大基本叶或扩展叶的叶、越过某个叶的最大值或终止符的子叶,以及已禁用组件的 XSAVE 子叶。它们的取值由实现定义,客户机不得依赖它们;验证仍会把宿主特性排除在这些条目之外。
有些字段仅供参考,不参与比较:CPUID 报告的处理器名称(品牌字符串)按代通用,并不指明任何频率;缓存描述符叶来自参考宿主;微码修订未被钉定。
与缓解措施相关的位跟随硬件。只有当其所在代的每个 CPU 都具备某项免疫能力或控制,并且每个后端都能呈现它时,CPU 配置才会声明该能力或控制,从而使客户机保持其缓解措施处于启用状态。
2.2.1.2 CPU 配置选择
每个微虚拟机都有一个 CPU 配置。冷启动会显式选择一个钉定的 CPU 配置、自动选择一个,或使用宿主 CPU 配置:
- 自动选择使用那唯一一个钉定配置的最高修订,其所在代覆盖宿主的厂商、family、model 和 stepping。
- 在没有任何钉定配置能服务的 Intel 或 AMD CPU 上,自动选择回退到宿主配置,并在每次走该回退路径的冷启动时发出警告。
- 其他厂商的 CPU、有歧义的目录匹配,或后端无法支持的钉定配置,都会导致失败而不是回退。
宿主 CPU 配置在冷启动时按照与钉定配置相同的导出策略,从后端在当前宿主上的指纹导出。客户机看到的仍然是经策略过滤的表面,而不是宿主的 CPUID:只有被允许的数据叶才保留数据,策略特性被清零,XCR0 保持在被允许的组件范围内,品牌字符串是通用的,且该代只覆盖宿主的 family、model 和 stepping。宿主配置既未经评审,也并非不可变,因为固件、微码、hypervisor 或操作系统更新都可能改变它。它的快照携带宿主配置文档,且只有在 CPU 型号和 stepping 相同、并且其 hypervisor 支持它的宿主上才能恢复。
恢复始终使用快照所记录的 CPU 配置,绝不回退。
2.2.1.3 CPU 配置验证
在分区创建时,无论是冷启动还是恢复,VMM 都会验证:
- CPU 配置是有效的,包括其规范编码、稠密度、归属掩码和 CPU 时间位。
- 宿主的厂商、family、model 和 stepping 属于该 CPU 配置所在的代。
- 后端支持该 CPU 配置,包括每一个置位的特性位、每一个上限、XSAVE 布局、XCR0 与 XSS 子集,以及每一个钉定的 MSR 取值,其中时间策略位豁免。
- 在恢复时,VMM 钉定相同的 CPU 配置 ID 和摘要,或者所记录的是宿主配置且它是一份带有记录摘要的有效规范文档,并且重新计算出的有效 CPUID 与所记录的相等。
- 后端在其掩码之下,于第一个虚拟处理器上呈现有效 CPUID。
- 在会透传保留条目的后端上,CPU 配置的表、身份范围和拓扑叶之外不存在任何非零条目。
所有违规项都会一并报告,并指出具体的叶、子叶、寄存器和位。
2.2.2 处理器容量
处理器容量是机器身份的一部分,并在 VM 的整个生命周期内保持固定。处理器拓扑、APIC ID、MP 表和已保存的处理器清单始终准确描述该容量,即使快照捕获的在线处理器更少,因此在恢复时让更多处理器上线也绝不会改变拓扑。处理器激活 描述了恢复如何选择其在线处理器。