libvirt驱动程序启动AMD SEV加密实例

https://blueprints.launchpad.net/nova/+spec/amd-sev-libvirt-support

本规范提出Nova的libvirt驱动程序支持启动使用AMD的SEV(安全加密虚拟化)技术加密的KVM实例所需的工作。

问题描述

虽然数据通常在存储在磁盘上时会被加密,但它在DRAM中以明文形式存储。这可能使数据容易受到未经授权的管理员或软件窥探,或通过硬件探测。新的非易失性存储器技术(NVDIMM)加剧了这个问题,因为NVDIMM芯片可以从系统中物理移除,数据仍然完整,类似于硬盘驱动器。如果没有加密,任何存储的信息,例如敏感数据、密码或密钥都可能轻易被泄露。

AMD的SEV提供了一种VM保护技术,可以透明地使用唯一密钥加密每个VM的内存。它还可以计算内存内容的签名,可以将其发送给VM的所有者作为证明,证明固件已正确加密了内存。SEV尤其适用于云计算,因为它能够减少VM需要信任其主机系统的hypervisor和管理员的程度。

用例

  1. 作为云管理员,为了让我的用户对正在运行的实例的安全性更有信心,我希望提供一个包含SEV特定extra spec资源需求的flavor,这将允许用户启动具有该flavor的实例,以确保他们的实例在启用SEV加密的SEV功能计算主机上运行。

  2. 作为云用户,为了不必信任我的云运营商来保护我的密钥,我希望能够启动启用SEV功能的VM实例。

提议的变更

