受保护执行设施

简介

受保护执行设施 (PEF) 是 POWER 9 的架构变更,它支持安全虚拟机 (SVM)。DD2.3 芯片(PVR=0x004e1203)或更高版本将支持 PEF。新的 ISA 版本将包含 PEF RFC02487 的更改。

启用后,PEF 会为 POWER 架构添加一种新的更高特权模式,称为 Ultravisor 模式。除了新模式之外,还有一种称为受保护执行 Ultravisor(简称 Ultravisor)的新固件。Ultravisor 模式是 POWER 架构中特权最高的模式。

特权状态

问题

管理程序

Hypervisor

Ultravisor

PEF 保护 SVM 免受 hypervisor、特权用户和系统中其他虚拟机的攻击。SVM 在闲置时受到保护,只能由授权的机器执行。所有虚拟机都利用 hypervisor 服务。Ultravisor 过滤 SVM 和 hypervisor 之间的调用,以确保信息不会意外泄漏。除了 H_RANDOM 之外,所有超级调用都会反映到 hypervisor。H_RANDOM 不会反映,以防止 hypervisor 影响 SVM 中的随机值。

为了支持这一点,CPU 中资源的所有权进行了重构。一些以前是 hypervisor 特权的资源现在是 ultravisor 特权的。

硬件

硬件更改包括以下内容

  • MSR 中有一个新位,用于确定当前进程是否在安全模式下运行,MSR(S) 位 41。MSR(S)=1,进程处于安全模式,MSR(s)=0 进程处于正常模式。

  • MSR(S) 位只能由 Ultravisor 设置。

  • HRFID 不能用于设置 MSR(S) 位。如果 hypervisor 需要返回到 SVM,它必须使用 ultracall。它可以确定它要返回的 VM 是否安全。

  • 有一个新的 Ultravisor 特权寄存器 SMFCTRL,它有一个启用/禁用位 SMFCTRL(E)。

  • 进程的特权现在由三个 MSR 位 MSR(S, HV, PR) 确定。在下面的每个表中,模式都按从最低特权到最高特权的顺序列出。特权较高的模式可以访问特权较低的模式的所有资源。

    安全模式 MSR 设置

    S

    HV

    PR

    特权

    1

    0

    1

    问题

    1

    0

    0

    特权(操作系统)

    1

    1

    0

    Ultravisor

    1

    1

    1

    保留

    正常模式 MSR 设置

    S

    HV

    PR

    特权

    0

    0

    1

    问题

    0

    0

    0

    特权(操作系统)

    0

    1

    0

    Hypervisor

    0

    1

    1

    问题(主机)

  • 内存被划分为安全内存和正常内存。只有在安全模式下运行的进程才能访问安全内存。

  • 硬件不允许任何不在安全模式下运行的进程访问安全内存。这意味着 hypervisor 无法在不使用 ultracall(询问 Ultravisor)的情况下访问 SVM 的内存。Ultravisor 只允许 hypervisor 查看加密的 SVM 内存。

  • 不允许 I/O 系统直接寻址安全内存。这限制了 SVM 只能使用虚拟 I/O。

  • 该架构允许 SVM 与 hypervisor 共享未受加密保护的内存页。但是,此共享必须由 SVM 发起。

  • 当进程在安全模式下运行时,所有超级调用(syscall lev=1)都会转到 Ultravisor。

  • 当进程处于安全模式时,所有中断都会转到 Ultravisor。

  • 以下资源已变为 Ultravisor 特权,需要 Ultravisor 接口来操作

    • 处理器配置寄存器 (SCOM)。

    • 停止状态信息。

    • 当 SMFCTRL(D) 设置时,调试寄存器 CIABR、DAWR 和 DAWRX。如果未设置 SMFCTRL(D),则它们在安全模式下不起作用。设置后,读取和写入需要 Ultravisor 调用,否则会导致 Hypervisor 模拟辅助中断。

    • PTCR 和分区表条目(分区表位于安全内存中)。尝试写入 PTCR 将导致 Hypervisor 模拟辅助中断。

    • LDBAR(LD 基地址寄存器)和 IMC(内存中收集)非架构寄存器。尝试写入它们将导致 Hypervisor 模拟辅助中断。

    • SVM 的分页,与 Hypervisor 共享 SVM 的内存。(包括虚拟处理器区域 (VPA) 和虚拟 I/O)。

