虚拟处理器

每个分区可能具有零个或多个虚拟处理器。

虚拟处理器索引

虚拟处理器由由其分区 ID 和处理器索引组成的元组标识。 在创建虚拟处理器时,处理器索引将分配给虚拟处理器,并且该索引在虚拟处理器的生存期内保持不变。

在某些情况下,可以使用特殊值HV_ANY_VP来指定“任何虚拟处理器”。 值 HV_VP_INDEX_SELF 可用于指定自己的 VP 索引。

typedef UINT32 HV_VP_INDEX;

#define HV_ANY_VP ((HV_VP_INDEX)-1)

#define HV_VP_INDEX_SELF ((HV_VP_INDEX)-2)

来宾可以通过虚拟机监控程序定义的 MSR (特定于模型的寄存器) HV_X64_MSR_VP_INDEX检索虚拟处理器的 ID。

#define HV_X64_MSR_VP_INDEX 0x40000002

虚拟处理器空闲睡眠状态

虚拟处理器可以置于虚拟空闲处理器电源状态或处理器睡眠状态。 这种增强的虚拟空闲状态允许处于低功耗空闲状态的虚拟处理器在中断的到来时被唤醒,即使中断在虚拟处理器上屏蔽也是如此。 换句话说,虚拟空闲状态允许来宾分区中的操作系统利用 OS 中的处理器节能技术,否则在来宾分区中运行时将不可用。

具有 AccessGuestIdleMsr 特权的分区可以通过读取虚拟机监控程序定义的 MSR HV_X64_MSR_GUEST_IDLE来触发进入虚拟处理器空闲睡眠状态。 无论是否在虚拟处理器上启用了中断,都会在中断到来时唤醒虚拟处理器。

“虚拟处理器助手”页

虚拟机监控程序为每个虚拟处理器提供一个页面,该页面叠加在来宾 GPA 空间上。 此页面可用于来宾 VP 与虚拟机监控程序之间的双向通信。 来宾 OS 对此虚拟 VP 助手页具有读/写访问权限。

来宾通过向 Virtual VP Assist MSR (0x40000073) 写入来指定覆盖页 (在 GPA 空间) 中的位置。 虚拟 VP 助手页面 MSR 的格式如下:

Bits 字段 说明
0 启用 启用 VP 助手页面
11:1 RsvdP 预留
63:12 页 PFN 虚拟 VP 助手页 PFN

虚拟处理器运行时寄存器

虚拟机监控程序的计划程序在内部跟踪每个虚拟处理器在执行代码时消耗的时间。 跟踪的时间是虚拟处理器使用正在运行的来宾代码的时间,以及关联的逻辑处理器代表该来宾运行虚拟机监控程序代码所花费的时间的组合。 可通过 64 位只读HV_X64_MSR_VP_RUNTIME虚拟机监控程序 MSR 访问此累积时间。 时间量以 100ns 为单位度量。

非特权指令执行防护 (NPIEP)

非特权指令执行 (NPIEP) 是一项功能,可限制用户模式代码使用某些指令。 具体而言,启用此功能后,可能会阻止 SIDT、SGDT、SLDT 和 STR 指令的执行。 执行这些指令会导致#GP错误。

必须使用 HV_X64_MSR_NPIEP_CONFIG_CONTENTS 按 VP 配置此功能。

来宾旋转锁

支持多处理器的典型操作系统使用锁来强制实施某些操作的原子性。 在虚拟机监控程序控制的虚拟机中运行此类操作系统时,这些受锁保护的关键部分可以通过关键节代码生成的拦截进行扩展。 关键节代码也可能被虚拟机监控程序计划程序抢占。 尽管虚拟机监控程序尝试阻止此类抢占,但可能发生此类抢占。 因此,其他锁竞争者可能最终旋转,直到锁持有人再次重新计划,从而显著延长旋转锁获取时间。

虚拟机监控程序向来宾 OS 指示在向虚拟机监控程序指示过度旋转情况之前,应尝试获取旋转锁的次数。 此计数在 CPUID 叶0x40000004中返回。 值为 0 表示来宾 OS 不应通知虚拟机监控程序有关获取长旋转锁的信息。

HvCallNotifyLongSpinWait hypercall 为开明的来宾提供了一个接口,以改进多处理器虚拟机锁的统计公平属性。 来宾应针对 CPUID 叶0x40000004返回的建议计数的倍数发出此通知。 通过此超级呼叫,来宾会通知虚拟机监控程序长时间的旋转锁获取。 这允许虚拟机监控程序做出更好的计划决策。