对于Train版本,目标是实现一个最小但可用的实现,以满足上述用例。建议初始开发和测试包括以下交付成果

  • 添加对主机SEV功能的支持检测。需要逻辑来检查硬件和软件hypervisor堆栈的各个层是否支持SEV

    • libvirt virConnectGetDomainCapabilities() API调用的响应中存在的以下XML 表明QEMU和AMD安全处理器(AMD-SP)都支持SEV功能

      <domainCapabilities>
        ...
        <features>
          ...
          <sev supported='yes'/>
            ...
          </sev>
        </features>
      </domainCapabilities>
      

      这种面向功能的检查应该可以避免驱动程序中任何版本检查的需要。

    • /sys/module/kvm_amd/parameters/sev 的值应为 1,以指示内核已启用SEV功能。这应该可以被任何用户读取(即,即使是非root用户)。

    请注意,需要进行这两个检查,因为第一个检查的存在并不意味着第二个检查的存在。

  • 实现一个新的 MEM_ENCRYPTION_CONTEXT 资源类,它代表计算主机可以并发运行的具有安全加密内存的guest数量(由于内存控制器中加密密钥插槽数量有限)。对于不支持SEV的主机,它将为零。

  • 更新os-traits中 HW_CPU_AMD_SEV trait的文档,以表明 a) 它目前还不能使用,仅在完全实现SEV支持的未来才能使用,以及 b) 即使在那个时候,也不应该通过 trait:HW_CPU_AMD_SEV=required 使用它,因为应该使用新的资源类代替。

    该trait存在于 0.11.0版本,并且在 Stein周期中添加,基于 先前接受用于Stein的本规范的设计。但是,从那时起,我们意识到需要将SEV功能跟踪为可离散量化的资源,而不是二进制特征,因此 MEM_ENCRYPTION_CONTEXT 资源类将取代它作为指示何时需要SEV上下文的底层机制。

    不得不退步到设计的这个元素令人遗憾;但是,还没有任何东西使用 HW_CPU_AMD_SEV trait,因此似乎不太可能对任何人造成问题。它不会被删除,原因有两个

    1. os-traits项目有一个策略,即从不删除任何trait,基于可扩展的trait集比可以缩减的trait集更容易管理。例如,trait与placement数据库的同步永远不必担心删除条目或相应的外部键。

    2. 即使它不是严格必需的,提供trait似乎也有帮助。事实上 执行此操作的代码 正在审查中,因此几乎不需要额外的操作。

      一个建议的用例是实现非SEV guest与SEV主机的反亲和性,从而使SEV主机尽可能地为SEV guest释放。这可以通过简单地将 trait:HW_CPU_AMD_SEV=forbidden 放置在所有非SEV flavor上来实现,尽管更复杂的方法可能会利用未来 对禁止聚合 的并行提案的实现。

      另一个用例可能是允许运营商和用户区分单个云中来自不同供应商的可用guest内存加密机制,例如,如果计算平面包含支持AMD SEV和Intel MKTME 的机器的混合。

      但是,这些用例的任何实现都超出了本规范的范围。

  • 使libvirt驱动程序 更新ProviderTree对象,以使用新的 MEM_ENCRYPTION_CONTEXT 资源类的正确库存。例如 在EPYC机器上,支持的SEV guest的最大数量预计为15

    由于目前无法通过libvirt以编程方式获得此限制,因此在 [libvirt] 部分的 nova.conf 中引入一个新的配置选项,以设置每个SEV功能计算主机的此库存的大小。这将默认设置为 None,具有前瞻性含义“自动检测库存,或者如果这不可能,则不要施加任何限制”。这将有两个好处

    1. 运营商不必进行任何配置更改即可开箱即用地利用SEV。如果主机实际容量被超过,guest VM可能会启动失败,但如果这成为问题,运营商可以设置该值。

    2. 一旦引入自动检测,就不需要进行任何配置更改。例如,如果自动检测获得与手动配置的限制相同的值,则可以发出警告弃用该配置选项,如果它获得不同的值,则可以引发错误,或者至少发出警告,将使用自动检测到的值。

    有关更多信息,请参阅 限制 部分。

  • 当flavor extra specs中存在 resources:MEM_ENCRYPTION_CONTEXT=1 时,更改libvirt驱动程序以在guest的domain定义中包含额外的XML,以确保以下内容

    • 通过 <launchSecurity> 元素启用SEV安全,如以下 SEV启动时配置 部分所述。

    • 启动盘不能是 virtio-blk(由于与bounce buffer相关的资源限制)。

    • VM使用machine type q35 和通过OVMF的UEFI。(q35 是必需的,以便将所有virtio设备绑定到PCIe桥,以便它们使用virtio 1.0而不是virtio 0.9,因为QEMU的 iommu_platform 功能仅在virtio 1.0中添加。)

      如果SEV对Q35 machine type的要求不能由image指定的 hw_machine_type 满足(如果存在),或者由 nova.conf 中的 libvirt.hw_machine_type 指定的值(默认情况下未设置),则应引发异常,以便构建失败。

    • 对于所有virtio设备,iommu 属性为 on。尽管名称如此,这并不要求guest或主机具有IOMMU设备,而仅仅启用virtio标志,指示应使用虚拟化DMA。这与SEV代码相关联,以处理内存加密/解密,并防止IO buffer在主机和guest之间共享。

      DMA将通过bounce buffer进行,因此与非SEV guest相比,预计会有一些开销。

      (注意:virtio-net设备队列未加密。)

    • 出于以下原因,<locked/> 元素存在于domain的XML的 <memoryBacking> 部分,原因在下面的 内存锁定和会计 部分中解释。

    例如,假设一个4GB的VM

    <domain type='kvm'>
      <os>
        <type arch='x86_64' machine='pc-q35-2.11'>hvm</type>
        <loader readonly='yes' type='pflash'>/usr/share/qemu/ovmf-x86_64-ms-4m-code.bin</loader>
        <nvram>/var/lib/libvirt/qemu/nvram/sles15-sev-guest_VARS.fd</nvram>
        <boot dev='hd'/>
      </os>
      <launchSecurity type='sev'>
        <cbitpos>47</cbitpos>
        <reducedPhysBits>1</reducedPhysBits>
        <policy>0x0037</policy>
      </launchSecurity>
      <memoryBacking>
        <locked/>
        ...
      </memoryBacking>
      <devices>
        <rng model='virtio'>
          <driver iommu='on'/>
          ...
        </rng>
        <memballoon model='virtio'>
          <driver iommu='on' />
          ...
        </memballoon>
        ...
        <video>
          <model type='qxl' ram='65536' vram='65536' vgamem='16384' heads='1'  primary='yes'/>
        </video>
        ...
      </devices>
      ...
    </domain>
    

    作为参考,AMDSEV GitHub存储库 提供 一个完整的示例,其中启用了 libvirt的SEV选项 的domain的XML定义。

  • 添加对flavor extra specs中新的 hw:mem_encryption 参数和image属性 hw_mem_encryption 的支持。当其中任何一个设置为 true 时,它将在后台转换为 resources:MEM_ENCRYPTION_CONTEXT=1,这将添加到 RequestSpec 对象中的flavor extra specs中。(此对flavor的更改仅影响此启动上下文,不会持久保存到数据库。)

    实现这个新参数,隐藏资源库存和分配的实现,具有一些优势

    1. 它使其更用户友好,更侧重于提供的功能。

    2. 它允许我们在不更改用户界面的情况下更改或扩展实现,例如在添加来自其他供应商的类似功能的支持时。

    3. 从image属性到extra spec的转换允许我们为故意设计的决策提供一个特殊例外,即image属性通常不会像 extra specs允许的那样,促进对特定资源类的要求。