软件/微代码

软件更改包括

  • SVM 是使用 IBM 提供的(开源)工具从正常 VM 创建的。

  • 所有 SVM 都以正常 VM 的身份启动,并利用 ultracall UV_ESM(进入安全模式)进行转换。

  • 当发出 UV_ESM ultracall 时,Ultravisor 将 VM 复制到安全内存中,解密验证信息,并检查 SVM 的完整性。如果完整性检查通过,Ultravisor 将在安全模式下传递控制。

  • 验证信息包括与 SVM 关联的加密磁盘的密码。此密码在请求时会提供给 SVM。

  • Ultravisor 不参与保护静止时 SVM 的加密磁盘。

  • 对于外部中断,Ultravisor 保存 SVM 的状态,并将中断反映到 hypervisor 进行处理。对于超级调用,Ultravisor 将中性状态插入到所有不需要用于超级调用的寄存器中,然后将调用反映到 hypervisor 进行处理。H_RANDOM 超级调用由 Ultravisor 执行,不反映。

  • 为了使虚拟 I/O 工作,必须进行反弹缓冲。

  • Ultravisor 使用 AES (IAPM) 来保护 SVM 内存。IAPM 是一种 AES 模式,可同时提供完整性和保密性。

  • 正常页面和安全页面之间的数据移动由 Hypervisor 中的新 HMM 插件与 Ultravisor 协调。

Ultravisor 为 hypervisor 和 SVM 提供新服务。这些服务通过 ultracall 访问。

术语

  • 超级调用:用于请求 Hypervisor 服务的特殊系统调用。

  • 正常内存:Hypervisor 可访问的内存。

  • 正常页面:由正常内存支持并可用于 Hypervisor 的页面。

  • 共享页面:由正常内存支持并可供 Hypervisor/QEMU 和 SVM 使用的页面(即页面在 SVM 和 Hypervisor/QEMU 中都有映射)。

  • 安全内存:仅 Ultravisor 和 SVM 可以访问的内存。

  • 安全页面:由安全内存支持且仅可供 Ultravisor 和 SVM 使用的页面。

  • SVM:安全虚拟机。

  • Ultracall:用于请求 Ultravisor 服务的特殊系统调用。

Ultravisor 调用 API

本节介绍支持安全虚拟机 (SVM) 和准虚拟化 KVM 所需的 Ultravisor 调用 (ultracall)。Ultracall 允许 SVM 和 Hypervisor 从 Ultravisor 请求服务,例如访问只能在以 Ultravisor 特权模式运行时才能访问的寄存器或内存区域。

ultracall 中所需的特定服务在寄存器 R3(ultracall 的第一个参数)中指定。ultracall 的其他参数(如果有)在寄存器 R4 到 R12 中指定。

所有 ultracall 的返回值都在寄存器 R3 中。ultracall 的其他输出值(如果有)在寄存器 R4 到 R12 中返回。此寄存器使用的唯一例外是下面描述的 UV_RETURN ultracall。

每个 ultracall 都返回特定的错误代码,这些错误代码适用于 ultracall 的上下文。但是,与 PowerPC 架构平台参考 (PAPR) 一样,如果没有为特定情况定义特定的错误代码,则 ultracall 将回退到基于参数位置的错误代码。即 U_PARAMETER、U_P2、U_P3 等,具体取决于可能导致错误的 ultracall 参数。

一些超调用涉及到在 Ultravisor 和 Hypervisor 之间传输数据页。从安全内存传输到普通内存的安全页可能会使用动态生成的密钥进行加密。当安全页传输回安全内存时,可以使用相同的动态生成的密钥进行解密。这些密钥的生成和管理将在单独的文档中介绍。

