KVM Planes试图统一四种安全域:机密计算需要新的vCPU抽象

摘要:AMD VMPL、Intel TDX partition、Hyper-V VTL与Arm CCA plane都在一个逻辑vCPU中引入多份安全上下文。KVM Planes试图提供统一对象与API,但调度策略仍在激烈演进。

KVM Planes试图统一四种安全域:机密计算需要新的vCPU抽象 ## 摘要

机密计算与虚拟化安全正在把传统“宿主机—虚拟机—用户态/内核态”模型扩展为单个虚拟 CPU 内的多个隔离执行域。AMD SEV-SNP 提供 VMPL,Intel TDX 正在发展 partition,Microsoft Hyper-V 使用 VTL,Arm CCA 则直接采用 plane 一词。它们的硬件机制、编号方向和切换规则并不相同,却共享一个核心特征:同一逻辑 vCPU 拥有多份执行上下文,各安全域可使用不同寄存器状态、内存权限和中断视图,并在一定约束下互相切换。KVM planes 补丁尝试以统一对象模型和用户态 API 表达这些能力,避免为每种架构重复发明接口。本文梳理各技术的共同点与差异,解释 KVM_CREATE_PLANEKVM_CREATE_VCPU_PLANE 的设计,分析旧方案为何难以扩展,以及 plane 调度究竟应位于内核还是用户态。需要特别强调:截至本文所讨论的补丁版本,KVM planes 仍处于邮件列表评审和持续演进阶段,并非可依赖的稳定 Linux 主线 ABI。

从单一 guest privilege 到多个虚拟安全域

经典 KVM 模型中,一个 VM 文件描述符代表一台虚拟机,一个 vCPU 文件描述符代表一个逻辑处理器。虽然 guest 内部仍有用户态、内核态以及可能的嵌套虚拟化层级,但从 KVM 用户态 API 看,vCPU 基本只有一套可保存、恢复和运行的架构状态。

新一代可信执行环境改变了这个前提。安全监控器、密钥服务、完整性守卫或隔离驱动可能与普通 guest OS 共处一台 VM,却必须拥有独立于普通内核的状态和内存访问能力。它们不一定值得获得整台虚拟机的最高权限,但必须能抵抗其他域的读取或篡改。于是,“一个 vCPU,多份受保护上下文”成为跨架构需求。

KVM 选择 plane 作为中性术语。这里的 plane 不应简单理解为 x86 ring,也不必天然形成严格的线性特权等级。更稳妥的定义是:plane 是 VM 内一个具有独立 vCPU 状态及可配置资源可见性的虚拟安全域;多个 plane 的同号 vCPU 共同构成一个逻辑 vCPU,任一时刻通常只能有其中一个执行。

四类硬件或软件模型如何映射到 planes

AMD VMPL

SEV-SNP 的 Virtual Machine Privilege Level 提供 VMPL0 至 VMPL3。VMPL 数字越小,通常权限越高;VMPL0 可管理更低权限层使用的 VMSA 和页权限。每个 VMPL 可拥有自己的 VMSA,即受机密计算保护的 vCPU 保存区,并通过 RMP 权限控制页面在不同 VMPL 下的读、写、执行能力。

VMPL 是 planes 最直接的硬件映射之一,但它也揭示了抽象不能过度承诺。VMPL 编号携带 AMD 特定的权限方向,VMSA 是否 runnable 以及 SVSM 如何约束切换,均不是通用 API 应硬编码的策略。KVM 可以把每个 VMPL 表达为 plane,却不应假定所有架构都遵循“编号越小越高权”的规则。

Intel TDX partitions

TDX partitioning 的目标是在一个 TD 内形成多个受隔离的执行分区,各分区拥有相应状态与访问控制。与完全由 VMM 任意装载上下文的软件模型不同,TDX 的切换可能由受保护环境直接完成,甚至不产生传统 VM exit。VMM 也未必有权强制跳转到任意目标 partition。