SEV启动时配置

cbitposreducedPhysBits 取决于处理器系列,可以通过 domain capabilities 中的 sev 元素获得。

policy 允许特定的SEV策略,如 AMD SEV-KM API规范 中所述。最初,该策略将被硬编码,并且不能被云租户或云运营商修改。该策略将是

#define SEV_POLICY_NORM \
    ((SEV_POLICY)(SEV_POLICY_NODBG|SEV_POLICY_NOKS| \
      SEV_POLICY_DOMAIN|SEV_POLICY_SEV))

这相当于 0x0033。将来,当hypervisor软件堆栈中添加支持时,这将允许实时迁移到同一集群中的其他机器 [1](即,具有相同的OCA证书),但不会允许其他guest或hypervisor直接检查内存。

可以提交未来的规范来通过extra spec或image属性使此策略可配置。

SEV-ES(加密状态,加密guest寄存器状态以保护其免受hypervisor侵害)尚未准备好,但以后可能会添加到此策略中。

内存锁定和会计

在domain的XML的 <memoryBacking> 部分中存在 <locked/> 元素,将导致libvirt将 -realtime mlock=on 传递给QEMU,反过来 导致QEMU将RLIMIT_MEMLOCK设置为RLIM_INFINITY

这是由于以下因素链造成的

  • 虽然 -realtime mlock=on导致QEMU调用mlockall(2),以防止页面交换出去,但这不足以防止锁定的页面在物理内存中迁移,如 Unevictable LRU基础设施内核文档 的“迁移mlocked页面”部分中解释的那样。

  • 同样,虽然使用hugepages可以固定页面以防止它们交换出去,但它不能防止它们迁移。此外 hugepages只能固定guest RAM,而不能固定QEMU所需的其他内存块。

    话虽如此,hugepages仍然可以用于会计,如下所述。

  • QEMU 分配的所有内存页都必须被固定(pin),(不仅仅是分配给客户机 RAM 的那些,还包括视频 RAM、UEFI ROM / pflash、pc.rom、isa-bios 和 ACPI 表),这样它们甚至不能在物理内存中迁移,更不用说交换出去了。这是因为 SEV 内存加密引擎使用一种调整方式,使得不同位置的两个相同的明文页将具有不同的密文,因此交换或移动两个页面的密文不会导致明文被交换。在典型的页面迁移中,pgtable 表会被更新,内容会从源地址复制到目标地址。但是,在 SEV 的情况下,内容复制阶段将不会产生正确的结果,因为页面包含加密的数据。

  • 因此,为了固定分配的页面以防止它们迁移,QEMU 的 SEV 实现将发出特殊的 KVM_MEMORY_ENCRYPT_{REG,UNREG}_REGION ioctls,如 内核的 KVM API 文档 中所述。

    这些 ioctls 接收内存区域并将它们固定,使用内核 API 确保这些范围被排除在页面移动 rcu 列表中。在固定页面时,KVM 会检查 RLIMIT_MEMLOCK,以确保它不会盲目地执行请求并超过该 rlimit。如果 rlimit 不够大,则通过此 ioctl 固定页面将失败。

  • 最初的计划是通过在域的 XML 的 <memtune> 部分设置一个硬内存限制 <hard_limit> 来确保 rlimit 足够高。但是,后来有人指出,不仅很难计算 rlimit 的安全上限,并且使用不正确的值会导致虚拟机崩溃,而且这可能非常浪费,因为每个客户机都需要最坏情况(最高)的上限。

  • 因此,提出了一种更好的方法,即为每个客户机设置 rlimit 为 RLIM_INFINITY,并在 /machine.slice 顶级 cgroup 中实施主机内存预留,并将所有 VM 放置在该 cgroup 内部。后者将保护宿主机操作系统免于因 VM 过度提交而耗尽内存。

