陷阱指令:为什么必须自动更改程序计数器和处理器状态寄存器?

Trap instruction: why must the program counter and processor status register be changed atomically?

我在之前的操作系统考试中遇到了以下问题 class。

考虑一个体系结构,其中 TRAP 指令有两个作用:加载处理器状态寄存器 (PCR) 的预定义值,其中包含 user/kernel 模式位,保存程序计数器的值 ( PC) 到一个特殊的 Save PC 寄存器并将预定义的值加载到 PC 中。解释为什么在同一指令周期中不更改 PC 的情况下为 PCR 加载新值是不安全的。

我知道 PCR 将设置为内核模式并关闭内存管理。是不是因为PC还在用户程序里不安全?如果是这样,它会在哪里出错?如果不是,为什么不安全?为什么先换电脑也不安全?

旁白:没有理由假设 "memory management" 通过加载新的处理器状态变为 "off";事实上,根据我的经验,在 CPU 年代不会发生这种情况。但这与这个答案无关。

我们正在用户模式下执行,并获取了一条 TRAP 指令。然后程序计数器(比方说)指向 TRAP 之后的指令。

现在处理器执行TRAP。它加载新的处理器状态,将 CPU 切换到内核模式。假设这本身不会抑制设备中断。

现在...设备中断。硬件或软件机制保存处理器状态(=内核态)和程序计数器(=TRAP后指令的用户态地址)。设备中断服务例程执行其任务并从中断执行 return 以恢复程序计数器和处理器状态。我们无法恢复 "half-way through the TRAP instruction" - 唯一可能发生的事情是我们开始执行 PC 指向的指令,即我们在 TRAP 之后但在内核模式下执行指令。

具体问题取决于系统架构:

如果内核地址映射是用户地址映射的超集(通常在用户 space 是总地址 space 的一半的操作系统上),那么我们正在执行用户提供的代码内核模式,这至少是一个严重的权限问题,并且在我们无法处理时可能会导致页面错误导致我们失败。

如果内核地址映射不包括用户space(在虚拟地址大小有限的系统上经常出现这种情况)那么这相当于疯狂跳转到内核。

总结就是处理器状态和程序计数器都需要定义"where you are in execution",而且两者要一起saved/updated;或者换句话说,中间不允许控制权的改变(例如中断)。