目前,这仅涵盖 Hypervisor 和 SVM 当前实现和正在使用的超调用,但当有意义时,可以在此处添加其他超调用。

所有 hypercall/ultracall 的完整规范最终将在 PAPR 规范的公共/OpenPower 版本中提供。

注意

如果未启用 PEF,超调用将被重定向到 Hypervisor,Hypervisor 必须处理/失败这些调用。

Hypervisor 使用的超调用

本节介绍 Hypervisor 用于管理 SVM 的虚拟内存管理超调用。

UV_PAGE_OUT

加密并将页面的内容从安全内存移动到普通内存。

语法
uint64_t ultracall(const uint64_t UV_PAGE_OUT,
        uint16_t lpid,          /* LPAR ID */
        uint64_t dest_ra,       /* real address of destination page */
        uint64_t src_gpa,       /* source guest-physical-address */
        uint8_t  flags,         /* flags */
        uint64_t order)         /* page size order */
返回值

以下值之一

  • 成功时返回 U_SUCCESS。

  • 如果 lpid 无效,则返回 U_PARAMETER。

  • 如果 dest_ra 无效,则返回 U_P2。

  • 如果 src_gpa 地址无效,则返回 U_P3。

  • 如果 flags 中的任何位无法识别,则返回 U_P4。

  • 如果不支持 order 参数,则返回 U_P5。

  • 如果不支持该功能,则返回 U_FUNCTION。

  • 如果页面当前无法分页输出,则返回 U_BUSY。

描述

加密安全页面的内容,并使其在普通页面中可供 Hypervisor 使用。

默认情况下,源页面会从 SVM 的分区范围页表中取消映射。但是,Hypervisor 可以通过在 flags 参数中设置 UV_SNAPSHOT 标志来提示 Ultravisor 保留页面映射。

如果源页面已经是共享页面,则该调用返回 U_SUCCESS,而不执行任何操作。

用例
  1. QEMU 尝试访问属于 SVM 的地址,但该地址的页面帧未映射到 QEMU 的地址空间中。在这种情况下,Hypervisor 将分配一个页面帧,将其映射到 QEMU 的地址空间中,并发出 UV_PAGE_OUT 调用以检索该页面的加密内容。

  2. 当 Ultravisor 安全内存不足并且需要分页输出 LRU 页面时。在这种情况下,Ultravisor 将向 Hypervisor 发出 H_SVM_PAGE_OUT hypercall。然后,Hypervisor 将分配一个普通页面并发出 UV_PAGE_OUT 超调用,Ultravisor 将加密并将安全页面的内容移动到普通页面中。

  3. 当 Hypervisor 访问 SVM 数据时,Hypervisor 会请求 Ultravisor 将相应的页面传输到 Hypervisor 可以访问的不安全页面中。但是,普通页面中的数据将被加密。

UV_PAGE_IN

将页面的内容从普通内存移动到安全内存。

语法
uint64_t ultracall(const uint64_t UV_PAGE_IN,
        uint16_t lpid,          /* the LPAR ID */
        uint64_t src_ra,        /* source real address of page */
        uint64_t dest_gpa,      /* destination guest physical address */
        uint64_t flags,         /* flags */
        uint64_t order)         /* page size order */
返回值

以下值之一

  • 成功时返回 U_SUCCESS。

  • 如果页面当前无法分页输入,则返回 U_BUSY。

  • 如果不支持该功能,则返回 U_FUNCTION。

  • 如果 lpid 无效,则返回 U_PARAMETER。

  • 如果 src_ra 无效,则返回 U_P2。

  • 如果 dest_gpa 地址无效,则返回 U_P3。

  • 如果 flags 中的任何位无法识别,则返回 U_P4。

  • 如果不支持 order 参数,则返回 U_P5。

描述

src_ra 标识的页面的内容从普通内存移动到安全内存,并将其映射到客户物理地址 dest_gpa