这个正确的内存会计和安全的内存锁定的问题并非 SEV 特有的。诚然,SEV 要求锁定内存中的页面以防止使用交换,这改变了当发生过度订阅时潜在影响的性质,因此,而不是启动 VM 并产生大量的交换,VM 将首先无法启动。事实上,从某种意义上说,这种“快速失败”的方法更可取,因为它不太可能影响已经运行的其他 VM。

有人建议使用 hugepages 来实现 SEV 客户机,这不仅对性能有益,而且还可以重用 nova 现有的跟踪每个 NUMA 节点 hugepages 并将其计入资源跟踪器的能力。但是,看来这只能对客户机 RAM 进行会计,而不能对 QEMU 要求的其他内存块进行会计。

其他选项包括 reserved_host_memory_mb,甚至只是让操作系统发行版负责在上述 /machine.slice cgroup 中配置 rlimit,在它们的虚拟化堆栈中。

但是,只要向操作员提供关于如何正确缓解这些与内存预留相关的风险的明确指导(如在下面的 文档影响 部分中详细说明),建议获得完整的解决方案应超出此规范的范围,因此不应阻止它。

请注意,预计这种内存固定将是一个临时要求;最新的固件已经支持页面复制(如 AMD SEV-KM API 规范 中记录的 COPY API),因此,当操作系统开始支持页面移动或页面迁移命令时,将不再需要它。但是,我们仍然需要使用较旧的固件和内核组合。

限制

以下限制将来可能会被移除,因为硬件、固件和各种软件层会收到新功能

  • SEV 加密的 VM 尚未能够进行实时迁移或挂起,因此也无法恢复。如前所述,未来将支持该功能。但是,这意味着在短期内,使用 SEV 将对计算节点维护产生影响,因为 SEV 加密的实例需要在迁移掉 SEV 主机之前完全关闭。

  • SEV 加密的 VM 不能包含直接可访问的主机设备(PCI 直通)。因此,例如 mdev vGPU 支持目前无法工作。但是,基于 vhost-user 的技术应该可以正常工作。

  • SEV 加密的 VM 的启动磁盘不能是 virtio-blk。使用 virtio-scsi 或 SATA 作为启动磁盘可以正常工作,正如 virtio-blk 用于非启动磁盘一样。

  • 操作员最初需要手动为每个计算主机指定 SEV 客户机的上限,通过上面提出的新配置选项。这是当前缺乏通过 libvirt 以编程方式发现 SEV 客户机限制的机制的短期解决方法。

    此配置选项暂时将提出的 SEV 检测代码从必需降低到更安全的检查,以防止操作员在非 SEV 主机上意外将配置值设置为非零。但是,检测代码 已经接近完成,并且从长远来看仍然值得拥有,因为它将允许我们在能够以编程方式获得它时删除操作员手动指定上限的要求。截至撰写本文时,一个补丁正在审查中,以在 QEMU 中公开 SEV 客户机限制,但最早要到 4.1.0 版本才能提供。预计会有一个 后续补丁到 libvirt,它将通过上述 <domainCapabilities> XML 公开它。

    如果可以以编程方式检测到限制,此配置选项以后可能会降级为无法检测限制时使用的回退值,甚至完全删除,当 nova 的最低 QEMU 版本保证始终可以检测到它时。

    部署工具可能会分层设置一个额外的集中配置值,代表 SEV 自动检测到的主机默认非零限制。例如,如果您的所有 SEV 兼容主机都是具有相同最大 15 个 SEV 客户机的 EPYC 机器,则可以在一个地方将其设置为 15,然后依靠 已经提出的自动 SEV 检测代码MEM_ENCRYPTION_CONTEXT 库存设置为 15,而无需在每个主机上手动设置它。

  • 在初始实现中,VM 启动时可能会偶尔发生故障,例如,如果 q35 机器类型不可用(尽管这种情况应该很少见,因为 q35 已经有近 11 年的历史了),或者其他必需的虚拟组件(如 UEFI)不可用。未来的工作可能会跟踪所需组件的可用性,以便更早地在放置时发生故障。这可能会增加放置找到可以提供所有必需组件的替代主机的机会,从而成功启动客户机。