这一点对 KVM API 很关键:若硬件可在内核执行路径中完成 plane 转换,而用户态根本观察不到中间事件,那么把调度完全设计为 QEMU 的责任既低效又不正确。TDX 也说明 plane 更像“同一受保护 VM 内的关联执行域”,而不是几台碰巧共享内存的独立 VM。

Hyper-V VTL

Virtual Trust Level 是微软 Virtual Secure Mode 的基础。常见语义中 VTL0 运行普通 Windows,较高 VTL 承载安全内核及隔离服务;调度倾向于运行最高优先级、可运行的 VTL。不过,VTL 的启动、锁定和中断切换规则并不能仅凭数字概括。例如 VTL0 先启动并建立更高 VTL,某个层级在被锁定前后的权限关系可能发生变化。

Hyper-V VTL 主要是可由软件虚拟化实现的模型,因此用户态 VMM 有较强动机保留策略控制:跨 VTL IPI、拦截、SMP bring-up 和切换语义可在用户态迭代,减少内核承载特定于 VSM 的复杂策略。它与 TDX 的需求形成了 planes 设计中最核心的张力。

Arm CCA planes

Arm CCA 的 Realm Management Extension 为受保护 Realm 提供基础,而 CCA plane 进一步表达 Realm 内的多个隔离执行环境。其机制同样可能包含硬件约束的状态切换与按 plane 区分的内存访问。由于 Arm 已使用 plane 术语,KVM 社区借用这一名称,既避免让跨架构 API 偏向 VMPL、partition 或 VTL 中任何一家,也提醒开发者:统一的是生命周期和关联关系,并非抹平底层安全语义。

四者的最大公约数包括:同一逻辑 vCPU 下存在多份状态;不同域具有独立或更严格的内存属性;切换需要原子地处理运行权、中断和共享状态;KVM 必须知道各 plane-vCPU 之间的亲缘关系。差异则包括特权编号方向、是否严格层级化、VMM 能否任意切换、切换是否导致退出,以及哪些寄存器或设备状态必须共享。

两类旧 API 方案为何走不远

早期讨论主要尝试过两条路。

第一条是继续只暴露一个 vCPU fd,把所有 plane 状态塞进单个 struct kvm_vcpu。表面上 fd 数量不变,兼容传统运行循环;实际上,MMU、APIC、通用寄存器、事件、调试状态乃至架构私有结构都要复制或加索引。现有 KVM_GET_*KVM_SET_* ioctl 还必须新增“目标特权层”选择方式,导致大量既有 UAPI 改造。SEV-SNP 原型看似尚可,是因为部分寄存器状态隐藏在 KVM 不直接管理的 VMSA 中;一旦用于 Hyper-V VTL,状态归属和共享边界便迅速复杂化。

第二条是把每个安全域建成独立 VM 和独立 vCPU,并由用户态协调。它复用了现有 fd,却破坏了本应属于同一 VM 的资源关系。不同 VM 难以自然共享 memslot、脏页位图以及 private/shared memory attributes;对共享 ASID 的 SNP VMPL 尤其棘手。用户态还要保证同号 vCPU 的多个域不会并行运行,复制那些确实应共享的状态,并在高权限域出现中断时及时抢占低权限域。

更严重的是,KVM 看不到这些 vCPU 实际属于同一逻辑处理器,便无法可靠实现内核内快速切换,也无法在硬件不产生 VM exit 时维持关系。由此,planes 方案采取折中:共享一个底层 VM 和逻辑 vCPU 关联结构,但为额外 plane 暴露受限的新 fd 类型。

新对象模型与两个核心 ioctl

plane 0 是最初通过传统 KVM API 创建的默认域,保留完整 VM/vCPU ioctl 和 struct kvm_run 使用方式。额外 plane 则通过 plane fd 表达,只支持明确标注的 ioctl 子集,例如能力查询、内存属性、MSI 注入,以及面向各 plane 的寄存器读写。这样既不需要给所有旧 ioctl 添加 plane 参数,也不会把各安全域伪装成互不相关的 VM。