如果 dest_gpa 指向共享地址,则将页面映射到 SVM 的分区范围页表中。如果 dest_gpa 不是共享地址,则将页面的内容复制到相应的安全页面中。根据上下文,在复制之前解密页面。

调用者通过 flags 参数提供页面的属性。flags 的有效值为

  • CACHE_INHIBITED

  • CACHE_ENABLED

  • WRITE_PROTECTION

Hypervisor 必须在进行 UV_PAGE_IN 超调用之前将页面固定在内存中。

用例
  1. 当普通虚拟机切换到安全模式时,其驻留在普通内存中的所有页面都会移动到安全内存中。

  2. 当 SVM 请求与 Hypervisor 共享页面时,Hypervisor 会分配一个页面并通知 Ultravisor。

  3. 当 SVM 访问已分页输出的安全页面时,Ultravisor 会调用 Hypervisor 以查找该页面。找到该页面后,Hypervisor 使用 UV_PAGE_IN 使该页面可供 Ultravisor 使用。

UV_PAGE_INVAL

使 Ultravisor 的页面映射无效。

语法
uint64_t ultracall(const uint64_t UV_PAGE_INVAL,
        uint16_t lpid,          /* the LPAR ID */
        uint64_t guest_pa,      /* destination guest-physical-address */
        uint64_t order)         /* page size order */
返回值

以下值之一

  • 成功时返回 U_SUCCESS。

  • 如果 lpid 无效,则返回 U_PARAMETER。

  • 如果 guest_pa 无效(或对应于安全页面映射),则返回 U_P2。

    页面映射)。

  • 如果 order 无效,则返回 U_P3。

  • 如果不支持该功能,则返回 U_FUNCTION。

  • 如果页面当前无法失效,则返回 U_BUSY。

描述

此超调用通知 Ultravisor,Hypervisor 中与给定客户物理地址对应的页面映射已失效,并且 Ultravisor 不应访问该页面。如果指定的 guest_pa 对应于安全页面,则 Ultravisor 将忽略使该页面失效的尝试,并返回 U_P2。

用例
  1. 当共享页面从 QEMU 的页表中取消映射时(可能是因为它已分页输出到磁盘),Ultravisor 需要知道该页面也不应从其侧访问。

UV_WRITE_PATE

验证并写入给定分区的分区表条目 (PATE)。

语法
uint64_t ultracall(const uint64_t UV_WRITE_PATE,
        uint32_t lpid,          /* the LPAR ID */
        uint64_t dw0            /* the first double word to write */
        uint64_t dw1)           /* the second double word to write */
返回值

以下值之一

  • 成功时返回 U_SUCCESS。

  • 如果当前无法写入 PATE,则返回 U_BUSY。

  • 如果不支持该功能,则返回 U_FUNCTION。

  • 如果 lpid 无效,则返回 U_PARAMETER。

  • 如果 dw0 无效,则返回 U_P2。

  • 如果 dw1 地址无效,则返回 U_P3。

  • 如果 Hypervisor 试图更改安全虚拟机的 PATE 或从 Hypervisor 以外的上下文中调用,则返回 U_PERMISSION。

    的 PATE。

描述

验证并写入给定 LPID 的 LPID 及其分区表条目。如果 LPID 已分配和初始化,则此调用会导致更改分区表条目。

用例
  1. 分区表驻留在安全内存中,其条目(称为 PATE(分区表条目))指向 Hypervisor 以及每个虚拟机(包括安全虚拟机和普通虚拟机)的分区范围页表。Hypervisor 在分区 0 中运行,其分区范围页表驻留在普通内存中。

  2. 此超调用允许 Hypervisor 向 Ultravisor 注册 Hypervisor 和其他分区(虚拟机)的分区范围和进程范围的页表条目。

  3. 如果现有分区 (VM) 的 PATE 值发生更改,则该分区的 TLB 缓存将被刷新。

  4. Hypervisor 负责分配 LPID。LPID 及其 PATE 条目一起注册。Hypervisor 管理普通虚拟机的 PATE 条目,并且可以随时更改 PATE 条目。Ultravisor 管理 SVM 的 PATE 条目,Hypervisor 不允许修改它们。

