在 x86 Intel VT-X 非根模式下,是否可以在每个指令边界传递中断?
In x86 Intel VT-X non-root mode, can an interrupt be delivered at every instruction boundary?
除了中断未传送到虚拟处理器的某些正常指定条件(cli、if=0 等)外,来宾中的所有指令实际上都是可中断的吗?
也就是说,当一个传入的硬件中断被提供给 LAPIC,然后再提供给处理器时,据说一些内部魔法恰好将其转换为虚拟中断给来宾(使用虚拟 APIC,没有退出)。当发生这种情况时,当前正在执行的指令是否立即序列化 OOO 流并像典型的中断传递一样跳转到向量,或者 VT-x 的虚拟中断传递是否会导致发生其他类型的解析?
上下文是使用模拟器对竞争条件和同步原语进行压力测试通常非常有价值。人们希望您的模拟器能够在任何指令处接收中断,以触发 "interesting behavior".
这引出了一个问题,VT-x 虚拟化是否提供相同的指令级中断粒度,以便 "interesting behavior" 会像纯指令模拟器一样被触发?
英特尔 SDM 确实注意到虚拟中断是在指令边界上传递的,但是对于 所有 在芯片上通常有效的边界是否 always 仍在 VT-x 模式下检查中断。
我看不出有任何理由让客人在里面会很特别。当外部中断到达时会发生什么。 (假设我们正在谈论访客代码 运行 在管道上本地运行,而不是根模拟 and/or 决定延迟重新进入访客以预期另一个中断。见评论。)
它们不会有效地阻止多条指令的中断;那会损害中断延迟。由于没有特殊的 "sync points" 中断只能在那里传递,因此管道需要能够处理任意指令之间的中断。无序执行总是可能有很多事情要做,所以你不能指望在处理中断之前等待任何特定的状态;那可能需要很长时间。如果一对指令之间的间隙可以传递中断,为什么其他指令不行?
CPUs 不重命名权限级别,所以是的,他们会回滚到退休状态,丢弃后端的所有正在运行的指令,然后找出要做什么基于当前状态。另见 When an interrupt occurs, what happens to instructions in the pipeline?
这个完全未经检验的猜测是基于我对 CPU 体系结构的理解。如果对中断延迟有可衡量的影响,那可能是真的。
实际上,不管 VT-X 是什么,除非单步执行,否则某些指令边界可能无法中断。
退休带宽为每个时钟 3 个 (Nehalem),每个逻辑线程每个时钟 4 个 (Haswell),在 Skylake 中甚至更高。从乱序核心退出通常是突发的,因为它是按顺序发生的(以支持精确的异常),这就是为什么我们有一个与保留站分开的 ROB。
一条指令在一段时间内阻止后面的独立指令退出,然后与该指令一起退出是很常见的。例如缓存未命中加载,或者在一些独立指令之前的长 dep 链的末尾。
因此对于某些函数或代码块,很可能每次它们 运行,例如 xor
归零指令总是在与之前的指令相同的周期中退出。这意味着 CPU 永远不会处于异或归零指令是最旧的非退休指令的状态,因此它与之前的 insn 之间的间隙永远不会成为中断出现的地方。
如果您有 2 条彼此紧跟的指令,例如一个在 CPU returns 到 user-space 之后的一个周期中从较早的指令进入,您最终可能会在 64 字节 I-cache 边界处产生前端效应,从而扰乱通常的nop
或 xor
等廉价独立指令的模式 - 归零总是在与较早的更高延迟指令相同的周期中退出,但可能仍然存在不可干扰的情况,其中 fetch 和 5-wide解码,并且 4-wide issue/rename 将可靠地将指令一起送入管道,而没有机会让慢速指令在快指令准备好退出后先于快指令完成。
正如我所说,这不是 VT-x 特有的。
除了中断未传送到虚拟处理器的某些正常指定条件(cli、if=0 等)外,来宾中的所有指令实际上都是可中断的吗?
也就是说,当一个传入的硬件中断被提供给 LAPIC,然后再提供给处理器时,据说一些内部魔法恰好将其转换为虚拟中断给来宾(使用虚拟 APIC,没有退出)。当发生这种情况时,当前正在执行的指令是否立即序列化 OOO 流并像典型的中断传递一样跳转到向量,或者 VT-x 的虚拟中断传递是否会导致发生其他类型的解析?
上下文是使用模拟器对竞争条件和同步原语进行压力测试通常非常有价值。人们希望您的模拟器能够在任何指令处接收中断,以触发 "interesting behavior".
这引出了一个问题,VT-x 虚拟化是否提供相同的指令级中断粒度,以便 "interesting behavior" 会像纯指令模拟器一样被触发?
英特尔 SDM 确实注意到虚拟中断是在指令边界上传递的,但是对于 所有 在芯片上通常有效的边界是否 always 仍在 VT-x 模式下检查中断。
我看不出有任何理由让客人在里面会很特别。当外部中断到达时会发生什么。 (假设我们正在谈论访客代码 运行 在管道上本地运行,而不是根模拟 and/or 决定延迟重新进入访客以预期另一个中断。见评论。)
它们不会有效地阻止多条指令的中断;那会损害中断延迟。由于没有特殊的 "sync points" 中断只能在那里传递,因此管道需要能够处理任意指令之间的中断。无序执行总是可能有很多事情要做,所以你不能指望在处理中断之前等待任何特定的状态;那可能需要很长时间。如果一对指令之间的间隙可以传递中断,为什么其他指令不行?
CPUs 不重命名权限级别,所以是的,他们会回滚到退休状态,丢弃后端的所有正在运行的指令,然后找出要做什么基于当前状态。另见 When an interrupt occurs, what happens to instructions in the pipeline?
这个完全未经检验的猜测是基于我对 CPU 体系结构的理解。如果对中断延迟有可衡量的影响,那可能是真的。
实际上,不管 VT-X 是什么,除非单步执行,否则某些指令边界可能无法中断。
退休带宽为每个时钟 3 个 (Nehalem),每个逻辑线程每个时钟 4 个 (Haswell),在 Skylake 中甚至更高。从乱序核心退出通常是突发的,因为它是按顺序发生的(以支持精确的异常),这就是为什么我们有一个与保留站分开的 ROB。
一条指令在一段时间内阻止后面的独立指令退出,然后与该指令一起退出是很常见的。例如缓存未命中加载,或者在一些独立指令之前的长 dep 链的末尾。
因此对于某些函数或代码块,很可能每次它们 运行,例如 xor
归零指令总是在与之前的指令相同的周期中退出。这意味着 CPU 永远不会处于异或归零指令是最旧的非退休指令的状态,因此它与之前的 insn 之间的间隙永远不会成为中断出现的地方。
如果您有 2 条彼此紧跟的指令,例如一个在 CPU returns 到 user-space 之后的一个周期中从较早的指令进入,您最终可能会在 64 字节 I-cache 边界处产生前端效应,从而扰乱通常的nop
或 xor
等廉价独立指令的模式 - 归零总是在与较早的更高延迟指令相同的周期中退出,但可能仍然存在不可干扰的情况,其中 fetch 和 5-wide解码,并且 4-wide issue/rename 将可靠地将指令一起送入管道,而没有机会让慢速指令在快指令准备好退出后先于快指令完成。
正如我所说,这不是 VT-x 特有的。