预计以下限制将是长期的

  • 允许并发运行的 SEV 客户机数量始终是有限的。在 EPYC 机器上,它将限制为 15 个客户机。

  • 在加密虚拟机中运行的操作系统必须包含 SEV 支持。

  • q35 机器类型不提供 IDE 控制器,因此不支持 IDE 设备。特别是,这意味着 nova 的 libvirt 驱动程序在 x86_64 架构上的当前默认行为是将配置驱动器作为 iso9660 IDE CD-ROM 设备附加将不起作用。有两种潜在的解决方法

    1. nova.conf 中的 CONF.config_drive_format 从其默认值 iso9660 更改为 vfat。这将导致使用 virtio。但是,此主机设置可能会破坏期望配置驱动器为 IDE CD-ROM 的旧版操作系统的镜像。它也不会处理其他 CD-ROM 设备。

    2. 将(很大程度上 未记录)的图像属性 hw_cdrom_bus 设置为 virtio,建议将其作为 ide 的替代品,并将 hw_scsi_model 设置为 virtio-scsi

    一些可能更干净的长期解决方案,需要代码更改,被建议作为 工作项目 部分中的拉伸目标。

为了消除任何疑问,以下操作预计在使用 SEV 加密时不会受到限制

  • 冷迁移或搁置,因为它们在操作之前会关闭 VM,此时没有加密的内存(尽管这可能会改变,因为目前正在添加对 PMEM 的支持)

  • 快照,因为它只快照磁盘

  • 撤离,因为只有在假定 VM 已死或有充分理由将其杀死时才会启动它

  • 附加任何卷,只要它们不需要通过 IDE 总线附加

  • 使用 spice / VNC / serial / RDP 控制台

  • VM 客户机虚拟 NUMA(也称为 vNUMA)

备选方案

有人建议以特定于供应商的方式命名资源类,例如 AMD_SEV_CONTEXT。这将避免对来自 Intel(例如 MKTME)和其他未来供应商的类似功能进行硬编码假设,这些功能将受到可以并发运行的具有加密内存的客户机数量的限制。但是,这会引发其他挑战;例如,在具有来自 AMD 和 Intel 的混合计算硬件的云中,两者都提供安全的加密客户机内存功能,当前的规范无法表达对任一AMD SEV 硬件Intel MKTME 硬件的需求。因此,将无法将供应商无关的 hw:mem_encryption=true 额外规范参数或 hw_mem_encryption 图像属性转换为实现所需效果的额外规范参数。

在先前版本的此规范中,最初提出了关于 SEV 的一些根本不同的 方法,该版本被 Stein 接受。但是,从那时起,大量代码已被合并和提交以供审查,以实现上述主要提出的更改,更不用说花费了大量时间来完善这种方法。

因此,似乎不太可能使用这些替代方法中的任何一种,特别是考虑到从面向特征的设计转变为面向新资源类别的设计,因此此处省略了它们。

数据模型影响

将使用一个新的资源类来盘点 SEV 客户机的插槽,这些插槽位于支持 SEV 的计算主机上。

将使用一个新的配置选项(至少在短期内)来指定每个计算主机上可运行的 SEV 客户机的最大数量。

不需要新的数据对象或数据库模式更改。

REST API 影响

没有,尽管未来的工作可能需要扩展 REST API,以便用户可以验证固件是否正确加密了内存。但是,如果这种扩展对多个 CPU 供应商的其他 virt 驱动程序没有用处,那么最好通过独立的 AMD 特定服务来提供此功能。

安全影响

此更改不会添加或处理任何秘密信息,除了当然是客户机 VM 加密内存中的数据。用于实现 SEV 的密钥被锁定在 AMD 硬件内部。硬件随机数生成器使用来自 NIST SP 800-90A 的 CTR_DRBG 结构,该结构未被发现容易受到任何后门攻击。它使用 AES 计数器模式生成随机数。

SEV 保护 VM 的数据免受来自 VM 外部的攻击,包括超visor 和其他 VM。试图欺骗超visor 从另一个 VM 读取页面的攻击将不起作用,因为获得的数据将使用攻击者和超visor 无法访问的密钥进行加密。SEV 通过使用所有者标记每个缓存行来保护缓存中的数据,从而防止超visor 和其他 VM 读取缓存的数据。