UV_RETURN

在处理完转发(也称为反射)到 Hypervisor 的 hypercall 或中断后,将控制权从 Hypervisor 返回到 Ultravisor。

语法
uint64_t ultracall(const uint64_t UV_RETURN)
返回值

成功后,此调用永远不会返回到 Hypervisor。如果超调用不是从 Hypervisor 上下文发出的,则返回 U_INVALID。

描述

当 SVM 发出 hypercall 或发生其他异常时,Ultravisor 通常会将异常转发(也称为反射)到 Hypervisor。在处理完异常后,Hypervisor 使用 UV_RETURN 超调用将控制权返回给 SVM。

此超调用入口的预期寄存器状态为

  • 非易失性寄存器将恢复到其原始值。

  • 如果从 hypercall 返回,寄存器 R0 包含返回值(与其他超调用不同),寄存器 R4 到 R12 包含 hypercall 的任何输出值。

  • R3 包含超调用编号,即 UV_RETURN。

  • 如果返回合成中断,则 R2 包含合成中断号。

用例
  1. Ultravisor 依靠 Hypervisor 向 SVM 提供多项服务,例如处理 hypercall 和其他异常。在处理完异常后,Hypervisor 使用 UV_RETURN 将控制权返回给 Ultravisor。

  2. Hypervisor 必须使用此超调用将控制权返回给 SVM。

UV_REGISTER_MEM_SLOT

注册具有指定属性的 SVM 地址范围。

语法
uint64_t ultracall(const uint64_t UV_REGISTER_MEM_SLOT,
        uint64_t lpid,          /* LPAR ID of the SVM */
        uint64_t start_gpa,     /* start guest physical address */
        uint64_t size,          /* size of address range in bytes */
        uint64_t flags          /* reserved for future expansion */
        uint16_t slotid)        /* slot identifier */
返回值

以下值之一

  • 成功时返回 U_SUCCESS。

  • 如果 lpid 无效,则返回 U_PARAMETER。

  • 如果 start_gpa 无效,则返回 U_P2。

  • 如果 size 无效,则返回 U_P3。

  • 如果 flags 中的任何位无法识别,则返回 U_P4。

  • 如果不支持 slotid 参数,则返回 U_P5。

  • 如果从 Hypervisor 以外的上下文中调用,则返回 U_PERMISSION。

  • 如果不支持该功能,则返回 U_FUNCTION。

描述

为 SVM 注册内存范围。内存范围从客户物理地址 start_gpa 开始,长度为 size 字节。

用例
  1. 当虚拟机进入安全状态时,Hypervisor 管理的所有内存槽都会移动到安全内存中。Hypervisor 会遍历每个内存槽,并将该槽注册到 Ultravisor。Hypervisor 可能会丢弃一些槽,例如用于固件 (SLOF) 的槽。

  2. 当热插拔新内存时,会注册一个新的内存槽。

UV_UNREGISTER_MEM_SLOT

注销先前使用 UV_REGISTER_MEM_SLOT 注册的 SVM 地址范围。

语法
uint64_t ultracall(const uint64_t UV_UNREGISTER_MEM_SLOT,
        uint64_t lpid,          /* LPAR ID of the SVM */
        uint64_t slotid)        /* reservation slotid */
返回值

以下值之一

  • 成功时返回 U_SUCCESS。

  • 如果不支持该功能,则返回 U_FUNCTION。

  • 如果 lpid 无效,则返回 U_PARAMETER。

  • 如果 slotid 无效,则返回 U_P2。

  • 如果从 Hypervisor 以外的上下文中调用,则返回 U_PERMISSION。

描述

释放由 slotid 标识的内存槽,并释放为保留分配的任何资源。

用例
  1. 内存热移除。

UV_SVM_TERMINATE

终止 SVM 并释放其资源。

