CR8 寄存器如何用于 x86-64 CPU 中的中断优先级?

How is CR8 register used to prioritize interrupts in an x86-64 CPU?

我正在阅读有关控制寄存器的 Intel 文档,但我很难理解如何使用 CR8 寄存器。引用文档 (2-18 Vol. 3A):

Task Priority Level (bit 3:0 of CR8) — This sets the threshold value corresponding to the highest- priority interrupt to be blocked. A value of 0 means all interrupts are enabled. This field is available in 64- bit mode. A value of 15 means all interrupts will be disabled.

我有 3 个简单的问题,如果你不介意的话:

  1. 因此 CR8 的第 3 位到第 0 位构成了这 16 个优先级值。但是优先什么? A 运行 "thread",我想,对吗?

  2. 但是与收到中断以查看是否必须阻止时相比,CR8 中的优先级值是多少?

  3. 中断被阻塞是什么意思?它是 "delayed" 直到以后,还是只是被丢弃,即丢失?

CR8 表示CPU的当前优先级。当中断挂起时,中断向量编号的位 7:4 将与 CR8 进行比较。如果矢量更大,则为其提供服务,否则它将保持挂起状态,直到将 CR8 设置为较低的值。

假设正在使用 APIC,它有一个 IRR(中断请求寄存器),每个中断向量号有一位。当该位被设置时,中断挂起。它可以永远保持这种状态。

当中断到达时,它被或运算到 IRR 中。如果中断已挂起(即该向量的 IRR 位已设置),则新中断将与前一个中断合并。 (你可以说它被丢弃了,但我不这么认为;相反,我说两者合而为一。)由于这种合并,中断服务例程必须设计为处理所有就绪的工作,而不是期望每个工作单元都有一个明显的中断。

另一个相关点是 Windows(我假设 Linux)试图始终保持 CPU 的 IRQ 级别尽可能低。中断服务例程在其提升的硬件中断级别上做尽可能少的工作,然后提示延迟过程调用以在 DPC IRQ 级别上完成其余工作。 DPC 通常会立即得到服务,除非另一个 IRQ 到达,因为它们的优先级高于正常进程。

一旦 CPU 开始执行 DPC,它将在其每个 CPU DPC 提示中执行所有 DPC,然后将 CPU IRQL 返回零以允许正常线程恢复.

这样做的好处是任何优先级的传入硬件 IRQ 都可以中断 DPC 并几乎立即在提示上获得它自己的 DPC,因此它永远不会被遗漏。

我也应该尝试解释(我认为是)CPU 的 IRQ 级别和 IRQ 的优先级之间的区别。

在控制寄存器 8 可用于 x64 之前,CPU 没有 IRQ 级别的概念。

windows NT 的设计者决定系统中的每个逻辑处理器都应该有一个 NOTIONAL IRQ 级别,该级别将存储在称为每个 CPU 的处理器控制块的数据结构中。他们决定应该有 32 个级别,我不知道什么原因。

软件和硬件中断也分配了一个级别,因此如果它们高于 CPU 分配的级别,则允许它们继续。

Windows 不使用 PIC/APIC 硬件分配的中断优先级,而是使用其中的中断屏蔽位。各种引脚被分配一个向量编号,然后它们得到一个电平。

当Windows 提高其PCB 中CPU 的LRQL 时,它还会重新编程PIC/APIC 的中断掩码。但不是马上。

发生的每个中断都会导致 Windows 陷阱调度程序执行并将 IRQ 级别与 CPU IRQL 进行比较,如果 IRQ 级别更高,则中断继续,否则 Windows 将掩码和 returns 重新编程到执行线程。

原因是重新编程 PIC 需要时间,如果没有较低级别的 IRQ 进来,那么 windows 可以节省自己的工作。

在 x64 上有 CR8,我仍在研究它是如何工作的。