SEV 不保护 VM 本身免受侧信道攻击或运行在 VM 上的软件攻击。保持 VM 更新补丁并正确配置 VM 上运行的软件非常重要。

这个首次提出的实现提供了一些保护,但显著缺乏云用户验证SEV能够提供的认证的能力,该认证可以通过LAUNCH_MEASURE固件调用来实现。未来添加这种认证能力意味着需要对云管理员的信任度降低很多,因为虚拟机将使用云用户通过受保护的通道提供给SEV固件的密钥进行加密和完整性保护。然后,云用户可以确定他们正在运行正确的镜像,内存确实已加密,并且他们正在运行具有SEV硬件的真实AMD平台,而不是设置用于窃取数据的冒名平台。云用户可以在向虚拟机提供额外的密钥(例如存储解密密钥)之前验证所有这些。本规范是实现SEV可以提供的全部价值以防止云管理员访问云用户数据的过程中的第一步。

强烈建议将OpenStack安全组纳入其中,并有机会审查每个阶段的工作,以帮助确保安全措施得到适当实施。

通知影响

可能需要访问实例正在加密运行的信息,例如,计费云提供商可能希望征收安全附加费,即加密实例的计费方式与未加密实例不同。但是,这不应立即影响通知,因为版本化通知中的实例有效负载包含flavor及其额外的specs,其中将定义MEM_ENCRYPTION_CONTEXT资源。

如果SEV资源是在服务器的backing image上指定的,而不是在flavor上指定的,则通知中只会包含image UUID。消费者可以通过UUID查找image以检查是否存在MEM_ENCRYPTION_CONTEXT资源,但这确实会打开一个潜在的竞争窗口,即image属性可能会在实例创建后发生更改。可以通过未来的工作来解决这个问题,该工作将包括在实例启动通知中包含image属性,或者将image元数据存储在instance_extra中,就像目前flavor一样。或者,仅检查extra specs中的resources:MEM_ENCRYPTION_CONTEXT=1是否足够。

其他最终用户影响

最终用户将通过flavor extra specs和image属性中的资源机制来利用SEV。稍后,添加对调度器提示的支持可能是有意义的(请参阅下面的未来工作部分)。

性能影响

预计不会对nova产生性能影响。

初步测试表明,启用SEV对VM的预期性能影响是适度的;根据特定的工作负载和测试,观察到1%到6%的降解。更多详细信息可以在AMD在2017年Linux安全峰会上关于SEV-ES的演示文稿的幻灯片4-6中看到。

如果交换磁盘正在使用压缩,则可能需要更多的存储空间,因为加密VM的内存将无法压缩到更小的尺寸。

内存去重机制,例如KSM(内核相同页合并),将被渲染无效。

其他部署者影响

为了让用户能够使用SEV,操作员需要执行以下步骤

  • 将SEV兼容的硬件作为nova计算主机部署。

  • 确保他们拥有适当配置的软件堆栈,以便各个层级都已准备好SEV

    • kernel >= 4.16

    • QEMU >= 2.12

    • libvirt >= 4.5

    • ovmf >= commit 75b7aa9528bd 2018-07-06

最后,云管理员需要定义SEV启用的flavor,如上所述,除非用户定义SEV启用的image就足够了。

开发人员影响

升级影响

实现

负责人

主要负责人

adam.spiers

其他贡献者

来自SUSE和AMD的各种开发人员

工作项