语法
uint64_t ultracall(const uint64_t UV_SVM_TERMINATE,
        uint64_t lpid,          /* LPAR ID of the SVM */)
返回值

以下值之一

  • 成功时返回 U_SUCCESS。

  • 如果不支持该功能,则返回 U_FUNCTION。

  • 如果 lpid 无效,则返回 U_PARAMETER。

  • 如果 VM 不安全,则返回 U_INVALID。

  • 如果不是从 Hypervisor 上下文调用,则返回 U_PERMISSION。

描述

终止 SVM 并释放其所有资源。

用例
  1. 由 Hypervisor 在终止 SVM 时调用。

SVM 使用的超调用

UV_SHARE_PAGE

与 Hypervisor 共享一组客户物理页面。

语法
uint64_t ultracall(const uint64_t UV_SHARE_PAGE,
        uint64_t gfn,   /* guest page frame number */
        uint64_t num)   /* number of pages of size PAGE_SIZE */
返回值

以下值之一

  • 成功时返回 U_SUCCESS。

  • 如果不支持该功能,则返回 U_FUNCTION。

  • 如果 VM 不安全,则返回 U_INVALID。

  • 如果 gfn 无效,则返回 U_PARAMETER。

  • 如果 num 无效,则返回 U_P2。

描述

与 Hypervisor 共享从客户物理帧号 gfn 开始的 num 个页面。假设页面大小为 PAGE_SIZE 字节。在返回之前将页面清零。

如果地址已经由安全页面支持,则取消映射该页面,并在 Hypervisor 的帮助下,使用不安全的页面支持该页面。如果尚未由任何页面支持,则将 PTE 标记为不安全,并在访问该地址时使用不安全的页面支持该页面。如果它已经由不安全的页面支持,则将该页面清零并返回。

用例
  1. Hypervisor 无法访问 SVM 页面,因为它们由安全页面支持。因此,SVM 必须显式地向 Ultravisor 请求它可以与 Hypervisor 共享的页面。

  2. 需要共享页面来支持 SVM 中的 virtio 和虚拟处理器区域 (VPA)。

UV_UNSHARE_PAGE

将共享的 SVM 页面恢复到其初始状态。

语法
uint64_t ultracall(const uint64_t UV_UNSHARE_PAGE,
        uint64_t gfn,   /* guest page frame number */
        uint73 num)     /* number of pages of size PAGE_SIZE*/
返回值

以下值之一

  • 成功时返回 U_SUCCESS。

  • 如果不支持该功能,则返回 U_FUNCTION。

  • 如果 VM 不安全,则返回 U_INVALID。

  • 如果 gfn 无效,则返回 U_PARAMETER。

  • 如果 num 无效,则返回 U_P2。

描述

停止与 Hypervisor 共享从 gfn 开始的 num 个页面。假设页面大小为 PAGE_SIZE。在返回之前将页面清零。

如果该地址已经由不安全的页面支持,则取消映射该页面,并使用安全页面支持该页面。通知 Hypervisor 释放对其共享页面的引用。如果该地址尚未由页面支持,则将 PTE 标记为安全,并在访问该地址时使用安全页面支持该页面。如果它已经由安全的页面支持,则将该页面清零并返回。

用例
  1. SVM 可能会决定从 Hypervisor 取消共享一个页面。

UV_UNSHARE_ALL_PAGES

取消共享 SVM 已与 Hypervisor 共享的所有页面。

语法
uint64_t ultracall(const uint64_t UV_UNSHARE_ALL_PAGES)
返回值

以下值之一

  • 成功时返回 U_SUCCESS。

  • 如果不支持该功能,则返回 U_FUNCTION。

  • 如果 VM 不安全,则返回 U_INVAL。

描述

取消共享 Hypervisor 中的所有共享页面。返回时,所有未共享的页面都会被清零。只有 SVM 明确与 Hypervisor 共享的页面(使用 UV_SHARE_PAGE 超调用)才会被取消共享。Ultravisor 可能会在内部与 Hypervisor 共享一些页面,而无需 SVM 的明确请求。这些页面不会被此超调用取消共享。

