使用 x86 VIF 和 VIP 标志?

Use of x86 VIF and VIP flags?

我通读了英特尔软件开发人员手册第 3 卷第 20 节,其中解释了虚拟 8086 模式的工作原理,包括 VIF 和 VIP 标志的使用。但是,我对一些事情仍然感到困惑。

VIF 标志用作 IF 标志的代理项,因此 8086 仿真器(可能是某些用户 space 程序)可以接收可屏蔽的硬件中断,即使实模式程序是模拟不想。

  1. 为什么模拟器要这样做?

VIP 用作space 来标记何时收到中断。根据手册,如果处理器接收到可屏蔽中断,但被仿真的程序不想接收它们(因此 VIF 标志将被清除),仿真器应设置 VIP 标志,等待仿真程序设置IF标志,然后处理中断。

  1. 为什么我们要等待处理中断而不是立即处理呢?实模式 8086 上的中断是否被推迟而不是被忽略?

  2. 附加问题——当 VIP 被设置并且程序启用中断(通过 STI 等)时处理器生成#GP 但是当 VIP 标志被设置为多个时可能会生成#GP方式——例如通过无效的内存访问。手册没有提到检查#GP 的原因是什么,那么无论是否设置了 IF,程序都应该处理挂起的中断吗?

编辑:好的,所以我看到了我的部分困惑——它是需要保持 IF 设置的 kernel。在那种情况下,我宁愿问#2——为什么我们要等待处理中断 而不是完全忽略它?

  1. 第 20.3.2 节介绍了这样做的原因:"Existing 8086 programs commonly set and clear the IF flag in the EFLAGS register to enable and disable maskable hardware interrupts."当 运行 在现代 OS 下虚拟 8086 模式下的此类应用程序时, OS 不允许 8086 程序禁用系统中的中断。因此 IF 标志需要保持在 OS 的控制之下,并且它必须代表 virtual-8086 程序进行虚拟化。使用 VIF 和 VIP 标志 "eliminat[es] the need for all IF related operations (such as PUSHF, POPF, CLI, and STI instructions) to trap to the virtual-8086 monitor."

  2. virtual-8086模式的程序已经执行过CLI清除IF(具有清除VIF的作用),无法下发中断

  3. 这是个好问题。在我看来,处理器应该在生成#GP 之前设置 VIF;然后 virtual-8086 监视器中的 GP 处理程序可以很容易地看到 VIP 和 VIF 都已设置。这是当 VIF 由 POPF 或 IRET 设置时所描述的行为;我不知道为什么 STI 表现不同。

由于问题 1 已经回答,让我们 稍微处理一下 2 和 3。

Are interrupts on a real-mode 8086 deferred rather than ignored?

重要的是要注意 执行模式(真实或受保护) 与它没有太大关系。 CLI 确实 忽略 中断, 它不会延迟任何事情。但是 中断处理非常复杂, 并且,在大多数配置中, 中断设备and/or 中断控制器将确保 CPU 的 INT 引脚保持活动状态 直到你做了 STI 并维修了 打断。 因此,通过过度简化, 你可以说 CLI 推迟了 打断。但你不会找到这样的 CPU 手册中的声明,因为 它是用外部逻辑完成的, 并取决于许多可配置的东西。

But a #GP could be generated while the VIP flag is set in multiple ways—e.g. through an invalid memory access.

在v86模式下有很多 GPF 源代码,例如端口 IO 指令, 当 IOPL 小于 3 时,唯一可靠的 区分它们的方法是查找 错误的操作码,并模拟它。这是不可能的 例如,设置 VIF 并仅提高 GPF 在那之后,因为例外应该不留下 错误指令的可观察影响, 允许软件干净地模拟它。