微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

是否有任何 CPU 状态位指示在 x86 和 x86-64 中的异常/中断处理程序?

如何解决是否有任何 CPU 状态位指示在 x86 和 x86-64 中的异常/中断处理程序?

是否有任何 cpu-state 位表示在 x86x86-64 中的异常/中断处理程序?换句话说,我们能否仅根据 cpu 寄存器的状态来判断当前是否执行了主线程或异常处理程序?

解决方法

不是,CPU 本身(例如控制寄存器)中没有表示“我们处于异常或中断处理程序中”的位。

但是有隐藏状态表明您处于 NMI(不可屏蔽中断)处理程序中。由于您无法通过禁用中断来阻止它们,并且不可阻止的 NMI 任意嵌套会很不方便,因此在您运行 iret 之前不会传递另一个 NMI。即使在 NMI 处理程序期间发生异常(如 #DE div by 0),并且即使您没有完成对 NMI 的处理,该异常处理程序本身也会返回 iret。请参阅 LWN 上的 The x86 NMI iret problem

对于普通中断,如果您不希望在处理此中断时传递另一个中断,则可以禁用中断 (cli)。

但是,当您处理完外部中断时,可能需要通知中断控制器(逻辑上在 CPU 内核之外,但实际上是现代 CPU 的一部分)。 (不是软件中断或异常)。 https://wiki.osdev.org/IDT_problems#I_can_only_receive_one_IRQ 显示了保持旧 PIC 满意所需的 outb 指令。 (我不知道这是否适用于更现代的中断方式,例如 MSI-X 消息信号中断。 OSdev wiki 页面的那部分可能特定于玩具操作系统,这些操作系统让 BIOS 模拟传统 IBM-PC 的东西。)但无论哪种方式,这都仅适用于外部中断,如 PS/2 键盘控制器、硬盘驱动器DMA 完成,或其他(非例外),所以它与您的 Are Linux system calls executed inside an exception handler? 问题无关。


缺少异常状态意味着在从中断处理程序调用 schedule() 之前,您无需运行特殊指令来“确认”异常。您所要做的就是确保在应该或不应该启用中断时启用或不启用。 (sti / clipushf / popf 保存/恢复旧的中断状态。)当然,您的软件数据结构保持一致并适合您正在做。但是,您无需专门执行任何操作即可让 CPU 满意。

它不像在用户空间中,信号处理程序应该告诉操作系统它已经完成,而不仅仅是跳到某个地方并无限期地运行。 (在 Linux 中,信号处理程序可以修改主线程程序计数器,因此 sigreturn(2) 在交付时所在位置以外的其他地方恢复执行。)如果 POSIX 或 Linux 信号是(心理)模型你想知道中断/异常,不,不是那样的。


有一个中断优先级机制(x86-64 中的 CR8,或 LAPIC TPR(任务优先级寄存器)),但它不会在 CPU 传送中断时自动设置。您可以设置一次(例如,如果您有很多高优先级中断要在此内核上处理),并且它会在中断之间持续存在。 (How is CR8 register used to prioritize interrupts in an x86-64 CPU?)。

这只是一个过滤器,用于过滤启用中断时可以将哪些中断编号传送到此内核(sti,RFLAGS 中的 IF=1 位)。显然 Windows 使用了它,or did back in 2007,但 Linux 没有(或没有)。

您不必告诉 CPU / LAPIC 您已完成此中断,因此它可以提供另一个此优先级或更低优先级的中断。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。