用例
  1. 当使用 kexec 引导不同的内核时,需要此调用。SVM 重置期间也可能需要此调用。

UV_ESM

保护虚拟机(进入安全模式)。

语法
uint64_t ultracall(const uint64_t UV_ESM,
        uint64_t esm_blob_addr, /* location of the ESM blob */
        unint64_t fdt)          /* Flattened device tree */
返回值

以下值之一

  • 成功时返回 U_SUCCESS(包括 VM 已经安全的情况)。

  • 如果不支持该功能,则返回 U_FUNCTION。

  • 如果 VM 不安全,则返回 U_INVALID。

  • 如果 esm_blob_addr 无效,则返回 U_PARAMETER。

  • 如果 fdt 无效,则返回 U_P2。

  • 如果任何完整性检查失败,则返回 U_PERMISSION。

  • U_RETRY,表示创建 SVM 的内存不足。

  • U_NO_KEY,表示对称密钥不可用。

描述

保护虚拟机。成功完成后,将控制权返回到 ESM Blob 中指定的地址处的虚拟机。

用例
  1. 正常的虚拟机可以选择切换到安全模式。

Hypervisor 调用 API

本文档描述了支持 Ultravisor 所需的 Hypervisor 调用(超调用)。超调用是由 Hypervisor 向虚拟机和 Ultravisor 提供的服务。

这些超调用的寄存器使用方式与 Power Architecture Platform Reference (PAPR) 文档中定义的其他超调用相同。即,在输入时,寄存器 R3 标识所请求的特定服务,寄存器 R4 到 R11 包含超调用的其他参数(如果有)。在输出时,寄存器 R3 包含返回值,寄存器 R4 到 R9 包含超调用的任何其他输出值。

本文档仅涵盖当前为 Ultravisor 用法实现/计划的超调用,但如果合适,可以在此处添加其他超调用。

所有 hypercall/ultracall 的完整规范最终将在 PAPR 规范的公共/OpenPower 版本中提供。

支持 Ultravisor 的 Hypervisor 调用

以下是支持 Ultravisor 所需的一组超调用。

H_SVM_INIT_START

开始将普通虚拟机转换为 SVM 的过程。

语法
uint64_t hypercall(const uint64_t H_SVM_INIT_START)
返回值

以下值之一

  • 成功时返回 H_SUCCESS。

  • 如果 VM 不适合切换到安全模式,则返回 H_STATE。

描述

启动保护虚拟机过程。这包括使用超调用与 Ultravisor 协调,在新 SVM 的 Ultravisor 中分配资源,将 VM 的页面从普通内存转移到安全内存等。当过程完成后,Ultravisor 会发出 H_SVM_INIT_DONE 超调用。

用例
  1. Ultravisor 使用此超调用通知 Hypervisor,VM 已启动切换到安全模式的过程。

H_SVM_INIT_DONE

完成保护 SVM 的过程。

语法
uint64_t hypercall(const uint64_t H_SVM_INIT_DONE)
返回值

以下值之一

  • 成功时返回 H_SUCCESS。

  • 如果从错误的上下文调用(例如,

    从 SVM 或在 H_SVM_INIT_START 超调用之前),则返回 H_UNSUPPORTED。

  • 如果 hypervisor 无法成功

    将 VM 转换为安全 VM,则返回 H_STATE。

描述

完成保护虚拟机的过程。必须在先前调用 H_SVM_INIT_START 超调用之后进行此调用。

用例

成功保护虚拟机后,Ultravisor 会通知 Hypervisor。Hypervisor 可以使用此调用来完成此虚拟机的内部状态设置。

H_SVM_INIT_ABORT

中止保护 SVM 的过程。

语法
uint64_t hypercall(const uint64_t H_SVM_INIT_ABORT)
返回值