KVM_CREATE_PLANE 在默认 VM fd 上调用,以 plane id 为参数,返回新 plane 的 VM 类 fd。该 fd 不是一台新虚拟机:它仍关联原 VM 的地址空间和公共结构,但可拥有独立内存属性,从而对某些 GPA 设置比基础 memslot 更严格的访问权限。能力 KVM_CAP_PLANE 用于探测支持程度;补丁文档建议优先在 VM fd 上查询,因为可用 plane 范围可能受具体机器类型影响。

KVM_CREATE_VCPU_PLANE 在非默认 plane fd 上调用,参数是 plane 0 中已存在的 vCPU fd,返回同一逻辑 vCPU 在新 plane 内的 vCPU fd。其 vCPU id 继承自传入对象,因此额外 plane 只能覆盖 plane 0 已创建 vCPU 的子集。这一约束很有价值:内核可以建立 logical-vcpu -> plane-vcpu[] 的显式映射,天然禁止同一逻辑处理器的多个上下文并发进入硬件。

早期草案还扩展 kvm_run,使用 plane 字段表示拟运行或实际返回的域,以位图表示因更高优先级域而挂起的 planes,或指定哪些其他 plane 出现待处理中断时应退出,并通过类似 KVM_EXIT_PLANE_EVENT 的原因通知用户态。具体字段在后续系列中仍可能调整,但设计意图清晰:用户态需要观察和协助切换,同时给未来内核加速保留空间。

内核调度还是用户态调度

2026 年补丁讨论把争议进一步聚焦到“谁选择下一个 plane”。一种实现为每个 plane-vCPU 维护 STOPPEDRUNNABLE 状态,触发 KVM_REQ_PLANE_RESCHED,并在内核中选择可运行 plane。示例算法选择最低编号的 runnable plane;但这只是策略实例,并非跨平台真理。

支持内核调度的理由很强。首先,TDX partition 和可能的 CCA plane 能在无 VM exit 情况下切换,用户态无法参与每次决策。其次,SNP/SVSM 可通过令低权限 VMSA 不可运行来施加强制约束,用户态“任选目标”的接口会产生依平台变化、甚至无法兑现的语义。再次,切换涉及中断窗口、抢占和共享 vCPU 状态,在内核集中完成更容易保证原子性,也能减少频繁退出成本。

支持用户态调度的一方则担心内核过早固化策略。Hyper-V VSM 的优先级、锁定、跨 VTL 中断和拦截规则复杂,QEMU 或其他 VMM 更适合实现产品语义。更通用的安全 enclave 也未必是线性层级:两个互不信任的 plane 可能只共享通信页,各自封闭其他内存。若内核假定 plane 0 永远最高权,或固定按编号升降选择,就会限制 VSM 替代方案、服务型 enclave 以及未来硬件。

较合理的方向是分层:内核负责不可违反的安全与运行约束,维护 plane 关联、唯一运行权和硬件要求的快速切换;用户态在硬件允许时提供策略、配置优先级并处理复杂设备模型。能力位必须明确区分“可由用户态请求”“内核可能覆盖”“只能硬件决定”等模式,而不能让同一字段在不同平台上悄悄改变含义。编号也最好只是标识符,权限拓扑与切换能力应显式描述。

可落地的应用场景

第一类是 guest 内安全服务。普通内核在 plane 0 启动后创建密钥代理、磁盘解密服务或远程证明代理所在 plane,仅开放通信环和必要页面。即使 guest 内核被攻破,攻击者也难以直接读取该 plane 的私有内存。

第二类是 Windows VSM/VBS 兼容。VMM 可用 planes 表达 VTL 上下文,在用户态实现 Hyper-V 特定的拦截和中断协议,同时让 KVM 负责同一逻辑 vCPU 的互斥运行。这样比“每个 VTL 一台 VM”更贴近真实硬件关系。