预计nova的libvirt驱动程序需要进行以下扩展或类似扩展

  1. 添加对主机SEV功能的检测,如上所述。

  2. nova.conf[libvirt]部分添加一个新的配置选项,以设置每个SEV计算主机允许的SEV guest的最大数量。

  3. 添加一个新的MEM_ENCRYPTION_CONTEXT资源类,表示每个SEV计算主机上可用的离散插槽数。

  4. 使libvirt驱动程序更新ProviderTree对象,以使用新的MEM_ENCRYPTION_CONTEXT资源类的正确库存。目前,使用上面介绍的新配置选项设置此值。它还应考虑SEV检测代码的结果。

  5. 更新os-traits中HW_CPU_AMD_SEV trait的文档。

  6. 添加一个新的nova.virt.libvirt.LibvirtConfigGuestSEVLaunchSecurity类来描述<launchSecurity/>元素。

  7. 扩展nova.virt.libvirt.LibvirtDriver,以便如果allocations字典中包含MEM_ENCRYPTION_CONTEXT=1,并且主机是SEV兼容的,则将所需的XML添加到VM的domain定义中。

  8. 确定是否应使用hugepages,如果是,它们是否可以帮助进行会计。

  9. 添加对flavor extra specs中的新hw:mem_encryption参数和image属性hw_mem_encryption的支持,如上所述。很可能这些可以通过request_filter.py中的新请求过滤器来实现。

  10. 由于SEV加密实例之间的实时迁移尚未支持,

    阻止nova实时迁移任何SEV加密实例,或调整到不同的计算主机。或者,nova可以捕获QEMU引发的错误,该错误将通过libvirt传播,并适当处理。如果对操作员来说这成为一个主要问题,我们可以稍后构建更高层次的检查。

  11. 同样,尝试暂停/恢复SEV加密的domain尚未支持,因此应阻止它们,或者捕获错误并处理它们。

  12. (Stretch goal) 采用以下建议的代码更改,以减少或消除CD-ROM设备(例如config drive)在x86架构上使用IDE总线的情况

    1. 简单地将x86上CD-ROM的硬编码IDE总线使用情况更改为scsi,以与所有其他CPU架构保持一致,因为似乎ide的使用仅由于x86的遗留代码以及后来添加了对其他CPU架构的支持。image属性hw_cdrom_bus=ide可以覆盖旧image上缺少SCSI支持的情况。

    2. 自动检测VM没有IDE控制器的案例,并自动切换到scsivirtio-scsi

    3. 引入一个新的nova.conf选项,用于指定CD-ROM默认使用的总线。然后,默认值可以是scsi(与其他CPU架构一致)或virtiohw_cdrom_bus可以覆盖所需时此值。这可能更具未来证明,因为非常旧的机器类型的逐渐淘汰,尽管缺点是可能破坏旧image。

      如果存在使用此类旧x86 image很常见的云,则可以将选项设置为ide,并且hw_cdrom_bus=virtio覆盖在需要SEV(或任何其他原因)的较新机器类型时的情况。虽然这可能不太可能,因此不需要新的配置选项。

此外,应编写文档,如文档影响部分所述。

未来工作

展望Train之外,nova的SEV支持还有许多额外的改进空间

  • 扩展ComputeCapabilitiesFilter调度器过滤器以支持调度器提示,以便可以为每个实例选择启用SEV,从而无需操作员配置SEV特定的flavor或image。

  • 如果用户有足够的需求,则可以通过extra spec或image属性使SEV策略可配置。

  • 提供一种机制,让用户可以访问SEV的LAUNCH_MEASURE命令提供的认证测量结果,以便验证固件是否正确加密了guest内存。例如,可以扩展nova的API;但是,如果无法以适用于所有virt驱动程序/CPU供应商的方式完成,则可能超出nova的范围,需要替代方法,例如AMD专用的端点。

依赖项

测试

测试驱动程序fakelibvirt需要进行调整以模拟SEV兼容的硬件。

需要扩展或添加相应的单元/功能测试,以涵盖

  • 检测SEV兼容的硬件和软件,例如,作为nova.tests.functional.libvirt.test_report_cpu_traits.LibvirtReportTraitsTests的扩展。

  • nova.tests.unit.virt.libvirt.test_config中包含额外的SEV特定libvirt domain XML配置的trait的使用

Nova代码或其测试中可能存在由于面向Intel CPU的硬编码假设而导致的问题。

如果可用SEV硬件,则可以在gate或通过第三方CI中包含Tempest测试。

文档影响

  • 应在Feature Support Matrix中添加一个新条目,该条目引用了新的trait并显示当前的限制

  • 应更新Configuration Guide的KVM部分,其中包含有关如何设置SEV兼容的hypervisor的详细信息。同样,明智的做法是提及当前的限制,包括对config drive配置的影响、计算主机维护、根据预期同时在主机上运行的SEV guest的最大数量正确计算reserved_host_memory_mb的需要,以及上面提供的关于如何正确计算它的详细信息(例如内存区域大小)。

还应更新其他非nova文档

参考资料

历史

修订版

发布名称

描述

Train

重新批准

Stein

引入