以下值之一

  • 成功清理状态后,

    Hypervisor 将此值返回给客户机,以指示底层的 UV_ESM 超调用失败。

  • 如果在 VM 进入安全模式后调用,则返回 H_STATE(即

    H_SVM_INIT_DONE 超调用成功)。

  • 如果从错误的上下文调用(例如,从

    普通 VM),则返回 H_UNSUPPORTED。

描述

中止保护虚拟机的过程。必须在先前调用 H_SVM_INIT_START 超调用之后,以及调用 H_SVM_INIT_DONE 之前进行此调用。

进入此超调用时,预计非易失性 GPR 和 FPR 包含 VM 发出 UV_ESM 超调用时的值。此外,预计 SRR0 包含 UV_ESM 超调用之后指令的地址,SRR1 包含要返回到 VM 的 MSR 值。

此超调用将清理自先前的 H_SVM_INIT_START 超调用以来为 VM 建立的任何部分状态,包括换出已换入安全内存的页面,并发出 UV_SVM_TERMINATE 超调用以终止 VM。

清理部分状态后,控制返回到 VM(不是 Ultravisor),返回到 SRR0 中指定的地址,并将 MSR 值设置为 SRR1 中的值。

用例

如果在成功调用 H_SVM_INIT_START 之后,Ultravisor 在保护虚拟机时遇到错误,无论是由于资源不足还是因为无法验证 VM 的安全信息,Ultravisor 都会通知 Hypervisor。Hypervisor 应该使用此调用来清理此虚拟机的任何内部状态并返回到 VM。

H_SVM_PAGE_IN

将页面的内容从普通内存移动到安全内存。

语法
uint64_t hypercall(const uint64_t H_SVM_PAGE_IN,
        uint64_t guest_pa,      /* guest-physical-address */
        uint64_t flags,         /* flags */
        uint64_t order)         /* page size order */
返回值

以下值之一

  • 成功时返回 H_SUCCESS。

  • 如果 guest_pa 无效,则返回 H_PARAMETER。

  • 如果 flags 无效,则返回 H_P2。

  • 如果页面的 order 无效,则返回 H_P3。

描述

检索指定客户物理地址的虚拟机拥有的页面内容。

flags 中唯一有效的取值是

  • H_PAGE_IN_SHARED,表示该页面将与 Ultravisor 共享。

  • H_PAGE_IN_NONSHARED,表示 UV 不再对该页面感兴趣。如果页面是共享页面,则适用。

order 参数必须与配置的页面大小相对应。

用例
  1. 当一个普通虚拟机变成安全虚拟机(使用 UV_ESM 超级调用)时,Ultravisor 使用此超级调用将虚拟机的每个页面的内容从普通内存移动到安全内存。

  2. Ultravisor 使用此超级调用来请求 Hypervisor 提供普通内存中的一个页面,该页面可以在 SVM 和 Hypervisor 之间共享。

  3. Ultravisor 使用此超级调用来换入已换出的页面。当 SVM 访问已换出的页面时,可能会发生这种情况。

  4. 如果 SVM 想要禁用与 Hypervisor 的页面共享,它可以通知 Ultravisor 执行此操作。然后,Ultravisor 将使用此超级调用并通知 Hypervisor 它已释放对普通页面的访问权限。

H_SVM_PAGE_OUT

将页面内容移动到普通内存。

语法
uint64_t hypercall(const uint64_t H_SVM_PAGE_OUT,
        uint64_t guest_pa,      /* guest-physical-address */
        uint64_t flags,         /* flags (currently none) */
        uint64_t order)         /* page size order */
返回值

以下值之一

  • 成功时返回 H_SUCCESS。

  • 如果 guest_pa 无效,则返回 H_PARAMETER。

  • 如果 flags 无效,则返回 H_P2。

  • 如果 order 无效,则返回 H_P3。

描述

guest_pa 标识的页面的内容移动到普通内存。

当前 flags 未使用,必须设置为 0。order 参数必须与配置的页面大小相对应。

用例
  1. 如果 Ultravisor 运行的安全页面不足,它可以使用此超级调用将一些安全页面的内容移动到普通页面。内容将被加密。

参考