第三类是机密虚拟机内的可服务安全模块。云平台可将测量、密钥轮换或策略执行放进独立 plane,但必须谨慎定义信任边界:安全模块不应因为名称上“更高权限”就自动获得整个 guest 内存。按页 sealing、最小授权和双向隔离往往比单纯层级模型更安全。

第四类是跨架构 VMM 复用。QEMU、Cloud Hypervisor 或 rust-vmm 组件可以围绕统一生命周期实现创建、迁移和状态保存框架,再由架构后端处理 VMPL、TDX、VTL 或 CCA 的差异。

采用建议与工程风险

对发行版和云平台而言,当前最重要的建议是:不要把补丁接口当成稳定主线 ABI 对外承诺。本文引用的 2024 年文档草案与 2026 年 SNP 支持系列已显示对象布局、调度位置、编号语义仍在讨论。产品原型应锁定确切内核提交、QEMU 分支和固件版本,启动时通过 capability 探测,而不是仅凭版本号判断。

VMM 实现应增加一层内部抽象,避免业务代码直接依赖 ioctl 数值或临时结构字段;迁移格式要记录 plane 拓扑、每个 plane 的架构状态、内存属性及共享状态版本,并在源宿主能力不等价时拒绝迁移。测试不能只验证启动,还要覆盖跨 plane 中断、并发 KVM_RUN 拒绝、热插拔 vCPU、私有/共享页面转换、异常注入、暂停恢复及恶意 plane 请求。

安全设计上,应把 plane id 与权限分离,不默认“数字大/小就是可信”。管理面必须验证内存属性变更由谁授权,防止低信任域扩大自身可见范围;共享通信区需使用长度校验、序列号和重放保护。对于用户态调度,VMM 崩溃或延迟不能造成高优先级安全域永久饥饿;对于内核调度,则要审计策略是否可能绕过用户态设备状态同步。

内核开发者应优先稳定对象关系和不变量,而非急于统一所有策略:额外 plane 属于同一 VM;同号 plane-vCPU 共享逻辑运行槽;任何时刻只有合法目标可运行;内存权限只能在硬件允许范围内收紧或转换。在这些基础之上,再以能力协商扩展调度、FPU 是否分域、无退出切换及架构专有状态,能够减少未来 ABI 包袱。

结语

KVM planes 的价值不在于给四种技术换一个共同名字,而在于为“单 VM、单逻辑 vCPU、多个隔离执行域”建立内核可见的关系模型。它避开了单 fd 内状态爆炸,也修复了多 VM 模拟导致的内存、调度和中断割裂;两个创建 ioctl 则以较小 UAPI 增量提供可管理的 fd 边界。

真正困难的部分仍是抽象边界:硬件必须执行的安全规则应留在内核,VSM 等产品策略又需要用户态灵活性;有的平台是严格层级,有的平台更适合互相 sealing。因而,planes 最终能否成为稳定接口,取决于它是否只统一可统一的机制,并通过明确能力暴露不可统一的语义。现阶段它是一条值得跟踪和实验的上游方向,而不是已经定型、可直接部署的 Linux KVM 主线功能。

参考资料

  1. Paolo Bonzini, “Documentation: kvm: cleanup and introduce ‘VM planes’”, Linux KVM patch discussion, 2024:https://patchew.org/linux/20241023124507.280382-1-pbonzini@redhat.com/20241023124507.280382-6-pbonzini@redhat.com/
  2. Joerg Roedel 等, “KVM Planes + SEV-SNP Support”, Linux KVM patch discussion, 2026:https://patchew.org/linux/20260608144252.351443-1-joro@8bytes.org/20260608144252.351443-36-joro@8bytes.org/
  3. AMD, SEV-SNP Architecture and VMPL/VMSA documentation
  4. Intel, Intel Trust Domain Extensions architecture specifications
  5. Microsoft, Virtual Secure Mode and Virtual Trust Levels documentation
  6. Arm, Confidential Compute Architecture and Realm Management Extension specifications
分享到