Continue the "Those things" series, the subject of which is Intel's interrupt processing. The references are mainly from Chapters VI, tenth and 29th of the third volume of the Intel document, as well as this article. Part of the content comes from the article mentioned above.
The following five questions focus on the following: First, what is interrupted and what kind. Second, how interrupts are sent to the CPU. The third is how the CPU handles the interrupts received. Four, the priority problem of interruption. Five, what support does the virtualization environment provide for interrupts?
They will be answered in the next step. what the interruption is, what kind it has.
We often mix interruptions (Interrupt) and anomalies (Exception) together to illustrate that they have similarities and different places. The similarity lies in the fact that some events occur in the system, allowing the processor to suspend the current execution stream, thereby pumping energy (into a predetermined path) to handle the events. The difference lies in their origins, and the whole path from the event to the final processing is different. This blog post focuses on interruptions, so don't go into details about the anomalies.
Generally speaking, interrupts are mainly caused by some hardware devices, indicating that these hardware have some important events to notify the processor, such as some of the data requested from the external device is ready, you need to notify the processor to read it and so on. Of course, the so-called "generally speaking" refers to the software can also be used to trigger interrupts, such as the invocation of int n instructions, of course, this way the interruption and the resulting interruption in the end of the process will be a great difference. Thus, from a variety of categories, interrupts can be divided into external interrupts through hardware (External interrupt) and software interrupts (Software interrupt) resulting from software. Whether it's an external interrupt or a software outage, each interrupt has an interrupt number corresponding to it, and for external interrupts, the range of interrupts that can be used is from 16 to 255 (0 to 15) for the system reservation, while for software interrupts, the interrupt number available is 0 to 255. In addition, 16 to 255 interrupts can be disable through the IF flag in EFlags if the IF flag in EFlags is cleared, indicating that the current CPU does not accept interrupts within this range, if it is set to 1, Indicates that the current CPU can handle interrupts in this range normally. how interrupts are sent to the CPU.
Interrupts are first entered into a controller called Advanced Programmable Interrupt Controller (APIC) before entering the CPU, which can be said to have a APIC per CPU, known as the CPU's local APIC (lapic). Each lapic consists of a series of registers that control how the lapic sends interrupts to the processor. Depending on the implementation, these registers are accessed in a different way, for example, for traditional APIC and xapic, these registers are mapped in memory, can be read and written directly through memory access, and for X2apic, These registers need to be accessed by accessing the MSR, with specific addresses and access methods to view the Intel documentation.
The following illustration shows a lapic architecture with a wide variety of registers, most of which can be obtained by querying an Intel document, with several particularly important registers: in-service register (ISR), Interrupt Request Register (IRR), EOI register,task Priority Register (TPR), Processor Priority Register (PPR), Interrupt Command Register (IC R), local Vector Table (LVT). These will be covered in the following pages.
For the current lapic, it may receive interrupts from several sources: locally connected I/O devices: This is primarily a direct connection to the processor via the local interrupt pins (LINT0 and LINT1) o device; APIC Timer generated interrupts:lapic can programmatically set a counter, send interrupts to the processor at a fixed time; performance monitoring counter Interrupts: This means that the performance counter in the processor sends an interrupt to the processor when the overflow event occurs; Thermal Sensor interrupts: This is interrupted by a temperature sensor; APIC Internal Error Interrupts: This is an interruption of lapic internal error triggering; externally connected I/O devices: This means that the external devices are connected through ioapic and lapic; inter-processor Interrupts (IPIs): This refers to the delivery and reception of interrupts between processors through IPI.
Of these, the previous five source of interrupts, known as the local interrupt source (interrupt sources), lapic the corresponding interrupt delivery (delivery) scheme in advance in the native Vector table (LVT) table. When these local interrupt sources are received, the related interrupts are delivered according to the scenarios in LVT.
In addition, for external interrupts sent from Ioapic, and IPI interrupts from other processors, lapic directly hands the interrupt to the local processor for processing. If you need to send IPI to another processor, you can do so by writing the ICR register in Lapic. This part is not detailed here, just look at the document.
So let's take a look at what happens when an external device interrupts and the interrupt is sent to the appropriate CPU.
Inside the ioapic, there is a very important data structure called the Programmable redirect table (programmable redirection table,prt), which contains several redirected table entries in the PRT table (redirection table Entry, RTE), each RTE corresponds to an interrupt pin, for example, a typical ioapic may contain 24 interrupt pins, and the corresponding PTR table has 24 corresponding Rte. Typically, each external device is connected through a specific pin and ioapic, and after the interrupt is generated, it enters the ioapic through the pin, and when a ioapic pin receives the interrupt signal, it formats an interrupt message according to an RTE corresponding to the pin. A lapic that is sent to a (or multiple) processor. The format of the RTE is listed in the following table:
Bits |
Description |
63:56 |
Destination field, Destination field, r/w (readable and writable). Depending on the value of the destination Filed (see below), the value of the field is different, and it has two meanings: physical mode (destination mode is 0 o'clock): Its value is APIC ID, which identifies a unique APIC. Logical Mode (destination mode 1 o'clock): Its value represents a set of CPUs based on different configurations of lapic. |
55:17 |
Reserved, reservation is not available. |
16 |
Interrupt Mask, interrupt screen bit, r/w. At the moment, the corresponding interrupt pins are shielded, and the resulting interrupts are ignored. The interrupt produced by the corresponding PIN is sent to lapic at zero. |
15 |
Trigger mode, triggering pattern, r/w. Indicates how the interruption of the pin is triggered. 1:level, level trigger, 2:edge, edge trigger. |
14 |
Remote IRR, remotely irr,ro (read-only). is only valid for level-triggered interrupts, when the interrupt is triggered by the edge, the value represents undefined. When an interrupt is a level trigger, the LAPIC receives the interrupt, which, when Lapic writes EOI, is zeroed. |
13 |
Interrupt Input Pin Polarity (INTPOL), interrupt pin polarity, r/w. Specifies whether the effective level of the PIN is a high or low level. 0: High level; 1: Low level. |
12 |
Delivery status, delivery state, RO. 0:idel is not currently interrupted; 1:send Pending,ioapic has received the interrupt, but for some reason the interrupt has not been sent to Lapic |
11 |
Destination mode, destination model, r/w. 0:physical mode, see destination field;1:logical mode, ditto. |
10:8 |
Delivery mode, transfer modes, r/w. Used to specify how the interrupt is sent to the destination APIC, and the various modes need to be matched with the corresponding triggering method. See the Intel documentation for details. |
7:0 |
Interrupt vector, interrupt vectors, r/w. Specifies the vector that corresponds to the interrupt, ranging from 10h to Feh. |
As we can see from the table above, the message contains all the information that was interrupted. Where destination field and destination mode define the target processor to which the interrupt will be delivered. There are two possible paths from Ioapic to Lapic, as shown in the following illustration: The first is through the system bus, which is implemented on the processors in the Pentium 4 and Intel Xeon series; the second is through APIC bus, This path is implemented on the processor of the Pentium and P6 family. As for the difference between them, or to see the interpretation of the document.
In short, an interrupt from an external device is eventually delivered through Ioapic to a lapic in one (or more) of the processors. Next, it depends on how the Lapic delivers these interrupts to the processor for processing. How the CPU handles the received interrupts.
Lapic either receives an interrupt from the ioapic, interrupts from the local interrupt source, or a IPI interrupt sent from another processor, it is referred to the CPU, but because the CPU may be handling other interrupts at this time, a mechanism is needed to ensure the security of the interrupt processing.
The first thing to note is that in the RTE format, there may be several types of interrupted delivery mode, in which the interrupts of delivery mode, NMI, SMI, INIT, Extint, and Sipi, will be directly handled by the CPU. If the current CPU is processing these delivery mode interrupts, the same interrupts will be prevented from being delivered. In addition, there is a delivery mode called fixed, which is a normal interrupt, and their delivery mechanism is done through IRR and ISR registers. On the X86 platform, these two are 256bits registers (in fact, consisting of 8 64bits registers), each bit representing an interrupted vector, where the No. 0 to 16th bit is reserve. IRR and ISR each bit represent the following meanings: IRR: If the bit n bit is placed, it represents the interrupt that Lapic has received vector N, but has not yet been processed by the CPU. ISR: If the bit n bit is placed, the CPU has begun processing the interrupt of vector N, but it has not yet completed.
It is to be noted that when the CPU is processing an interrupt, if it is delivered again to an interrupt of the same vector, the corresponding IRR bit is reset again, and if an interrupt is pending in IRR and the same type is delivered again, the corresponding bit in the ISR is set one. This indicates that the same type of interrupt can be counted up to two times in the APIC system.
In addition, when an interrupt is processed, the lapic need to write a EOI register via the software to tell.
Thus, depending on the processor, a typical lapic interrupt processing process is this: for the Pentium4 and Xeon Series: by interrupting the destination field field of the message, determine whether the interrupt was sent to itself; If the interrupt delivery mode is NMI, SMI, INIT, Extint, Sipi, directly to CPU processing, if not for the interrupt enumerated above, the corresponding bit of IRR is placed one; when the interrupt is pending to the IRR register, According to the TPR and PPR registers, determine whether the current highest priority interrupt can be sent to the CPU for processing, and the corresponding bit in the ISR register to one; software write EOI register notification interrupt processing completed. If the interrupt is a level trigger, the EOI broadcasts to all Ioapic,nmi, SMI, INIT, Extint, Sipi type interrupts without writing EOI. for the Pentium series and P6 schemas: Determine if the interrupt was received by itself. If it is a IPI, and delivery mode is lowest priority,lapic together with the other lapic, who receives the IPI. If the interrupt is received by itself, and the IPI interrupts (Bipi, Fipi, Sipi) in the NMI, SMI, INIT, Extinit, Init-deassert, or MP protocols, are referred directly to the CPU. Interrupts the pending to IRR or ISR registers, if there is an identical interrupt pending on the IRR and ISR registers, rejects the interrupt message, and notifies sender "Retry". With PENTIUM4, Xeon series process. With PENTIUM4, Xeon series process.
In these two sets of processes, several key registers (TPR,PRR) and delivery mode (lowest priority) are involved, which involves the priority of the interrupt and is explained in the "Interrupt priority issue".
When the CPU starts processing interrupts, it queries a data structure called the Interrupt Descriptor Table (Interrupt descriptor Table,idt), each of which is pre-filled with a gate descriptor (Gate descriptor), There are three kinds of door descriptors: task, interrupt and trap, where our main concern is interrupt-gate descriptor. The following figure shows the relevant information for interrupt Gate:
With it, you can find the handler function of the corresponding vector interrupt. Before entering the processing function, the stack is typically switched, and the corresponding register information (including Rflags, CS, RIP, etc.) is pushed into the stack to ensure that the relevant information can be recovered after the interrupt processing is completed. The process of switching stacks and saving related information is shown in the following illustration:
Mainly includes two kinds of cases, the first case is that the interrupted process is not a kernel process, then a permission level switch is required, so the second is that the interrupted process is a kernel process, so there is no need to switch the stack, just to save the information on the original stack. The whole process is clear, so there is no detail here. priority issues for interrupts.