分区间通信

虚拟机监控程序为一个分区提供两种简单机制来与另一个分区通信:消息和事件。 在这两种情况下,使用 SynIC (综合中断控制器) 发出通知。

SynIC 消息

虚拟机监控程序提供简单的分区间通信设施,允许一个分区将参数化消息发送到另一个分区。 (由于消息是异步发送的,因此据说会发布消息。) 目标分区可能会通过中断通知此消息的到达情况。 可以使用 HvCallPostMessage hypercall 或由虚拟机监控程序隐式发送消息。

消息

发送消息时,虚拟机监控程序会选择一个免费的消息缓冲区。 可用消息缓冲区集取决于触发发送消息的事件。

虚拟机监控程序将消息缓冲区标记为"正在使用",并使用消息类型、有效负载大小和有关发送方的信息填充消息标头。 最后,它会填充消息有效负载。 有效负载的内容取决于触发消息的事件。

然后,虚拟机监控程序将消息缓冲区追加到接收消息队列。 接收消息队列取决于触发发送消息的事件。 对于所有消息类型,SINTx 在截获消息) 时为隐式 (,在计时器消息) 的情况下显式 (,或者在来宾消息) 的情况下由端口 ID (指定。 当消息排队时,虚拟机监控程序会显式指定或选择目标虚拟处理器。 禁用 SynIC 或 SIM 页的虚拟处理器不会被视为潜在目标。 如果没有可用的目标,虚拟机监控程序将终止操作,并向调用方返回错误。

然后,虚拟机监控程序确定目标虚拟处理器 的 SIM 页 中的指定 SINTx 消息槽是否为空。 如果消息槽中的消息类型等于 HvMessageTypeNone (,即零) ,则假定消息槽为空。 在这种情况下,虚拟机监控程序会取消消息缓冲区的排队,并将其内容复制到 SIM 页中的消息槽。 虚拟机监控程序只能复制与消息关联的有效负载字节数。 虚拟机监控程序还尝试为指定的 SINTx 生成边缘触发的中断。 如果 APIC 已禁用软件或 SINTx 被屏蔽,则中断将丢失。 此中断的到达通知来宾新消息已到达。 如果禁用 SIM 页或 SIM 页中的消息槽不为空,则消息将保持排队状态,并且不会生成中断。

与任何固定优先级中断一样,在 PPR (进程优先级寄存器) 小于 SINTx 寄存器中指定的矢量,并且虚拟处理器 (rFLAGS[IF] 未屏蔽中断,中断不会被虚拟处理器屏蔽 (rFLAGS[IF] 设置为 1) 。

可将具有相同 SINTx 的多个消息缓冲区排队到虚拟处理器。 在这种情况下,虚拟机监控程序将传递第一条消息 (,即将其写入 SIM 页) ,并将其他人排入队列,直到发生三个事件之一:

  • 另一个消息缓冲区已排队。
  • 来宾通过写入 APIC 的 EOI 寄存器来指示"中断结束"。
  • 来宾通过写入 SynIC 的 EOM 寄存器来指示"消息结束"。

在所有三种情况下,虚拟机监控程序将扫描一个或多个消息缓冲区队列,并尝试传递其他消息。 虚拟机监控程序还尝试生成边缘触发的中断,指示新消息已到达。

SIM 页

SIM 页包含一个由 256 字节消息组成的 16 元素数组, (查看 HV_MESSAGE 数据结构) 。 每个数组元素 (也称为消息槽) 对应于单个综合中断源 (SINTx) 。 如果槽中的消息类型等于 HvMessageTypeNone,则消息槽表示为"空"。

SIM 页的地址在 SIMP 寄存器中指定。 SIM 页的地址对于每个虚拟处理器应是唯一的。 将这些页面编程以重叠 SIEF 或 SIM 页的其他实例或任何其他覆盖页 (例如,超标页) 将导致未定义的行为。

虚拟处理器对 SIM 页的读取和写入访问权限的行为类似于对 RAM 的读取和写入访问。 但是,虚拟机监控程序的 SynIC 实现还会写入页面以响应某些事件。

创建和重置虚拟处理器后,SIM 页将清除为零。

SynIC 消息传递机制旨在适应目标分区内消息的有效传递和接收。 建议在目标分区中) 消息处理 ISR (中断服务例程执行以下步骤:

  • 检查已存入 SIM 消息槽的消息。
  • 将消息的内容复制到另一个位置,并将消息槽中的消息类型设置为 HvMessageTypeNone。
  • 通过写入 APIC 的 EOI 寄存器来指示向量中断结束。
  • 执行消息暗示的任何操作。

消息源

可以触发消息发送的事件类如下所示:

  • 拦截:虚拟处理器中的任何拦截都会导致将消息发送到父分区或更高的 VTL。
  • 计时器:计时器机制将导致发送消息。 与每个虚拟处理器关联的是四个专用计时器消息缓冲区,每个计时器对应一个。 接收消息队列属于触发发送消息的虚拟处理器的 SINTx。
  • 来宾消息:虚拟机监控程序支持将消息作为来宾之间的分区间通信机制传递。 本节中定义的接口允许一个来宾将消息发送到另一个来宾。 用于此类消息的消息缓冲区取自接收方来宾消息缓冲区的每端口池。

消息缓冲区

消息缓冲区在内部用于虚拟机监控程序存储消息,直到消息传递到收件人为止。 虚拟机监控程序维护多个消息缓冲区集。

来宾消息缓冲区

虚拟机监控程序为每个端口维护一组来宾消息缓冲区。 这些缓冲区用于来宾显式从一个分区发送到另一个分区的消息。 创建端口后,虚拟机监控程序将从端口所有者的内存池分配 16 (16) 消息缓冲区。 删除端口时,这些消息缓冲区将返回到内存池。

消息缓冲区队列

对于分区中的每个分区和每个虚拟处理器,虚拟机监控程序会为每个 SINTx 维护一个消息缓冲区队列, (虚拟处理器 SynIC 中的综合中断源) 。 创建或重置虚拟处理器时,虚拟处理器的所有消息队列均为空。

来宾消息缓冲区的可靠性与序列化

来宾成功发布的消息已排队供虚拟机监控程序传送。 目标分区的实际传递和接收取决于其正确操作。 分区可以通过禁用其 SynIC 或禁用 SIMP 来禁用向特定虚拟处理器传递消息。

中断连接不会影响排队) 消息的未传递 (。 删除目标端口将始终释放所有端口的消息缓冲区,无论是可用还是包含未传递 (排队) 消息。

消息按成功发布的顺序到达。 如果接收端口与特定的虚拟处理器相关联,消息将按发布时的顺序到达。 如果接收端口与HV_ANY_VP相关联,则无法保证消息按任何特定顺序到达。

SynIC 事件标志

除了消息,SynIC 还支持第二种类型的跨分区通知机制,称为事件标志。 可以使用 HvCallSignalEvent hypercall 或由虚拟机监控程序隐式设置事件标志。

事件标志与消息

事件标志比消息更轻,因此开销较低。 此外,事件标志不需要虚拟机监控程序中的任何缓冲区分配或排队,因此由于资源不足,HvCallSignalEvent 永远不会失败。

事件标志传递

当分区调用 HvCallSignalEvent 时,它指定事件标志号。 虚拟机监控程序通过在接收虚拟处理器的 SIEF 页中以原子方式设置位来响应。 禁用 SynIC 或 SIEF 页的虚拟处理器不会被视为潜在目标。 如果没有可用的目标,虚拟机监控程序将终止操作,并向调用方返回错误。

如果以前清除了事件标志,虚拟机监控程序会尝试通过生成边缘触发的中断来通知接收分区,即现在设置该标志。 目标虚拟处理器以及目标 SINTx 指定为端口创建过程中的一部分。 如果掩码了 SINTx,则 HvSignalEvent 返回HV_STATUS_INVALID_SYNIC_STATE。

与任何固定优先级外部中断一样,在进程优先级寄存器 (PPR) 小于 SINTx 寄存器中指定的矢量,并且虚拟处理器 (rFLAGS[IF] 不会屏蔽中断,中断不会被虚拟处理器 (rFLAGS[IF) ] 屏蔽。

SIEF 页

SIEF 页由包含 256 字节事件标志的 16 元素数组组成, (查看 HV_SYNIC_EVENT_FLAGS) 。 每个数组元素对应于单个综合中断源 (SINTx) 。

SIEF 页的地址在 SIEF 寄存器中指定。 SIEF 页的地址对于每个虚拟处理器应是唯一的。 将这些页面编程以重叠 SIEF 或 SIM 页的其他实例或任何其他覆盖页 (例如,超标页) 将导致未定义的行为。

虚拟处理器对 SIEF 页的读取和写入访问权限的行为类似于对 RAM 的读取和写入访问。 但是,虚拟机监控程序的 SynIC 实现还会写入页面以响应某些事件。

创建和重置虚拟处理器后,SIEF 页将清除为零。

建议将事件标志中断服务例程 (目标分区中的 ISR) 执行以下步骤:

  • 检查事件标志并确定设置了哪些标志(如果有)。
  • 使用锁定的 (原子) 操作(如 LOCK AND 或 LOCK CMPXCHG)清除一个或多个事件标志。
  • 通过写入 APIC 的 EOI 寄存器来指示向量中断结束。
  • 执行设置的事件标志暗示的任何操作。

端口和连接

从一个来宾发送到另一个来宾的消息或事件必须通过预先分配的连接发送。 反过来,连接必须与目标端口相关联。

端口从接收器的内存池中分配,并指定要面向的虚拟处理器和 SINTx。 事件端口具有"基本标志号"和"标志计数",允许调用方指定该端口的有效事件标志范围。

从发送方的内存池分配连接。 创建连接时,它必须与有效的端口相关联。 此绑定创建简单的单向通信通道。 如果随后删除了端口,则其连接将变为无用状态。

SynIC MSR

除了为本地 APIC 定义的内存映射寄存器外,SynIC 中还定义了以下特定于模型的寄存器 (MSR) 。 每个虚拟处理器都有其自己的这些寄存器副本,因此可以独立编程它们。

MSR 地址 注册名称 函数
0x40000080 SCONTROL SynIC 控件
0x40000081 SVERSION SynIC 版本
0x40000082 SIEFP "中断事件标志"页
0x40000083 SIMP 中断消息页
0x40000084 EOM 消息结束
0x40000090 SINT0 中断源 0 (虚拟机监控程序)
0x40000090 SINT1 中断源 1
0x40000090 SINT2 中断源 2
0x40000090 SINT3 中断源 3
0x40000090 SINT4 中断源 4
0x40000090 SINT5 中断源 5
0x40000090 SINT6 中断源 6
0x40000090 SINT7 中断源 7
0x40000090 SINT8 中断源 8
0x40000090 SINT9 中断源 9
0x40000090 SINT10 中断源 10
0x40000090 SINT11 中断源 11
0x40000090 SINT12 中断源 12
0x40000090 SINT13 中断源 13
0x40000090 SINT14 中断源 14
0x40000090 SINT15 中断源 15

SCONTROL 寄存器

此寄存器用于控制虚拟处理器的 SynIC 行为。

在虚拟处理器创建时间和处理器重置后,此 SCONTROL (SynIC 控制寄存器的值) 0x0000000000000000。 因此,将禁用消息队列和事件标志通知。

Bits 字段 说明 属性
63:1 RsvdP 必须保留值 读/写
0 启用 设置后,此虚拟处理器将允许消息队列和事件标志通知发布到其 SynIC。 清除时,无法将消息队列和事件标志通知定向到此虚拟处理器。 读/写

SVERSION 寄存器

这是只读寄存器,它返回 SynIC 的版本号。 尝试写入此寄存器会导致#GP错误。

Bits 字段 说明 属性
63:32 RsvdP 读取
31:0 SynIC 版本 SynIc 的版本号 读取

SIEFP 寄存器

在虚拟处理器创建时间和处理器重置时,此 SIEFP (综合中断事件标志页) 寄存器的值0x0000000000000000。 因此,默认情况下禁用 SIEFP。 来宾必须通过设置位 0 来启用它。 如果指定的基址超出分区的 GPA 空间的末尾,则来宾无法访问 SIEFP 页。 修改寄存器时,来宾应保留保留位的值, (1 到 11) ,以便将来兼容。

Bits 字段 说明 属性
63:12 基址 SIEFP) GPA 空间中的基址 ( (假定为禁用的低 12 位) 读/写
11:1 RsvdP 保留值应保留 读/写
0 启用 启用 SIEFP 读/写

SIMP 寄存器

在虚拟处理器创建时间和处理器重置时,此 SIMP (综合中断消息页的值) 寄存器0x0000000000000000。 因此,默认情况下禁用 SIMP。 来宾必须通过设置位 0 来启用它。 如果指定的基址超出了分区的 GPA 空间的末尾,则来宾无法访问 SIMP 页。 修改寄存器时,来宾应保留保留位的值, (1 到 11) ,以便将来兼容。

Bits 字段 说明 属性
63:12 基址 假定) 禁用 SIMP (低 12 位的 GPA) 空间 (基址 ( 读/写
11:1 RsvdP 保留值应保留 读/写
0 启用 启用 SIMP 读/写

SINTx 寄存器

在虚拟处理器创建时,所有 SINTx (综合中断源) 寄存器的默认值0x0000000000010000。 因此,默认情况下会屏蔽所有合成中断源。 来宾必须通过编程适当的向量和清除位 16 来取消屏蔽它们。

设置轮询位将产生取消屏蔽中断源的效果,但未生成实际中断。

AutoEOI 标志指示当中断传递到虚拟处理器时,虚拟机监控程序应执行隐式 EOI。 此外,虚拟机监控程序将自动清除虚拟 APIC (ISR) "服务内寄存器"中的相应标志。 如果来宾启用此行为,则它不得在其中断服务例程中执行 EOI。 可以随时打开 AutoEOI 标志,尽管来宾必须在正在进行的中断上执行显式 EOI。计时考虑使得很难知道特定中断是否需要 EOI,因此建议在 SINT 取消屏蔽后,不会更改其设置。 同样,可以随时关闭 AutoEOI 标志,但对外部中断的相同担忧也适用

矢量的有效值为 16-255(含 16-255)。 指定无效矢量编号会导致#GP。

Bits 字段 说明 属性
63:19 RsvdP 保留值应保留 读/写
18 轮询 启用轮询模式 读/写
17 AutoEOI 设置在中断传递时是否应执行隐式 EOI 读/写
16 已屏蔽 如果掩码了 SINT,则设置 读/写
15:8 RsvdP 保留值应保留 读/写
7:0 向量 中断向量 读/写

EOM 寄存器

来宾将消息写入消息 (EOM) 注册,导致虚拟机监控程序扫描与虚拟处理器关联的内部消息缓冲区队列 () 。 如果消息缓冲区队列包含排队的消息缓冲区,虚拟机监控程序会尝试传递消息。 如果启用了 SIM 页并且与 SINTx 对应的消息槽为空 (,则消息传递成功,即标头中的消息类型设置为 HvMessageTypeNone) 。 如果成功传递消息,则其相应的内部消息缓冲区将被取消排队并标记为免费。 如果未屏蔽相应的 SINTx,则会 (传递边缘触发的中断,即将设置 IRR 中的相应位) 。

来宾可以使用此注册来"轮询"消息。 它还可用作为已禁用 ((即屏蔽) )的 SINTx 清空消息队列的方法。

如果消息队列全部为空,则对 EOM 寄存器的写入是无操作。

从 EOM 寄存器读取始终返回零。

Bits 字段 说明 属性
63:0 RsvdZ 仅写触发器 写入