|
|
INTERRUPT AND EXCEPTION HANDLING
Table 6-1. Protected-Mode Exceptions and Interrupts (Contd.)
Vector
Mnemonic
Description
Type
Error
Source
Code
15
-
(Intel reserved. Do not use.)
No
16
#MF
x87 FPU Floating-Point Error (Math
Fault
No
x87 FPU floating-point or WAIT/FWAIT
Fault)
instruction.
17
#AC
Alignment Check
Fault
Yes
Any data reference in memory.2
(Zero)
18
#MC
Machine Check
Abort
No
Error codes (if any) and source are model
dependent.3
19
#XM
SIMD Floating-Point Exception
Fault
No
SSE/SSE2/SSE3 floating-point
instructions4
20
#VE
Virtualization Exception
Fault
No
EPT violations5
21
#CP
Control Protection Exception
Fault
Yes
RET, IRET, RSTORSSP, and SETSSBSY
instructions can generate this exception.
When CET indirect branch tracking is
enabled, this exception can be generated
due to a missing ENDBRANCH instruction
at target of an indirect call or jump.
22-31
-
Intel reserved. Do not use.
32-255
-
User Defined (Non-reserved)
Interrupt
External interrupt or INT n instruction.
Interrupts
NOTES:
1. Processors after the Intel386 processor do not generate this exception.
2. This exception was introduced in the Intel486 processor.
3. This exception was introduced in the Pentium processor and enhanced in the P6 family processors.
4. This exception was introduced in the Pentium III processor.
5. This exception can occur only on processors that support the 1-setting of the “EPT-violation #VE” VM-execution control.
The processor’s local APIC is normally connected to a system-based I/O APIC. Here, external interrupts received at
the I/O APIC’s pins can be directed to the local APIC through the system bus (Pentium 4, Intel Core Duo, Intel Core
2, Intel Atom, and Intel Xeon processors) or the APIC serial bus (P6 family and Pentium processors). The I/O APIC
determines the vector number of the interrupt and sends this number to the local APIC. When a system contains
multiple processors, processors can also send interrupts to one another by means of the system bus (Pentium 4,
Intel Core Duo, Intel Core 2, Intel Atom, and Intel Xeon processors) or the APIC serial bus (P6 family and Pentium
processors).
The LINT[1:0] pins are not available on the Intel486 processor and earlier Pentium processors that do not contain
an on-chip local APIC. These processors have dedicated NMI and INTR pins. With these processors, external inter-
rupts are typically generated by a system-based interrupt controller (8259A), with the interrupts being signaled
through the INTR pin.
Note that several other pins on the processor can cause a processor interrupt to occur. However, these interrupts
are not handled by the interrupt and exception mechanism described in this chapter. These pins include the
RESET#, FLUSH#, STPCLK#, SMI#, R/S#, and INIT# pins. Whether they are included on a particular processor is
implementation dependent. Pin functions are described in the data books for the individual processors. The SMI#
pin is described in Chapter 32, “System Management Mode.”
6.3.2
Maskable Hardware Interrupts
Any external interrupt that is delivered to the processor by means of the INTR pin or through the local APIC is called
a maskable hardware interrupt. Maskable hardware interrupts that can be delivered through the INTR pin include
Vol. 3A
6-3
INTERRUPT AND EXCEPTION HANDLING
all IA-32 architecture defined interrupt vectors from 0 through 255; those that can be delivered through the local
APIC include interrupt vectors 16 through 255.
The IF flag in the EFLAGS register permits all maskable hardware interrupts to be masked as a group (see Section
6.8.1, “Masking Maskable Hardware Interrupts”). Note that when interrupts 0 through 15 are delivered through the
local APIC, the APIC indicates the receipt of an illegal vector.
6.3.3
Software-Generated Interrupts
The INT n instruction permits interrupts to be generated from within software by supplying an interrupt vector
number as an operand. For example, the INT 35 instruction forces an implicit call to the interrupt handler for inter-
rupt 35.
Any of the interrupt vectors from 0 to 255 can be used as a parameter in this instruction. If the processor’s
predefined NMI vector is used, however, the response of the processor will not be the same as it would be from an
NMI interrupt generated in the normal manner. If vector number 2 (the NMI vector) is used in this instruction, the
NMI interrupt handler is called, but the processor’s NMI-handling hardware is not activated.
Interrupts generated in software with the INT n instruction cannot be masked by the IF flag in the EFLAGS register.
6.4
SOURCES OF EXCEPTIONS
The processor receives exceptions from three sources:
• Processor-detected program-error exceptions.
• Software-generated exceptions.
• Machine-check exceptions.
6.4.1
Program-Error Exceptions
The processor generates one or more exceptions when it detects program errors during the execution in an appli-
cation program or the operating system or executive. Intel 64 and IA-32 architectures define a vector number for
each processor-detectable exception. Exceptions are classified as faults, traps, and aborts (see Section 6.5,
“Exception Classifications”).
6.4.2
Software-Generated Exceptions
The INTO, INT1, INT3, and BOUND instructions permit exceptions to be generated in software. These instructions
allow checks for exception conditions to be performed at points in the instruction stream. For example, INT3 causes
a breakpoint exception to be generated.
The INT n instruction can be used to emulate exceptions in software; but there is a limitation.1 If INT n provides a
vector for one of the architecturally-defined exceptions, the processor generates an interrupt to the correct vector
(to access the exception handler) but does not push an error code on the stack. This is true even if the associated
hardware-generated exception normally produces an error code. The exception handler will still attempt to pop an
error code from the stack while handling the exception. Because no error code was pushed, the handler will pop off
and discard the EIP instead (in place of the missing error code). This sends the return to the wrong location.
6.4.3
Machine-Check Exceptions
The P6 family and Pentium processors provide both internal and external machine-check mechanisms for checking
the operation of the internal chip hardware and bus transactions. These mechanisms are implementation depen-
1. The INT n instruction has opcode CD following by an immediate byte encoding the value of n. In contrast, INT1 has opcode F1 and
INT3 has opcode CC.
6-4
Vol. 3A
INTERRUPT AND EXCEPTION HANDLING
dent. When a machine-check error is detected, the processor signals a machine-check exception (vector 18) and
returns an error code.
See Chapter 6, “Interrupt 18-Machine-Check Exception (#MC),” and Chapter 16, “Machine-Check Architecture,”
for more information about the machine-check mechanism.
6.5
EXCEPTION CLASSIFICATIONS
Exceptions are classified as faults, traps, or aborts depending on the way they are reported and whether the
instruction that caused the exception can be restarted without loss of program or task continuity.
• Faults - A fault is an exception that can generally be corrected and that, once corrected, allows the program
to be restarted with no loss of continuity. When a fault is reported, the processor restores the machine state to
the state prior to the beginning of execution of the faulting instruction. The return address (saved contents of
the CS and EIP registers) for the fault handler points to the faulting instruction, rather than to the instruction
following the faulting instruction.
• Traps - A trap is an exception that is reported immediately following the execution of the trapping instruction.
Traps allow execution of a program or task to be continued without loss of program continuity. The return
address for the trap handler points to the instruction to be executed after the trapping instruction.
• Aborts - An abort is an exception that does not always report the precise location of the instruction causing
the exception and does not allow a restart of the program or task that caused the exception. Aborts are used to
report severe errors, such as hardware errors and inconsistent or illegal values in system tables.
NOTE
One exception subset normally reported as a fault is not restartable. Such exceptions result in loss
of some processor state. For example, executing a POPAD instruction where the stack frame
crosses over the end of the stack segment causes a fault to be reported. In this situation, the
exception handler sees that the instruction pointer (CS:EIP) has been restored as if the POPAD
instruction had not been executed. However, internal processor state (the general-purpose
registers) will have been modified. Such cases are considered programming errors. An application
causing this class of exceptions should be terminated by the operating system.
6.6
PROGRAM OR TASK RESTART
To allow the restarting of program or task following the handling of an exception or an interrupt, all exceptions
(except aborts) are guaranteed to report exceptions on an instruction boundary. All interrupts are guaranteed to be
taken on an instruction boundary.
For fault-class exceptions, the return instruction pointer (saved when the processor generates an exception) points
to the faulting instruction. So, when a program or task is restarted following the handling of a fault, the faulting
instruction is restarted (re-executed). Restarting the faulting instruction is commonly used to handle exceptions
that are generated when access to an operand is blocked. The most common example of this type of fault is a page-
fault exception (#PF) that occurs when a program or task references an operand located on a page that is not in
memory. When a page-fault exception occurs, the exception handler can load the page into memory and resume
execution of the program or task by restarting the faulting instruction. To ensure that the restart is handled trans-
parently to the currently executing program or task, the processor saves the necessary registers and stack pointers
to allow a restart to the state prior to the execution of the faulting instruction.
For trap-class exceptions, the return instruction pointer points to the instruction following the trapping instruction.
If a trap is detected during an instruction which transfers execution, the return instruction pointer reflects the
transfer. For example, if a trap is detected while executing a JMP instruction, the return instruction pointer points
to the destination of the JMP instruction, not to the next address past the JMP instruction. All trap exceptions allow
program or task restart with no loss of continuity. For example, the overflow exception is a trap exception. Here,
the return instruction pointer points to the instruction following the INTO instruction that tested EFLAGS.OF (over-
flow) flag. The trap handler for this exception resolves the overflow condition. Upon return from the trap handler,
program or task execution continues at the instruction following the INTO instruction.
Vol. 3A
6-5
INTERRUPT AND EXCEPTION HANDLING
The abort-class exceptions do not support reliable restarting of the program or task. Abort handlers are designed
to collect diagnostic information about the state of the processor when the abort exception occurred and then shut
down the application and system as gracefully as possible.
Interrupts rigorously support restarting of interrupted programs and tasks without loss of continuity. The return
instruction pointer saved for an interrupt points to the next instruction to be executed at the instruction boundary
where the processor took the interrupt. If the instruction just executed has a repeat prefix, the interrupt is taken
at the end of the current iteration with the registers set to execute the next iteration.
The ability of a P6 family processor to speculatively execute instructions does not affect the taking of interrupts by
the processor. Interrupts are taken at instruction boundaries located during the retirement phase of instruction
execution; so they are always taken in the “in-order” instruction stream. See Chapter 2, “Intel® 64 and IA-32
Architectures,” in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1, for more informa-
tion about the P6 family processors’ microarchitecture and its support for out-of-order instruction execution.
Note that the Pentium processor and earlier IA-32 processors also perform varying amounts of prefetching and
preliminary decoding. With these processors as well, exceptions and interrupts are not signaled until actual “in-
order” execution of the instructions. For a given code sample, the signaling of exceptions occurs uniformly when
the code is executed on any family of IA-32 processors (except where new exceptions or new opcodes have been
defined).
6.7
NONMASKABLE INTERRUPT (NMI)
The nonmaskable interrupt (NMI) can be generated in either of two ways:
• External hardware asserts the NMI pin.
• The processor receives a message on the system bus (Pentium 4, Intel Core Duo, Intel Core 2, Intel Atom, and
Intel Xeon processors) or the APIC serial bus (P6 family and Pentium processors) with a delivery mode NMI.
When the processor receives a NMI from either of these sources, the processor handles it immediately by calling
the NMI handler pointed to by interrupt vector number 2. The processor also invokes certain hardware conditions
to ensure that no other interrupts, including NMI interrupts, are received until the NMI handler has completed
executing (see Section 6.7.1, “Handling Multiple NMIs”).
Also, when an NMI is received from either of the above sources, it cannot be masked by the IF flag in the EFLAGS
register.
It is possible to issue a maskable hardware interrupt (through the INTR pin) to vector 2 to invoke the NMI interrupt
handler; however, this interrupt will not truly be an NMI interrupt. A true NMI interrupt that activates the
processor’s NMI-handling hardware can only be delivered through one of the mechanisms listed above.
6.7.1
Handling Multiple NMIs
While an NMI interrupt handler is executing, the processor blocks delivery of subsequent NMIs until the next execu-
tion of the IRET instruction. This blocking of NMIs prevents nested execution of the NMI handler. It is recommended
that the NMI interrupt handler be accessed through an interrupt gate to disable maskable hardware interrupts (see
Section 6.8.1, “Masking Maskable Hardware Interrupts”).
An execution of the IRET instruction unblocks NMIs even if the instruction causes a fault. For example, if the IRET
instruction executes with EFLAGS.VM = 1 and IOPL of less than 3, a general-protection exception is generated (see
Section 21.2.7, “Sensitive Instructions”). In such a case, NMIs are unmasked before the exception handler is
invoked.
6.8
ENABLING AND DISABLING INTERRUPTS
The processor inhibits the generation of some interrupts, depending on the state of the processor and of the IF and
RF flags in the EFLAGS register, as described in the following sections.
6-6
Vol. 3A
INTERRUPT AND EXCEPTION HANDLING
6.8.1
Masking Maskable Hardware Interrupts
The IF flag can disable the servicing of maskable hardware interrupts received on the processor’s INTR pin or
through the local APIC (see Section 6.3.2, “Maskable Hardware Interrupts”). When the IF flag is clear, the
processor inhibits interrupts delivered to the INTR pin or through the local APIC from generating an internal inter-
rupt request; when the IF flag is set, interrupts delivered to the INTR or through the local APIC pin are processed
as normal external interrupts.
The IF flag does not affect non-maskable interrupts (NMIs) delivered to the NMI pin or delivery mode NMI
messages delivered through the local APIC, nor does it affect processor generated exceptions. As with the other
flags in the EFLAGS register, the processor clears the IF flag in response to a hardware reset.
The fact that the group of maskable hardware interrupts includes the reserved interrupt and exception vectors 0
through 32 can potentially cause confusion. Architecturally, when the IF flag is set, an interrupt for any of the
vectors from 0 through 32 can be delivered to the processor through the INTR pin and any of the vectors from 16
through 32 can be delivered through the local APIC. The processor will then generate an interrupt and call the
interrupt or exception handler pointed to by the vector number. So for example, it is possible to invoke the page-
fault handler through the INTR pin (by means of vector 14); however, this is not a true page-fault exception. It is
an interrupt. As with the INT n instruction (see Section 6.4.2, “Software-Generated Exceptions”), when an inter-
rupt is generated through the INTR pin to an exception vector, the processor does not push an error code on the
stack, so the exception handler may not operate correctly.
The IF flag can be set or cleared with the STI (set interrupt-enable flag) and CLI (clear interrupt-enable flag)
instructions, respectively. These instructions may be executed only if the CPL is equal to or less than the IOPL. A
general-protection exception (#GP) is generated if they are executed when the CPL is greater than the IOPL.1 If
IF = 0, maskable hardware interrupts remain inhibited on the instruction boundary following an execution of STI.2
The inhibition ends after delivery of another event (e.g., exception) or the execution of the next instruction.
The IF flag is also affected by the following operations:
• The PUSHF instruction stores all flags on the stack, where they can be examined and modified. The POPF
instruction can be used to load the modified flags back into the EFLAGS register.
• Task switches and the POPF and IRET instructions load the EFLAGS register; therefore, they can be used to
modify the setting of the IF flag.
• When an interrupt is handled through an interrupt gate, the IF flag is automatically cleared, which disables
maskable hardware interrupts. (If an interrupt is handled through a trap gate, the IF flag is not cleared.)
See the descriptions of the CLI, STI, PUSHF, POPF, and IRET instructions in Chapter 3, “Instruction Set Reference,
A-L,” in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 2A, and Chapter 4, “Instruc-
tion Set Reference, M-U,” in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 2B, for a
detailed description of the operations these instructions are allowed to perform on the IF flag.
6.8.2
Masking Instruction Breakpoints
The RF (resume) flag in the EFLAGS register controls the response of the processor to instruction-breakpoint condi-
tions (see the description of the RF flag in Section 2.3, “System Flags and Fields in the EFLAGS Register”).
When set, it prevents an instruction breakpoint from generating a debug exception (#DB); when clear, instruction
breakpoints will generate debug exceptions. The primary function of the RF flag is to prevent the processor from
going into a debug exception loop on an instruction-breakpoint. See Section 18.3.1.1, “Instruction-Breakpoint
Exception Condition,” for more information on the use of this flag.
As noted in Section 6.8.3, execution of the MOV or POP instruction to load the SS register suppresses any instruc-
tion breakpoint on the next instruction (just as if EFLAGS.RF were 1).
1. The effect of the IOPL on these instructions is modified slightly when the virtual mode extension is enabled by setting the VME flag
in control register CR4: see Section 21.3, “Interrupt and Exception Handling in Virtual-8086 Mode.” Behavior is also impacted by the
PVI flag: see Section 21.4, “Protected-Mode Virtual Interrupts.”
2. Nonmaskable interrupts and system-management interrupts may also be inhibited on the instruction boundary following such an
execution of STI.
Vol. 3A
6-7
INTERRUPT AND EXCEPTION HANDLING
6.8.3
Masking Exceptions and Interrupts When Switching Stacks
To switch to a different stack segment, software often uses a pair of instructions, for example:
MOV SS, AX
MOV ESP, StackTop
(Software might also use the POP instruction to load SS and ESP.)
If an interrupt or exception occurs after the new SS segment descriptor has been loaded but before the ESP register
has been loaded, these two parts of the logical address into the stack space are inconsistent for the duration of the
interrupt or exception handler (assuming that delivery of the interrupt or exception does not itself load a new stack
pointer).
To account for this situation, the processor prevents certain events from being delivered after execution of a MOV
to SS instruction or a POP to SS instruction. The following items provide details:
• Any instruction breakpoint on the next instruction is suppressed (as if EFLAGS.RF were 1).
• Any data breakpoint on the MOV to SS instruction or POP to SS instruction is inhibited until the instruction
boundary following the next instruction.
• Any single-step trap that would be delivered following the MOV to SS instruction or POP to SS instruction
(because EFLAGS.TF is 1) is suppressed.
• The suppression and inhibition ends after delivery of an exception or the execution of the next instruction.
• If a sequence of consecutive instructions each loads the SS register (using MOV or POP), only the first is
guaranteed to inhibit or suppress events in this way.
Intel recommends that software use the LSS instruction to load the SS register and ESP together. The problem
identified earlier does not apply to LSS, and the LSS instruction does not inhibit events as detailed above.
6.9
PRIORITIZATION OF CONCURRENT EVENTS
If more than one event is pending at an instruction boundary (between execution of instructions), the processor
services them in a predictable order. Table 6-2 shows the priority among classes of event sources.
Table 6-2. Priority Among Concurrent Events
Priority
Description
1 (Highest)
Hardware Reset and Machine Checks
- RESET
- Machine Check (#MC)
2
Trap on Task Switch
- T flag in TSS is set (#DB)
3
External Hardware Interventions
- FLUSH
- STOPCLK
- SMI
- INIT
4
Traps on the Previous Instruction
- Trap-class Debug Exceptions (#DB due to TF flag set or data/I-O breakpoint)
5
Nonmaskable Interrupts (NMI) 1
6
Maskable Hardware Interrupts 1
7
Fault-class Debug Exceptions (#DB due to instruction breakpoint)
6-8
Vol. 3A
INTERRUPT AND EXCEPTION HANDLING
Table 6-2. Priority Among Concurrent Events (Contd.)
Priority
Description
8
Faults from Fetching Next Instruction
- Code-Segment Limit Violation (#GP)
- Code Page Fault (#PF)
9 (Lowest)
Faults from Decoding the Next Instruction
- Control protection exception due to missing ENDBRANCH at target of an indirect call or jump (#CP)
- Instruction length > 15 bytes (#GP)
- Invalid Opcode (#UD)
- Coprocessor Not Available (#NM)
NOTE
1. The Intel® 486 processor and earlier processors group nonmaskable and maskable interrupts in the same priority class.
The processor first services a pending event from the class which has the highest priority, transferring execution to
the first instruction of the handler. Lower priority exceptions are discarded; lower priority interrupts are held
pending. Discarded exceptions may be re-generated when the event handler returns execution to the point in the
program or task where the original event occurred. While the priority among the classes listed in Table 6-2 is
consistent across processor implementations, the priority of events within a class is implementation-dependent
and may vary from processor to processor.
Table 6-2 specifies the prioritization of events that may be pending at an instruction boundary. It does not specify
the prioritization of faults that arise during instruction execution or event delivery (these include #BR, #TS, #NP,
#SS, #GP, #PF, #AC, #MF, #XM, #VE, or #CP). It also does not apply to the events generated by the “Call to Inter-
rupt Procedure” instructions (INT n, INTO, INT3, and INT1), as these events are integral to the execution of those
instructions and do not occur between instructions.
6.10
INTERRUPT DESCRIPTOR TABLE (IDT)
The interrupt descriptor table (IDT) associates each exception or interrupt vector with a gate descriptor for the
procedure or task used to service the associated exception or interrupt. Like the GDT and LDTs, the IDT is an array
of 8-byte descriptors (in protected mode). Unlike the GDT, the first entry of the IDT may contain a descriptor. To
form an index into the IDT, the processor scales the exception or interrupt vector by eight (the number of bytes in
a gate descriptor). Because there are only 256 interrupt or exception vectors, the IDT need not contain more than
256 descriptors. It can contain fewer than 256 descriptors, because descriptors are required only for the interrupt
and exception vectors that may occur. All empty descriptor slots in the IDT should have the present flag for the
descriptor set to 0.
The base addresses of the IDT should be aligned on an 8-byte boundary to maximize performance of cache line
fills. The limit value is expressed in bytes and is added to the base address to get the address of the last valid byte.
A limit value of 0 results in exactly 1 valid byte. Because IDT entries are always eight bytes long, the limit should
always be one less than an integral multiple of eight (that is, 8N - 1).
The IDT may reside anywhere in the linear address space. As shown in Figure 6-1, the processor locates the IDT
using the IDTR register. This register holds both a 32-bit base address and 16-bit limit for the IDT.
The LIDT (load IDT register) and SIDT (store IDT register) instructions load and store the contents of the IDTR
register, respectively. The LIDT instruction loads the IDTR register with the base address and limit held in a
memory operand. This instruction can be executed only when the CPL is 0. It normally is used by the initialization
code of an operating system when creating an IDT. An operating system also may use it to change from one IDT to
another. The SIDT instruction copies the base and limit value stored in IDTR to memory. This instruction can be
executed at any privilege level.
If a vector references a descriptor beyond the limit of the IDT, a general-protection exception (#GP) is generated.
Vol. 3A
6-9
INTERRUPT AND EXCEPTION HANDLING
NOTE
Because interrupts are delivered to the processor core only once, an incorrectly configured IDT
could result in incomplete interrupt handling and/or the blocking of interrupt delivery.
IA-32 architecture rules need to be followed for setting up IDTR base/limit/access fields and each
field in the gate descriptors. The same apply for the Intel 64 architecture. This includes implicit
referencing of the destination code segment through the GDT or LDT and accessing the stack.
IDTR Register
47
16 15
0
IDT Base
Address
IDT Limit
Interrupt
Descriptor Table (IDT)
+
Gate for
Interrupt #n
(n-1)∗8
Gate for
Interrupt #3
16
Gate for
Interrupt #2
8
Gate for
Interrupt #1
0
31
0
Figure 6-1. Relationship of the IDTR and IDT
6.11
IDT DESCRIPTORS
The IDT may contain any of three kinds of gate descriptors:
• Task-gate descriptor
• Interrupt-gate descriptor
• Trap-gate descriptor
Figure 6-2 shows the formats for the task-gate, interrupt-gate, and trap-gate descriptors. The format of a task
gate used in an IDT is the same as that of a task gate used in the GDT or an LDT (see Section 8.2.5, “Task-Gate
Descriptor”). The task gate contains the segment selector for a TSS for an exception and/or interrupt handler task.
Interrupt and trap gates are very similar to call gates (see Section 5.8.3, “Call Gates”). They contain a far pointer
(segment selector and offset) that the processor uses to transfer program execution to a handler procedure in an
exception- or interrupt-handler code segment. These gates differ in the way the processor handles the IF flag in the
EFLAGS register (see Section 6.12.1.3, “Flag Usage By Exception- or Interrupt-Handler Procedure”).
6-10
Vol. 3A
INTERRUPT AND EXCEPTION HANDLING
Task Gate
31
16 15 14 13 12
8
7
0
D
P
P
0
0
1
0
1
4
L
31
16 15
0
TSS Segment Selector
0
Interrupt Gate
31
16 15 14 13 12
8
7
5
4
0
D
Offset 31..16
P
P
0
D 1
1
0
0
0
0
4
L
31
16 15
0
Segment Selector
Offset 15..0
0
Trap Gate
31
16 15 14 13 12
8
7
5
4
0
D
Offset 31..16
P
P
0
D 1
1
1
0
0
0
4
L
31
16 15
0
Segment Selector
Offset 15..0
0
DPL
Descriptor Privilege Level
Offset
Offset to procedure entry point
P
Segment Present flag
Selector
Segment Selector for destination code segment
D
Size of gate: 1 = 32 bits; 0 = 16 bits
Reserved
Figure 6-2. IDT Gate Descriptors
6.12
EXCEPTION AND INTERRUPT HANDLING
The processor handles calls to exception- and interrupt-handlers similar to the way it handles calls with a CALL
instruction to a procedure or a task. When responding to an exception or interrupt, the processor uses the excep-
tion or interrupt vector as an index to a descriptor in the IDT. If the index points to an interrupt gate or trap gate,
the processor calls the exception or interrupt handler in a manner similar to a CALL to a call gate (see Section
5.8.2, “Gate Descriptors,” through Section 5.8.6, “Returning from a Called Procedure”). If index points to a task
gate, the processor executes a task switch to the exception- or interrupt-handler task in a manner similar to a CALL
to a task gate (see Section 8.3, “Task Switching”).
Vol. 3A
6-11
INTERRUPT AND EXCEPTION HANDLING
6.12.1 Exception- or Interrupt-Handler Procedures
An interrupt gate or trap gate references an exception- or interrupt-handler procedure that runs in the context of
the currently executing task (see Figure 6-3). The segment selector for the gate points to a segment descriptor for
an executable code segment in either the GDT or the current LDT. The offset field of the gate descriptor points to
the beginning of the exception- or interrupt-handling procedure.
Destination
IDT
Code Segment
Interrupt
Offset
Procedure
Interrupt
Interrupt or
+
Vector
Trap Gate
Segment Selector
GDT or LDT
Base
Address
Segment
Descriptor
Figure 6-3. Interrupt Procedure Call
6-12
Vol. 3A
INTERRUPT AND EXCEPTION HANDLING
When the processor performs a call to the exception- or interrupt-handler procedure:
•
If the handler procedure is going to be executed at a numerically lower privilege level, a stack switch occurs.
When the stack switch occurs:
a. The segment selector and stack pointer for the stack to be used by the handler are obtained from the TSS
for the currently executing task. On this new stack, the processor pushes the stack segment selector and
stack pointer of the interrupted procedure.
b. The processor then saves the current state of the EFLAGS, CS, and EIP registers on the new stack (see
Figure 6-4).
c. If an exception causes an error code to be saved, it is pushed on the new stack after the EIP value.
•
If the handler procedure is going to be executed at the same privilege level as the interrupted procedure:
a. The processor saves the current state of the EFLAGS, CS, and EIP registers on the current stack (see Figure
6-4).
b. If an exception causes an error code to be saved, it is pushed on the current stack after the EIP value.
Stack Usage with No
Privilege-Level Change
Interrupted Procedure’s
and Handler’s Stack
ESP Before
EFLAGS
Transfer to Handler
CS
EIP
Error Code
ESP After
Transfer to Handler
Stack Usage with
Privilege-Level Change
Interrupted Procedure’s
Handler’s Stack
Stack
ESP Before
Transfer to Handler
SS
ESP
EFLAGS
CS
EIP
ESP After
Error Code
Transfer to Handler
Figure 6-4. Stack Usage on Transfers to Interrupt and Exception-Handling Routines
To return from an exception- or interrupt-handler procedure, the handler must use the IRET (or IRETD) instruction.
The IRET instruction is similar to the RET instruction except that it restores the saved flags into the EFLAGS
register. The IOPL field of the EFLAGS register is restored only if the CPL is 0. The IF flag is changed only if the CPL
is less than or equal to the IOPL. See Chapter 3, “Instruction Set Reference, A-L,” of the Intel® 64 and IA-32 Archi-
tectures Software Developer’s Manual, Volume 2A, for a description of the complete operation performed by the
IRET instruction.
If a stack switch occurred when calling the handler procedure, the IRET instruction switches back to the interrupted
procedure’s stack on the return.
Vol. 3A
6-13
INTERRUPT AND EXCEPTION HANDLING
6.12.1.1 Shadow Stack Usage on Transfers to Interrupt and Exception Handling Routines
When the processor performs a call to the exception- or interrupt-handler procedure:
• If the handler procedure is going to be execute at a numerically lower privilege level, a shadow stack switch
occurs. When the shadow stack switch occurs:
a. On a transfer from privilege level 3, if shadow stacks are enabled at privilege level 3 then the SSP is saved
to the IA32_PL3_SSP MSR.
b. If shadow stacks are enabled at the privilege level where the handler will execute then the shadow stack for
the handler is obtained from one of the following MSRs based on the privilege level at which the handler
executes.
• IA32_PL2_SSP if handler executes at privilege level 2.
• IA32_PL1_SSP if handler executes at privilege level 1.
• IA32_PL0_SSP if handler executes at privilege level 0.
c. The SSP obtained is then verified to ensure it points to a valid supervisory shadow stack that is not currently
active by verifying a supervisor shadow stack token at the address pointed to by the SSP. The operations
performed to verify and acquire the supervisor shadow stack token by making it busy are as described in
Section 17.2.3 of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1.
d. On this new shadow stack, the processor pushes the CS, LIP (CS.base + EIP), and SSP of the interrupted
procedure if the interrupted procedure was executing at privilege level less than 3; see Figure 6-5.1
• If the handler procedure is going to be executed at the same privilege level as the interrupted procedure and
shadow stacks are enabled at current privilege level:
a. The processor saves the current state of the CS, LIP (CS.base + EIP), and SSP registers on the current
shadow stack; see Figure 6-5.
1. If any of these pushes leads to an exception or a VM exit, the supervisor shadow-stack token remains busy.
6-14
Vol. 3A
INTERRUPT AND EXCEPTION HANDLING
Shadow Stack Usage with
No Privilege-Level Change
Interrupted Procedure’s
and Handler’s Shadow Stack
SSP Before
Transfer to Handler
CS
LIP
SSP
SSP After
Transfer to Handler
Shadow Stack Usage with Privilege-
Level Change from Level 3
Interrupted Procedure’s
Handler’s Shadow Stack
Shadow Stack
SSP Before
Transfer to Handler
Supervisor
Shadow Stack
SSP After
Token
Transfer to Handler
Shadow Stack Usage with Privilege-
Level Change from Level 2 or 1
Interrupted Procedure’s
Handler’s Shadow Stack
Shadow Stack
SSP Before
Transfer to Handler
Supervisor
Shadow Stack
Token
CS
LIP
SSP After
SSP
Transfer to Handler
Figure 6-5. Shadow Stack Usage on Transfers to Interrupt and Exception-Handling Routines
To return from an exception- or interrupt-handler procedure, the handler must use the IRET (or IRETD) instruction.
When executing a return from an interrupt or exception handler from the same privilege level as the interrupted
procedure, the processor performs these actions to enforce return address protection:
• Restores the CS and EIP registers to their values prior to the interrupt or exception.
Vol. 3A
6-15
INTERRUPT AND EXCEPTION HANDLING
If shadow stack is enabled:
- Compares the values on shadow stack at address SSP+8 (the LIP) and SSP+16 (the CS) to the CS and
(CS.base + EIP) popped from the stack and causes a control protection exception (#CP(FAR-RET/IRET)) if
they do not match.
- Pops the top-of-stack value (the SSP prior to the interrupt or exception) from shadow stack into SSP
register.
When executing a return from an interrupt or exception handler from a different privilege level than the interrupted
procedure, the processor performs the actions below.
• If shadow stack is enabled at current privilege level:
- If SSP is not aligned to 8 bytes then causes a control protection exception (#CP(FAR-RET/IRET)).
- If privilege level of the procedure being returned to is less than 3 (returning to supervisor mode):
• Compares the values on shadow stack at address SSP+8 (the LIP) and SSP+16 (the CS) to the CS and
(CS.base + EIP) popped from the stack and causes a control protection exception (#CP(FAR-RET/IRET))
if they do not match.
• Temporarily saves the top-of-stack value (the SSP of the procedure being returned to) internally.
- If a busy supervisor shadow stack token is present at address SSP+24, then marks the token free using
operations described in section Section 17.2.3 of the Intel® 64 and IA-32 Architectures Software
Developer’s Manual, Volume 1.
- If the privilege level of the procedure being returned to is less than 3 (returning to supervisor mode),
restores the SSP register from the internally saved value.
- If the privilege level of the procedure being returned to is 3 (returning to user mode) and shadow stack is
enabled at privilege level 3, then restores the SSP register with value of IA32_PL3_SSP MSR.
6.12.1.2 Protection of Exception- and Interrupt-Handler Procedures
The privilege-level protection for exception- and interrupt-handler procedures is similar to that used for ordinary
procedure calls when called through a call gate (see Section 5.8.4, “Accessing a Code Segment Through a Call
Gate”). The processor does not permit transfer of execution to an exception- or interrupt-handler procedure in a
less privileged code segment (numerically greater privilege level) than the CPL.
An attempt to violate this rule results in a general-protection exception (#GP). The protection mechanism for
exception- and interrupt-handler procedures is different in the following ways:
• Because interrupt and exception vectors have no RPL, the RPL is not checked on implicit calls to exception and
interrupt handlers.
• The processor checks the DPL of the interrupt or trap gate only if an exception or interrupt is generated with an
INT n, INT3, or INTO instruction.1 Here, the CPL must be less than or equal to the DPL of the gate. This
restriction prevents application programs or procedures running at privilege level 3 from using a software
interrupt to access critical exception handlers, such as the page-fault handler, providing that those handlers are
placed in more privileged code segments (numerically lower privilege level). For hardware-generated interrupts
and processor-detected exceptions, the processor ignores the DPL of interrupt and trap gates.
Because exceptions and interrupts generally do not occur at predictable times, these privilege rules effectively
impose restrictions on the privilege levels at which exception and interrupt- handling procedures can run. Either of
the following techniques can be used to avoid privilege-level violations.
• The exception or interrupt handler can be placed in a conforming code segment. This technique can be used for
handlers that only need to access data available on the stack (for example, divide error exceptions). If the
handler needs data from a data segment, the data segment needs to be accessible from privilege level 3, which
would make it unprotected.
• The handler can be placed in a nonconforming code segment with privilege level 0. This handler would always
run, regardless of the CPL that the interrupted program or task is running at.
1. This check is not performed by execution of the INT1 instruction (opcode F1); it would be performed by execution of INT 1 (opcode
CD 01).
6-16
Vol. 3A
INTERRUPT AND EXCEPTION HANDLING
6.12.1.3 Flag Usage By Exception- or Interrupt-Handler Procedure
When accessing an exception or interrupt handler through either an interrupt gate or a trap gate, the processor
clears the TF flag in the EFLAGS register after it saves the contents of the EFLAGS register on the stack. (On calls
to exception and interrupt handlers, the processor also clears the VM, RF, and NT flags in the EFLAGS register, after
they are saved on the stack.) Clearing the TF flag prevents instruction tracing from affecting interrupt response and
ensures that no single-step exception will be delivered after delivery to the handler. A subsequent IRET instruction
restores the TF (and VM, RF, and NT) flags to the values in the saved contents of the EFLAGS register on the stack.
The only difference between an interrupt gate and a trap gate is the way the processor handles the IF flag in the
EFLAGS register. When accessing an exception- or interrupt-handling procedure through an interrupt gate, the
processor clears the IF flag to prevent other interrupts from interfering with the current interrupt handler. A subse-
quent IRET instruction restores the IF flag to its value in the saved contents of the EFLAGS register on the stack.
Accessing a handler procedure through a trap gate does not affect the IF flag.
6.12.2 Interrupt Tasks
When an exception or interrupt handler is accessed through a task gate in the IDT, a task switch results. Handling
an exception or interrupt with a separate task offers several advantages:
• The entire context of the interrupted program or task is saved automatically.
• A new TSS permits the handler to use a new privilege level 0 stack when handling the exception or interrupt. If
an exception or interrupt occurs when the current privilege level 0 stack is corrupted, accessing the handler
through a task gate can prevent a system crash by providing the handler with a new privilege level 0 stack.
• The handler can be further isolated from other tasks by giving it a separate address space. This is done by
giving it a separate LDT.
The disadvantage of handling an interrupt with a separate task is that the amount of machine state that must be
saved on a task switch makes it slower than using an interrupt gate, resulting in increased interrupt latency.
A task gate in the IDT references a TSS descriptor in the GDT (see Figure 6-6). A switch to the handler task is
handled in the same manner as an ordinary task switch (see Section 8.3, “Task Switching”). The link back to the
interrupted task is stored in the previous task link field of the handler task’s TSS. If an exception caused an error
code to be generated, this error code is copied to the stack of the new task.
When exception- or interrupt-handler tasks are used in an operating system, there are actually two mechanisms
that can be used to dispatch tasks: the software scheduler (part of the operating system) and the hardware sched-
uler (part of the processor's interrupt mechanism). The software scheduler needs to accommodate interrupt tasks
that may be dispatched when interrupts are enabled.
Vol. 3A
6-17
INTERRUPT AND EXCEPTION HANDLING
NOTE
Because IA-32 architecture tasks are not re-entrant, an interrupt-handler task must disable
interrupts between the time it completes handling the interrupt and the time it executes the IRET
instruction. This action prevents another interrupt from occurring while the interrupt task’s TSS is
still marked busy, which would cause a general-protection (#GP) exception.
TSS for Interrupt-
IDT
Handling Task
Interrupt
Task Gate
Vector
TSS Selector
TSS
Base
Address
GDT
TSS Descriptor
Figure 6-6. Interrupt Task Switch
6.13
ERROR CODE
When an exception condition is related to a specific segment selector or IDT vector, the processor pushes an error
code onto the stack of the exception handler (whether it is a procedure or task). The error code has the format
shown in Figure 6-7. The error code resembles a segment selector; however, instead of a TI flag and RPL field, the
error code contains 3 flags:
EXT
External event (bit 0) - When set, indicates that the exception occurred during delivery of an
event external to the program, such as an interrupt or an earlier exception.1 The bit is cleared if the
exception occurred during delivery of a software interrupt (INT n, INT3, or INTO).
IDT
Descriptor location (bit 1) - When set, indicates that the index portion of the error code refers
to a gate descriptor in the IDT; when clear, indicates that the index refers to a descriptor in the GDT
or the current LDT.
TI
GDT/LDT (bit 2) - Only used when the IDT flag is clear. When set, the TI flag indicates that the
index portion of the error code refers to a segment or gate descriptor in the LDT; when clear, it indi-
cates that the index refers to a descriptor in the current GDT.
1. The bit is also set if the exception occurred during delivery of INT1.
6-18
Vol. 3A
INTERRUPT AND EXCEPTION HANDLING
31
3
2
1
0
I
E
T
Reserved
Segment Selector Index
I
D
X
T
T
Figure 6-7. Error Code
The segment selector index field provides an index into the IDT, GDT, or current LDT to the segment or gate
selector being referenced by the error code. In some cases the error code is null (all bits are clear except possibly
EXT). A null error code indicates that the error was not caused by a reference to a specific segment or that a null
segment selector was referenced in an operation.
The format of the error code is different for page-fault exceptions (#PF). See the “Interrupt 14-Page-Fault Excep-
tion (#PF)” section in this chapter.
The format of the error code is different for control protection exceptions (#CP). See the “Interrupt 21-Control
Protection Exception (#CP)” section in this chapter.
The error code is pushed on the stack as a doubleword or word (depending on the default interrupt, trap, or task
gate size). To keep the stack aligned for doubleword pushes, the upper half of the error code is reserved. Note that
the error code is not popped when the IRET instruction is executed to return from an exception handler, so the
handler must remove the error code before executing a return.
Error codes are not pushed on the stack for exceptions that are generated externally (with the INTR or LINT[1:0]
pins) or the INT n instruction, even if an error code is normally produced for those exceptions.
6.14
EXCEPTION AND INTERRUPT HANDLING IN 64-BIT MODE
In 64-bit mode, interrupt and exception handling is similar to what has been described for non-64-bit modes. The
following are the exceptions:
• All interrupt handlers pointed by the IDT are in 64-bit code (this does not apply to the SMI handler).
• The size of interrupt-stack pushes is fixed at 64 bits; and the processor uses 8-byte, zero extended stores.
• The stack pointer (SS:RSP) is pushed unconditionally on interrupts. In legacy modes, this push is conditional
and based on a change in current privilege level (CPL).
• The new SS is set to NULL if there is a change in CPL.
• IRET behavior changes.
• There is a new interrupt stack-switch mechanism and a new interrupt shadow stack-switch mechanism.
• The alignment of interrupt stack frame is different.
6.14.1
64-Bit Mode IDT
Interrupt and trap gates are 16 bytes in length to provide a 64-bit offset for the instruction pointer (RIP). The 64-
bit RIP referenced by interrupt-gate descriptors allows an interrupt service routine to be located anywhere in the
linear-address space. See Figure 6-8.
Vol. 3A
6-19
INTERRUPT AND EXCEPTION HANDLING
Interrupt/Trap Gate
31
0
Reserved
12
31
0
Offset 63..32
8
31
16 15 14 13 12
11
8
7
5
4
2
0
D
Offset 31..16
P
P
0
TYPE
0
0
0
0
0
IST
4
L
31
16 15
0
Segment Selector
Offset 15..0
0
DPL
Descriptor Privilege Level
Offset
Offset to procedure entry point
P
Segment Present flag
Selector
Segment Selector for destination code segment
IST
Interrupt Stack Table
Figure 6-8. 64-Bit IDT Gate Descriptors
In 64-bit mode, the IDT index is formed by scaling the interrupt vector by 16. The first eight bytes (bytes 7:0) of a
64-bit mode interrupt gate are similar but not identical to legacy 32-bit interrupt gates. The type field (bits 11:8 in
bytes 7:4) is described in Table 3-2. The Interrupt Stack Table (IST) field (bits 4:0 in bytes 7:4) is used by the stack
switching mechanisms described in Section 6.14.5, “Interrupt Stack Table.” Bytes 11:8 hold the upper 32 bits of
the target RIP (interrupt segment offset) in canonical form. A general-protection exception (#GP) is generated if
software attempts to reference an interrupt gate with a target RIP that is not in canonical form.
The target code segment referenced by the interrupt gate must be a 64-bit code segment (CS.L = 1, CS.D = 0). If
the target is not a 64-bit code segment, a general-protection exception (#GP) is generated with the IDT vector
number reported as the error code.
Only 64-bit interrupt and trap gates can be referenced in IA-32e mode (64-bit mode and compatibility mode).
Legacy 32-bit interrupt or trap gate types (0EH or 0FH) are redefined in IA-32e mode as 64-bit interrupt and trap
gate types. No 32-bit interrupt or trap gate type exists in IA-32e mode. If a reference is made to a 16-bit interrupt
or trap gate (06H or 07H), a general-protection exception (#GP(0)) is generated.
6.14.2
64-Bit Mode Stack Frame
In legacy mode, the size of an IDT entry (16 bits or 32 bits) determines the size of interrupt-stack-frame pushes.
SS:ESP is pushed only on a CPL change. In 64-bit mode, the size of interrupt stack-frame pushes is fixed at eight
bytes. This is because only 64-bit mode gates can be referenced. 64-bit mode also pushes SS:RSP unconditionally,
rather than only on a CPL change.
When shadow stacks are enabled at the interrupt handler’s privilege level and the interrupted procedure was not
executing at a privilege level 3, then the processor pushes the CS:LIP:SSP of the interrupted procedure on the
shadow stack of the interrupt handler (where LIP is the linear address of the return address).
Aside from error codes, pushing SS:RSP unconditionally presents operating systems with a consistent interrupt-
stackframe size across all interrupts. Interrupt service-routine entry points that handle interrupts generated by the
INTn instruction or external INTR# signal can push an additional error code place-holder to maintain consistency.
In legacy mode, the stack pointer may be at any alignment when an interrupt or exception causes a stack frame to
be pushed. This causes the stack frame and succeeding pushes done by an interrupt handler to be at arbitrary
alignments. In IA-32e mode, the RSP is aligned to a 16-byte boundary before pushing the stack frame. The stack
frame itself is aligned on a 16-byte boundary when the interrupt handler is called. The processor can arbitrarily
realign the new RSP on interrupts because the previous (possibly unaligned) RSP is unconditionally saved on the
newly aligned stack. The previous RSP will be automatically restored by a subsequent IRET.
6-20
Vol. 3A
INTERRUPT AND EXCEPTION HANDLING
Aligning the stack permits exception and interrupt frames to be aligned on a 16-byte boundary before interrupts
are re-enabled. This allows the stack to be formatted for optimal storage of 16-byte XMM registers, which enables
the interrupt handler to use faster 16-byte aligned loads and stores (MOVAPS rather than MOVUPS) to save and
restore XMM registers.
Although the RSP alignment is always performed when LMA = 1, it is only of consequence for the kernel-mode case
where there is no stack switch or IST used. For a stack switch or IST, the OS would have presumably put suitably
aligned RSP values in the TSS.
6.14.3 IRET in IA-32e Mode
In IA-32e mode, IRET executes with an 8-byte operand size. There is nothing that forces this requirement. The
stack is formatted in such a way that for actions where IRET is required, the 8-byte IRET operand size works
correctly.
Because interrupt stack-frame pushes are always eight bytes in IA-32e mode, an IRET must pop eight byte items
off the stack. This is accomplished by preceding the IRET with a 64-bit operand-size prefix. The size of the pop is
determined by the address size of the instruction. The SS/ESP/RSP size adjustment is determined by the stack
size.
IRET pops SS:RSP unconditionally off the interrupt stack frame only when it is executed in 64-bit mode. In compat-
ibility mode, IRET pops SS:RSP off the stack only if there is a CPL change. This allows legacy applications to
execute properly in compatibility mode when using the IRET instruction. 64-bit interrupt service routines that exit
with an IRET unconditionally pop SS:RSP off of the interrupt stack frame, even if the target code segment is
running in 64-bit mode or at CPL = 0. This is because the original interrupt always pushes SS:RSP.
When shadow stacks are enabled and the target privilege level is not 3, the CS:LIP from the shadow stack frame is
compared to the return linear address formed by CS:EIP from the stack. If they do not match then the processor
caused a control protection exception (#CP(FAR-RET/IRET)), else the processor pops the SSP of the interrupted
procedure from the shadow stack. If the target privilege level is 3 and shadow stacks are enabled at privilege level
3, then the SSP for the interrupted procedure is restored from the IA32_PL3_SSP MSR.
In IA-32e mode, IRET is allowed to load a NULL SS under certain conditions. If the target mode is 64-bit mode and
the target CPL ≠ 3, IRET allows SS to be loaded with a NULL selector. As part of the stack switch mechanism, an
interrupt or exception sets the new SS to NULL, instead of fetching a new SS selector from the TSS and loading the
corresponding descriptor from the GDT or LDT. The new SS selector is set to NULL in order to properly handle
returns from subsequent nested far transfers. If the called procedure itself is interrupted, the NULL SS is pushed
on the stack frame. On the subsequent IRET, the NULL SS on the stack acts as a flag to tell the processor not to
load a new SS descriptor.
6.14.4 Stack Switching in IA-32e Mode
The IA-32 architecture provides a mechanism to automatically switch stack frames in response to an interrupt. The
64-bit extensions of Intel 64 architecture implement a modified version of the legacy stack-switching mechanism
and an alternative stack-switching mechanism called the interrupt stack table (IST).
In IA-32 modes, the legacy IA-32 stack-switch mechanism is unchanged. In IA-32e mode, the legacy stack-switch
mechanism is modified. When stacks are switched as part of a 64-bit mode privilege-level change (resulting from
an interrupt), a new SS descriptor is not loaded. IA-32e mode loads only an inner-level RSP from the TSS. The new
SS selector is forced to NULL and the SS selector’s RPL field is set to the new CPL. The new SS is set to NULL in
order to handle nested far transfers (far CALL, INT, interrupts, and exceptions). The old SS and RSP are saved on
the new stack (Figure 6-9). On the subsequent IRET, the old SS is popped from the stack and loaded into the SS
register.
In summary, a stack switch in IA-32e mode works like the legacy stack switch, except that a new SS selector is not
loaded from the TSS. Instead, the new SS is forced to NULL.
Vol. 3A
6-21
INTERRUPT AND EXCEPTION HANDLING
Legacy Mode
Stack Usage with
IA-32e Mode
Privilege-Level Change
Handler’s Stack
Handler’s Stack
+20
SS
SS
+40
+16
ESP
RSP
+32
+12
EFLAGS
RFLAGS
+24
+8
+16
CS
CS
+4
EIP
RIP
+8
0
Error Code
Stack Pointer After
Error Code
0
Transfer to Handler
Figure 6-9. IA-32e Mode Stack Usage After Privilege Level Change
6.14.5 Interrupt Stack Table
In IA-32e mode, a new interrupt stack table (IST) mechanism is available as an alternative to the modified legacy
stack-switching mechanism described above. This mechanism unconditionally switches stacks when it is enabled.
It can be enabled on an individual interrupt-vector basis using a field in the IDT entry. This means that some inter-
rupt vectors can use the modified legacy mechanism and others can use the IST mechanism.
The IST mechanism is only available in IA-32e mode. It is part of the 64-bit mode TSS. The motivation for the IST
mechanism is to provide a method for specific interrupts (such as NMI, double-fault, and machine-check) to always
execute on a known good stack. In legacy mode, interrupts can use the task-switch mechanism to set up a known-
good stack by accessing the interrupt service routine through a task gate located in the IDT. However, the legacy
task-switch mechanism is not supported in IA-32e mode.
The IST mechanism provides up to seven IST pointers in the TSS. The pointers are referenced by an interrupt-gate
descriptor in the interrupt-descriptor table (IDT); see Figure 6-8. The gate descriptor contains a 3-bit IST index
field that provides an offset into the IST section of the TSS. Using the IST mechanism, the processor loads the value
pointed by an IST pointer into the RSP.
When an interrupt occurs, the new SS selector is forced to NULL and the SS selector’s RPL field is set to the new
CPL. The old SS, RSP, RFLAGS, CS, and RIP are pushed onto the new stack. Interrupt processing then proceeds as
normal. If the IST index is zero, the modified legacy stack-switching mechanism described above is used.
To support this stack-switching mechanism with shadow stacks enabled, the processor provides an MSR, IA32_IN-
TERRUPT_SSP_TABLE, to program the linear address of a table of seven shadow stack pointers that are selected
using the IST index from the gate descriptor. To switch to a shadow stack selected from the interrupt shadow stack
table pointed to by the IA32_INTERRUPT_SSP_TABLE, the processor requires that the shadow stack addresses
programmed into this table point to a supervisor shadow stack token; see Figure 6-10.
6-22
Vol. 3A
INTERRUPT AND EXCEPTION HANDLING
IST7 SSP
56
IST6 SSP
48
IST5 SSP
40
IST4 SSP
32
IST3 SSP
24
IST2 SSP
16
IST1 SSP
8
Not used; available
0
IA32_INTERRUPT_SSP_TABLE
Figure 6-10. Interrupt Shadow Stack Table
6.15
EXCEPTION AND INTERRUPT REFERENCE
The following sections describe conditions which generate exceptions and interrupts. They are arranged in the
order of vector numbers. The information contained in these sections are as follows:
• Exception Class - Indicates whether the exception class is a fault, trap, or abort type. Some exceptions can
be either a fault or trap type, depending on when the error condition is detected. (This section is not applicable
to interrupts.)
• Description - Gives a general description of the purpose of the exception or interrupt type. It also describes
how the processor handles the exception or interrupt.
• Exception Error Code - Indicates whether an error code is saved for the exception. If one is saved, the
contents of the error code are described. (This section is not applicable to interrupts.)
• Saved Instruction Pointer - Describes which instruction the saved (or return) instruction pointer points to.
It also indicates whether the pointer can be used to restart a faulting instruction.
• Program State Change - Describes the effects of the exception or interrupt on the state of the currently
running program or task and the possibilities of restarting the program or task without loss of continuity.
Vol. 3A
6-23
INTERRUPT AND EXCEPTION HANDLING
Interrupt 0-Divide Error Exception (#DE)
Exception Class
Fault.
Description
Indicates the divisor operand for a DIV or IDIV instruction is 0 or that the result cannot be represented in the
number of bits specified for the destination operand.
Exception Error Code
None.
Saved Instruction Pointer
Saved contents of CS and EIP registers point to the instruction that generated the exception.
Program State Change
A program-state change does not accompany the divide error, because the exception occurs before the faulting
instruction is executed.
6-24
Vol. 3A
INTERRUPT AND EXCEPTION HANDLING
Interrupt 1-Debug Exception (#DB)
Exception Class
Trap or Fault. The exception handler can distinguish between traps or faults by exam-
ining the contents of DR6 and the other debug registers.
Description
Indicates that one or more of several debug-exception conditions has been detected. Whether the exception is a
fault or a trap depends on the condition (see Table 6-3). See Chapter 18, “Debug, Branch Profile, TSC, and Intel®
Resource Director Technology (Intel® RDT) Features,” for detailed information about the debug exceptions.
Table 6-3. Debug Exception Conditions and Corresponding Exception Classes
Exception Condition
Exception Class
Instruction fetch breakpoint
Fault
Data read or write breakpoint
Trap
I/O read or write breakpoint
Trap
General detect condition (in conjunction with in-circuit emulation)
Fault
Single-step
Trap
Task-switch
Trap
Execution of INT11
Trap
NOTES:
1. Hardware vendors may use the INT1 instruction for hardware debug. For that reason, Intel recommends software vendors instead
use the INT3 instruction for software breakpoints.
Exception Error Code
None. An exception handler can examine the debug registers to determine which condition caused the exception.
Saved Instruction Pointer
Fault - Saved contents of CS and EIP registers point to the instruction that generated the exception.
Trap - Saved contents of CS and EIP registers point to the instruction following the instruction that generated the
exception.
Program State Change
Fault - A program-state change does not accompany the debug exception, because the exception occurs before
the faulting instruction is executed. The program can resume normal execution upon returning from the debug
exception handler.
Trap - A program-state change does accompany the debug exception, because the instruction or task switch being
executed is allowed to complete before the exception is generated. However, the new state of the program is not
corrupted and execution of the program can continue reliably.
The following items detail the treatment of debug exceptions on the instruction boundary following execution of the
MOV or the POP instruction that loads the SS register:
• If EFLAGS.TF is 1, no single-step trap is generated.
• If the instruction encounters a data breakpoint, the resulting debug exception is delivered after completion of
the instruction after the MOV or POP. This occurs even if the next instruction is INT n, INT3, or INTO.
• Any instruction breakpoint on the instruction after the MOV or POP is suppressed (as if EFLAGS.RF were 1).
Any debug exception inside an RTM region causes a transactional abort and, by default, redirects control flow to the
fallback instruction address. If advanced debugging of RTM transactional regions has been enabled, any transac-
tional abort due to a debug exception instead causes execution to roll back to just before the XBEGIN instruction
Vol. 3A
6-25
INTERRUPT AND EXCEPTION HANDLING
and then delivers a #DB. See Section 16.3.7, “RTM-Enabled Debugger Support,” of Intel® 64 and IA-32 Architec-
tures Software Developer’s Manual, Volume 1.
6-26
Vol. 3A
INTERRUPT AND EXCEPTION HANDLING
Interrupt 2-NMI Interrupt
Exception Class
Not applicable.
Description
The nonmaskable interrupt (NMI) is generated externally by asserting the processor’s NMI pin or through an NMI
request set by the I/O APIC to the local APIC. This interrupt causes the NMI interrupt handler to be called.
Exception Error Code
Not applicable.
Saved Instruction Pointer
The processor always takes an NMI interrupt on an instruction boundary. The saved contents of CS and EIP regis-
ters point to the next instruction to be executed at the point the interrupt is taken. See Section 6.5, “Exception
Classifications,” for more information about when the processor takes NMI interrupts.
Program State Change
The instruction executing when an NMI interrupt is received is completed before the NMI is generated. A program
or task can thus be restarted upon returning from an interrupt handler without loss of continuity, provided the
interrupt handler saves the state of the processor before handling the interrupt and restores the processor’s state
prior to a return.
Vol. 3A
6-27
INTERRUPT AND EXCEPTION HANDLING
Interrupt 3-Breakpoint Exception (#BP)
Exception Class
Trap.
Description
Indicates that a breakpoint instruction (INT3, opcode CC) was executed, causing a breakpoint trap to be gener-
ated. Typically, a debugger sets a breakpoint by replacing the first opcode byte of an instruction with the opcode for
the INT3 instruction. (The INT3 instruction is one byte long, which makes it easy to replace an opcode in a code
segment in RAM with the breakpoint opcode.) The operating system or a debugging tool can use a data segment
mapped to the same physical address space as the code segment to place an INT3 instruction in places where it is
desired to call the debugger.
With the P6 family, Pentium, Intel486, and Intel386 processors, it is more convenient to set breakpoints with the
debug registers. (See Section 18.3.2, “Breakpoint Exception (#BP)-Interrupt Vector 3,” for information about the
breakpoint exception.) If more breakpoints are needed beyond what the debug registers allow, the INT3 instruction
can be used.
Any breakpoint exception inside an RTM region causes a transactional abort and, by default, redirects control flow
to the fallback instruction address. If advanced debugging of RTM transactional regions has been enabled, any
transactional abort due to a break exception instead causes execution to roll back to just before the XBEGIN
instruction and then delivers a debug exception (#DB) - not a breakpoint exception. See Section 16.3.7, “RTM-
Enabled Debugger Support,” of Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1.
A breakpoint exception can also be generated by executing the INT n instruction with an operand of 3. The action
of this instruction (INT 3) is slightly different than that of the INT3 instruction (see “INT n/INTO/INT3/INT1-Call to
Interrupt Procedure” in Chapter 3 of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume
2A).
Exception Error Code
None.
Saved Instruction Pointer
Saved contents of CS and EIP registers point to the instruction following the INT3 instruction.
Program State Change
Even though the EIP points to the instruction following the breakpoint instruction, the state of the program is
essentially unchanged because the INT3 instruction does not affect any register or memory locations. The
debugger can thus resume the suspended program by replacing the INT3 instruction that caused the breakpoint
with the original opcode and decrementing the saved contents of the EIP register. Upon returning from the
debugger, program execution resumes with the replaced instruction.
6-28
Vol. 3A
INTERRUPT AND EXCEPTION HANDLING
Interrupt 4-Overflow Exception (#OF)
Exception Class
Trap.
Description
Indicates that an overflow trap occurred when an INTO instruction was executed. The INTO instruction checks the
state of the OF flag in the EFLAGS register. If the OF flag is set, an overflow trap is generated.
Some arithmetic instructions (such as the ADD and SUB) perform both signed and unsigned arithmetic. These
instructions set the OF and CF flags in the EFLAGS register to indicate signed overflow and unsigned overflow,
respectively. When performing arithmetic on signed operands, the OF flag can be tested directly or the INTO
instruction can be used. The benefit of using the INTO instruction is that if the overflow exception is detected, an
exception handler can be called automatically to handle the overflow condition.
Exception Error Code
None.
Saved Instruction Pointer
The saved contents of CS and EIP registers point to the instruction following the INTO instruction.
Program State Change
Even though the EIP points to the instruction following the INTO instruction, the state of the program is essentially
unchanged because the INTO instruction does not affect any register or memory locations. The program can thus
resume normal execution upon returning from the overflow exception handler.
Vol. 3A
6-29
INTERRUPT AND EXCEPTION HANDLING
Interrupt 5-BOUND Range Exceeded Exception (#BR)
Exception Class
Fault.
Description
Indicates that a BOUND-range-exceeded fault occurred when a BOUND instruction was executed. The BOUND
instruction checks that a signed array index is within the upper and lower bounds of an array located in memory. If
the array index is not within the bounds of the array, a BOUND-range-exceeded fault is generated.
Exception Error Code
None.
Saved Instruction Pointer
The saved contents of CS and EIP registers point to the BOUND instruction that generated the exception.
Program State Change
A program-state change does not accompany the bounds-check fault, because the operands for the BOUND
instruction are not modified. Returning from the BOUND-range-exceeded exception handler causes the BOUND
instruction to be restarted.
6-30
Vol. 3A
INTERRUPT AND EXCEPTION HANDLING
Interrupt 6-Invalid Opcode Exception (#UD)
Exception Class
Fault.
Description
Indicates that the processor did one of the following things:
• Attempted to execute an invalid or reserved opcode.
• Attempted to execute an instruction with an operand type that is invalid for its accompanying opcode; for
example, the source operand for a LES instruction is not a memory location.
• Attempted to execute an MMX or SSE/SSE2/SSE3 instruction on an Intel 64 or IA-32 processor that does not
support the MMX technology or SSE/SSE2/SSE3/SSSE3 extensions, respectively. CPUID feature flags MMX (bit
23), SSE (bit 25), SSE2 (bit 26), SSE3 (ECX, bit 0), SSSE3 (ECX, bit 9) indicate support for these extensions.
• Attempted to execute an MMX instruction or SSE/SSE2/SSE3/SSSE3 SIMD instruction (with the exception of
the MOVNTI, PAUSE, PREFETCHh, SFENCE, LFENCE, MFENCE, CLFLUSH, MONITOR, and MWAIT instructions)
when the EM flag in control register CR0 is set (1).
• Attempted to execute an SSE/SE2/SSE3/SSSE3 instruction when the OSFXSR bit in control register CR4 is
clear (0). Note this does not include the following SSE/SSE2/SSE3 instructions: MASKMOVQ, MOVNTQ,
MOVNTI, PREFETCHh, SFENCE, LFENCE, MFENCE, and CLFLUSH; or the 64-bit versions of the PAVGB, PAVGW,
PEXTRW, PINSRW, PMAXSW, PMAXUB, PMINSW, PMINUB, PMOVMSKB, PMULHUW, PSADBW, PSHUFW, PADDQ,
PSUBQ, PALIGNR, PABSB, PABSD, PABSW, PHADDD, PHADDSW, PHADDW, PHSUBD, PHSUBSW, PHSUBW,
PMADDUBSM, PMULHRSW, PSHUFB, PSIGNB, PSIGND, and PSIGNW.
• Attempted to execute an SSE/SSE2/SSE3/SSSE3 instruction on an Intel 64 or IA-32 processor that caused a
SIMD floating-point exception when the OSXMMEXCPT bit in control register CR4 is clear (0).
• Executed a UD0, UD1 or UD2 instruction. Note that even though it is the execution of the UD0, UD1 or UD2
instruction that causes the invalid opcode exception, the saved instruction pointer will still points at the UD0,
UD1 or UD2 instruction.
• Detected a LOCK prefix that precedes an instruction that may not be locked or one that may be locked but the
destination operand is not a memory location.
• Attempted to execute an LLDT, SLDT, LTR, STR, LSL, LAR, VERR, VERW, or ARPL instruction while in real-
address or virtual-8086 mode.
• Attempted to execute the RSM instruction when not in SMM mode.
In Intel 64 and IA-32 processors that implement out-of-order execution microarchitectures, this exception is not
generated until an attempt is made to retire the result of executing an invalid instruction; that is, decoding and
speculatively attempting to execute an invalid opcode does not generate this exception. Likewise, in the Pentium
processor and earlier IA-32 processors, this exception is not generated as the result of prefetching and preliminary
decoding of an invalid instruction. (See Section 6.5, “Exception Classifications,” for general rules for taking of inter-
rupts and exceptions.)
The opcodes D6 and F1 are undefined opcodes reserved by the Intel 64 and IA-32 architectures. These opcodes,
even though undefined, do not generate an invalid opcode exception.
Exception Error Code
None.
Saved Instruction Pointer
The saved contents of CS and EIP registers point to the instruction that generated the exception.
Program State Change
A program-state change does not accompany an invalid-opcode fault, because the invalid instruction is not
executed.
Vol. 3A
6-31
INTERRUPT AND EXCEPTION HANDLING
Interrupt 7-Device Not Available Exception (#NM)
Exception Class
Fault.
Description
Indicates one of the following things:
The device-not-available exception is generated by either of three conditions:
• The processor executed an x87 FPU floating-point instruction while the EM flag in control register CR0 was set
(1). See the paragraph below for the special case of the WAIT/FWAIT instruction.
• The processor executed a WAIT/FWAIT instruction while the MP and TS flags of register CR0 were set,
regardless of the setting of the EM flag.
• The processor executed an x87 FPU, MMX, or SSE/SSE2/SSE3 instruction (with the exception of MOVNTI,
PAUSE, PREFETCHh, SFENCE, LFENCE, MFENCE, and CLFLUSH) while the TS flag in control register CR0 was set
and the EM flag is clear.
The EM flag is set when the processor does not have an internal x87 FPU floating-point unit. A device-not-available
exception is then generated each time an x87 FPU floating-point instruction is encountered, allowing an exception
handler to call floating-point instruction emulation routines.
The TS flag indicates that a context switch (task switch) has occurred since the last time an x87 floating-point,
MMX, or SSE/SSE2/SSE3 instruction was executed; but that the context of the x87 FPU, XMM, and MXCSR registers
were not saved. When the TS flag is set and the EM flag is clear, the processor generates a device-not-available
exception each time an x87 floating-point, MMX, or SSE/SSE2/SSE3 instruction is encountered (with the exception
of the instructions listed above). The exception handler can then save the context of the x87 FPU, XMM, and MXCSR
registers before it executes the instruction. See Section 2.5, “Control Registers,” for more information about the TS
flag.
The MP flag in control register CR0 is used along with the TS flag to determine if WAIT or FWAIT instructions should
generate a device-not-available exception. It extends the function of the TS flag to the WAIT and FWAIT instruc-
tions, giving the exception handler an opportunity to save the context of the x87 FPU before the WAIT or FWAIT
instruction is executed. The MP flag is provided primarily for use with the Intel 286 and Intel386 DX processors. For
programs running on the Pentium 4, Intel Xeon, P6 family, Pentium, or Intel486 DX processors, or the Intel 487 SX
coprocessors, the MP flag should always be set; for programs running on the Intel486 SX processor, the MP flag
should be clear.
Exception Error Code
None.
Saved Instruction Pointer
The saved contents of CS and EIP registers point to the floating-point instruction or the WAIT/FWAIT instruction
that generated the exception.
Program State Change
A program-state change does not accompany a device-not-available fault, because the instruction that generated
the exception is not executed.
If the EM flag is set, the exception handler can then read the floating-point instruction pointed to by the EIP and call
the appropriate emulation routine.
If the MP and TS flags are set or the TS flag alone is set, the exception handler can save the context of the x87 FPU,
clear the TS flag, and continue execution at the interrupted floating-point or WAIT/FWAIT instruction.
6-32
Vol. 3A
INTERRUPT AND EXCEPTION HANDLING
Interrupt 8-Double Fault Exception (#DF)
Exception Class
Abort.
Description
Indicates that the processor detected a second exception while calling an exception handler for a prior exception.
Normally, when the processor detects another exception while trying to call an exception handler, the two excep-
tions can be handled serially. If, however, the processor cannot handle them serially, it signals the double-fault
exception. To determine when two faults need to be signalled as a double fault, the processor divides the excep-
tions into three classes: benign exceptions, contributory exceptions, and page faults (see Table 6-4).
Table 6-4. Interrupt and Exception Classes
Class
Vector Number
Description
Benign Exceptions and Interrupts
1
Debug
2
NMI Interrupt
3
Breakpoint
4
Overflow
5
BOUND Range Exceeded
6
Invalid Opcode
7
Device Not Available
9
Coprocessor Segment Overrun
16
Floating-Point Error
17
Alignment Check
18
Machine Check
19
SIMD floating-point
All
INT n
All
INTR
Contributory Exceptions
0
Divide Error
10
Invalid TSS
11
Segment Not Present
12
Stack Fault
13
General Protection
21
Control Protection
Page Faults
14
Page Fault
20
Virtualization Exception
Table 6-5 shows the various combinations of exception classes that cause a double fault to be generated. A double-
fault exception falls in the abort class of exceptions. The program or task cannot be restarted or resumed. The
double-fault handler can be used to collect diagnostic information about the state of the machine and/or, when
possible, to shut the application and/or system down gracefully or restart the system.
Vol. 3A
6-33
INTERRUPT AND EXCEPTION HANDLING
A segment or page fault may be encountered while prefetching instructions; however, this behavior is outside the
domain of Table 6-5. Any further faults generated while the processor is attempting to transfer control to the appro-
priate fault handler could still lead to a double-fault sequence.
Table 6-5. Conditions for Generating a Double Fault
Second Exception
First Exception
Benign
Contributory
Page Fault
Benign
Handle Exceptions Serially
Handle Exceptions Serially
Handle Exceptions Serially
Contributory
Handle Exceptions Serially
Generate a Double Fault
Handle Exceptions Serially
Page Fault
Handle Exceptions Serially
Generate a Double Fault
Generate a Double Fault
Double Fault
Handle Exceptions Serially
Enter Shutdown Mode
Enter Shutdown Mode
If another contributory or page fault exception occurs while attempting to call the double-fault handler, the
processor enters shutdown mode. This mode is similar to the state following execution of an HLT instruction. In this
mode, the processor stops executing instructions until an NMI interrupt, SMI interrupt, hardware reset, or INIT# is
received. The processor generates a special bus cycle to indicate that it has entered shutdown mode. Software
designers may need to be aware of the response of hardware when it goes into shutdown mode. For example, hard-
ware may turn on an indicator light on the front panel, generate an NMI interrupt to record diagnostic information,
invoke reset initialization, generate an INIT initialization, or generate an SMI. If any events are pending during
shutdown, they will be handled after an wake event from shutdown is processed (for example, A20M# interrupts).
If a shutdown occurs while the processor is executing an NMI interrupt handler, then only a hardware reset can
restart the processor. Likewise, if the shutdown occurs while executing in SMM, a hardware reset must be used to
restart the processor.
Exception Error Code
Zero. The processor always pushes an error code of 0 onto the stack of the double-fault handler.
Saved Instruction Pointer
The saved contents of CS and EIP registers are undefined.
Program State Change
A program-state following a double-fault exception is undefined. The program or task cannot be resumed or
restarted. The only available action of the double-fault exception handler is to collect all possible context informa-
tion for use in diagnostics and then close the application and/or shut down or reset the processor.
If the double fault occurs when any portion of the exception handling machine state is corrupted, the handler
cannot be invoked and the processor must be reset.
6-34
Vol. 3A
INTERRUPT AND EXCEPTION HANDLING
Interrupt 9-Coprocessor Segment Overrun
Exception Class
Abort. (Intel reserved; do not use. Recent IA-32 processors do not generate this
exception.)
Description
Indicates that an Intel386 CPU-based systems with an Intel 387 math coprocessor detected a page or segment
violation while transferring the middle portion of an Intel 387 math coprocessor operand. The P6 family, Pentium,
and Intel486 processors do not generate this exception; instead, this condition is detected with a general protec-
tion exception (#GP), interrupt 13.
Exception Error Code
None.
Saved Instruction Pointer
The saved contents of CS and EIP registers point to the instruction that generated the exception.
Program State Change
A program-state following a coprocessor segment-overrun exception is undefined. The program or task cannot
be resumed or restarted. The only available action of the exception handler is to save the instruction pointer and
reinitialize the x87 FPU using the FNINIT instruction.
Vol. 3A
6-35
INTERRUPT AND EXCEPTION HANDLING
Interrupt 10-Invalid TSS Exception (#TS)
Exception Class
Fault.
Description
Indicates that there was an error related to a TSS. Such an error might be detected during a task switch or during
the execution of instructions that use information from a TSS. Table 6-6 shows the conditions that cause an invalid
TSS exception to be generated.
Table 6-6. Invalid TSS Conditions
Error Code Index
Invalid Condition
TSS segment selector index
The TSS segment limit is less than 67H for 32-bit TSS or less than 2CH for 16-bit TSS.
TSS segment selector index
During an IRET task switch, the TI flag in the TSS segment selector indicates the LDT.
TSS segment selector index
During an IRET task switch, the TSS segment selector exceeds descriptor table limit.
TSS segment selector index
During an IRET task switch, the busy flag in the TSS descriptor indicates an inactive task.
TSS segment selector index
During a task switch, an attempt to access data in a TSS results in a limit violation or
canonical fault.
TSS segment selector index
During an IRET task switch, the backlink is a NULL selector.
TSS segment selector index
During an IRET task switch, the backlink points to a descriptor which is not a busy TSS.
TSS segment selector index
The new TSS descriptor is beyond the GDT limit.
TSS segment selector index
The new TSS selector is null on an attempt to lock the new TSS.
TSS segment selector index
The new TSS selector has the TI bit set on an attempt to lock the new TSS.
TSS segment selector index
The new TSS descriptor is not an available TSS descriptor on an attempt to lock the new
TSS.
LDT segment selector index
LDT not valid or not present.
Stack segment selector index
The stack segment selector exceeds descriptor table limit.
Stack segment selector index
The stack segment selector is NULL.
Stack segment selector index
The stack segment descriptor is a non-data segment.
Stack segment selector index
The stack segment is not writable.
Stack segment selector index
The stack segment DPL ≠ CPL.
Stack segment selector index
The stack segment selector RPL ≠ CPL.
Code segment selector index
The code segment selector exceeds descriptor table limit.
Code segment selector index
The code segment selector is NULL.
Code segment selector index
The code segment descriptor is not a code segment type.
Code segment selector index
The nonconforming code segment DPL ≠ CPL.
Code segment selector index
The conforming code segment DPL is greater than CPL.
Data segment selector index
The data segment selector exceeds the descriptor table limit.
Data segment selector index
The data segment descriptor is not a readable code or data type.
Data segment selector index
The data segment descriptor is a nonconforming code type and RPL > DPL.
Data segment selector index
The data segment descriptor is a nonconforming code type and CPL > DPL.
TSS segment selector index
The TSS segment descriptor/upper descriptor is beyond the GDT segment limit.
TSS segment selector index
The TSS segment descriptor is not an available TSS type.
TSS segment selector index
The TSS segment descriptor is an available 286 TSS type in IA-32e mode.
6-36
Vol. 3A
INTERRUPT AND EXCEPTION HANDLING
Table 6-6. Invalid TSS Conditions (Contd.)
Error Code Index
Invalid Condition
TSS segment selector index
The TSS segment upper descriptor is not the correct type.
TSS segment selector index
The TSS segment descriptor contains a non-canonical base.
This exception can generated either in the context of the original task or in the context of the new task (see Section
8.3, “Task Switching”). Until the processor has completely verified the presence of the new TSS, the exception is
generated in the context of the original task. Once the existence of the new TSS is verified, the task switch is
considered complete. Any invalid-TSS conditions detected after this point are handled in the context of the new
task. (A task switch is considered complete when the task register is loaded with the segment selector for the new
TSS and, if the switch is due to a procedure call or interrupt, the previous task link field of the new TSS references
the old TSS.)
The invalid-TSS handler must be a task called using a task gate. Handling this exception inside the faulting TSS
context is not recommended because the processor state may not be consistent.
Exception Error Code
An error code containing the segment selector index for the segment descriptor that caused the violation is pushed
onto the stack of the exception handler. If the EXT flag is set, it indicates that the exception was caused by an event
external to the currently running program (for example, if an external interrupt handler using a task gate
attempted a task switch to an invalid TSS).
Saved Instruction Pointer
If the exception condition was detected before the task switch was carried out, the saved contents of CS and EIP
registers point to the instruction that invoked the task switch. If the exception condition was detected after the task
switch was carried out, the saved contents of CS and EIP registers point to the first instruction of the new task.
Program State Change
The ability of the invalid-TSS handler to recover from the fault depends on the error condition than causes the fault.
See Section 8.3, “Task Switching,” for more information on the task switch process and the possible recovery
actions that can be taken.
If an invalid TSS exception occurs during a task switch, it can occur before or after the commit-to-new-task point.
If it occurs before the commit point, no program state change occurs. If it occurs after the commit point (when the
segment descriptor information for the new segment selectors have been loaded in the segment registers), the
processor will load all the state information from the new TSS before it generates the exception. During a task
switch, the processor first loads all the segment registers with segment selectors from the TSS, then checks their
contents for validity. If an invalid TSS exception is discovered, the remaining segment registers are loaded but not
checked for validity and therefore may not be usable for referencing memory. The invalid TSS handler should not
rely on being able to use the segment selectors found in the CS, SS, DS, ES, FS, and GS registers without causing
another exception. The exception handler should load all segment registers before trying to resume the new task;
otherwise, general-protection exceptions (#GP) may result later under conditions that make diagnosis more diffi-
cult. The Intel recommended way of dealing situation is to use a task for the invalid TSS exception handler. The task
switch back to the interrupted task from the invalid-TSS exception-handler task will then cause the processor to
check the registers as it loads them from the TSS.
Vol. 3A
6-37
INTERRUPT AND EXCEPTION HANDLING
Interrupt 11-Segment Not Present (#NP)
Exception Class
Fault.
Description
Indicates that the present flag of a segment or gate descriptor is clear. The processor can generate this exception
during any of the following operations:
• While attempting to load CS, DS, ES, FS, or GS registers. [Detection of a not-present segment while loading the
SS register causes a stack fault exception (#SS) to be generated.] This situation can occur while performing a
task switch.
• While attempting to load the LDTR using an LLDT instruction. Detection of a not-present LDT while loading the
LDTR during a task switch operation causes an invalid-TSS exception (#TS) to be generated.
• When executing the LTR instruction and the TSS is marked not present.
• While attempting to use a gate descriptor or TSS that is marked segment-not-present, but is otherwise valid.
An operating system typically uses the segment-not-present exception to implement virtual memory at the
segment level. If the exception handler loads the segment and returns, the interrupted program or task resumes
execution.
A not-present indication in a gate descriptor, however, does not indicate that a segment is not present (because
gates do not correspond to segments). The operating system may use the present flag for gate descriptors to
trigger exceptions of special significance to the operating system.
A contributory exception or page fault that subsequently referenced a not-present segment would cause a double
fault (#DF) to be generated instead of #NP.
Exception Error Code
An error code containing the segment selector index for the segment descriptor that caused the violation is pushed
onto the stack of the exception handler. If the EXT flag is set, it indicates that the exception resulted from either:
• an external event (NMI or INTR) that caused an interrupt, which subsequently referenced a not-present
segment
• a benign exception that subsequently referenced a not-present segment
The IDT flag is set if the error code refers to an IDT entry. This occurs when the IDT entry for an interrupt being
serviced references a not-present gate. Such an event could be generated by an INT instruction or a hardware
interrupt.
Saved Instruction Pointer
The saved contents of CS and EIP registers normally point to the instruction that generated the exception. If the
exception occurred while loading segment descriptors for the segment selectors in a new TSS, the CS and EIP
registers point to the first instruction in the new task. If the exception occurred while accessing a gate descriptor,
the CS and EIP registers point to the instruction that invoked the access (for example a CALL instruction that refer-
ences a call gate).
Program State Change
If the segment-not-present exception occurs as the result of loading a register (CS, DS, SS, ES, FS, GS, or LDTR),
a program-state change does accompany the exception because the register is not loaded. Recovery from this
exception is possible by simply loading the missing segment into memory and setting the present flag in the
segment descriptor.
If the segment-not-present exception occurs while accessing a gate descriptor, a program-state change does not
accompany the exception. Recovery from this exception is possible merely by setting the present flag in the gate
descriptor.
If a segment-not-present exception occurs during a task switch, it can occur before or after the commit-to-new-
task point (see Section 8.3, “Task Switching”). If it occurs before the commit point, no program state change
6-38
Vol. 3A
INTERRUPT AND EXCEPTION HANDLING
occurs. If it occurs after the commit point, the processor will load all the state information from the new TSS
(without performing any additional limit, present, or type checks) before it generates the exception. The segment-
not-present exception handler should not rely on being able to use the segment selectors found in the CS, SS, DS,
ES, FS, and GS registers without causing another exception. (See the Program State Change description for “Inter-
rupt 10-Invalid TSS Exception (#TS)” in this chapter for additional information on how to handle this situation.)
Vol. 3A
6-39
INTERRUPT AND EXCEPTION HANDLING
Interrupt 12-Stack Fault Exception (#SS)
Exception Class
Fault.
Description
Indicates that one of the following stack related conditions was detected:
• A limit violation is detected during an operation that refers to the SS register. Operations that can cause a limit
violation include stack-oriented instructions such as POP, PUSH, CALL, RET, IRET, ENTER, and LEAVE, as well as
other memory references which implicitly or explicitly use the SS register (for example, MOV AX, [BP+6] or
MOV AX, SS:[EAX+6]). The ENTER instruction generates this exception when there is not enough stack space
for allocating local variables.
• A not-present stack segment is detected when attempting to load the SS register. This violation can occur
during the execution of a task switch, a CALL instruction to a different privilege level, a return to a different
privilege level, an LSS instruction, or a MOV or POP instruction to the SS register.
• A canonical violation is detected in 64-bit mode during an operation that reference memory using the stack
pointer register containing a non-canonical memory address.
Recovery from this fault is possible by either extending the limit of the stack segment (in the case of a limit viola-
tion) or loading the missing stack segment into memory (in the case of a not-present violation.
In the case of a canonical violation that was caused intentionally by software, recovery is possible by loading the
correct canonical value into RSP. Otherwise, a canonical violation of the address in RSP likely reflects some register
corruption in the software.
Exception Error Code
If the exception is caused by a not-present stack segment or by overflow of the new stack during an inter-privilege-
level call, the error code contains a segment selector for the segment that caused the exception. Here, the excep-
tion handler can test the present flag in the segment descriptor pointed to by the segment selector to determine
the cause of the exception. For a normal limit violation (on a stack segment already in use) the error code is set to
0.
Saved Instruction Pointer
The saved contents of CS and EIP registers generally point to the instruction that generated the exception.
However, when the exception results from attempting to load a not-present stack segment during a task switch, the
CS and EIP registers point to the first instruction of the new task.
Program State Change
A program-state change does not generally accompany a stack-fault exception, because the instruction that gener-
ated the fault is not executed. Here, the instruction can be restarted after the exception handler has corrected the
stack fault condition.
If a stack fault occurs during a task switch, it occurs after the commit-to-new-task point (see Section 8.3, “Task
Switching”). Here, the processor loads all the state information from the new TSS (without performing any addi-
tional limit, present, or type checks) before it generates the exception. The stack fault handler should thus not rely
on being able to use the segment selectors found in the CS, SS, DS, ES, FS, and GS registers without causing
another exception. The exception handler should check all segment registers before trying to resume the new
task; otherwise, general protection faults may result later under conditions that are more difficult to diagnose. (See
the Program State Change description for “Interrupt 10-Invalid TSS Exception (#TS)” in this chapter for additional
information on how to handle this situation.)
6-40
Vol. 3A
INTERRUPT AND EXCEPTION HANDLING
Interrupt 13-General Protection Exception (#GP)
Exception Class
Fault.
Description
Indicates that the processor detected one of a class of protection violations called “general-protection violations.”
The conditions that cause this exception to be generated comprise all the protection violations that do not cause
other exceptions to be generated (such as, invalid-TSS, segment-not-present, stack-fault, or page-fault excep-
tions). The following conditions cause general-protection exceptions to be generated:
•
Exceeding the segment limit when accessing the CS, DS, ES, FS, or GS segments.
•
Exceeding the segment limit when referencing a descriptor table (except during a task switch or a stack
switch).
•
Transferring execution to a segment that is not executable.
•
Writing to a code segment or a read-only data segment.
•
Reading from an execute-only code segment.
•
Loading the SS register with a segment selector for a read-only segment (unless the selector comes from a TSS
during a task switch, in which case an invalid-TSS exception occurs).
•
Loading the SS, DS, ES, FS, or GS register with a segment selector for a system segment.
•
Loading the DS, ES, FS, or GS register with a segment selector for an execute-only code segment.
•
Loading the SS register with the segment selector of an executable segment or a null segment selector.
•
Loading the CS register with a segment selector for a data segment or a null segment selector.
•
Accessing memory using the DS, ES, FS, or GS register when it contains a null segment selector.
•
Switching to a busy task during a call or jump to a TSS.
•
Using a segment selector on a non-IRET task switch that points to a TSS descriptor in the current LDT. TSS
descriptors can only reside in the GDT. This condition causes a #TS exception during an IRET task switch.
•
Violating any of the privilege rules described in Chapter 5, “Protection.”
•
Exceeding the instruction length limit of 15 bytes (this only can occur when redundant prefixes are placed
before an instruction).
•
Loading the CR0 register with a set PG flag (paging enabled) and a clear PE flag (protection disabled).
•
Loading the CR0 register with a set NW flag and a clear CD flag.
•
Referencing an entry in the IDT (following an interrupt or exception) that is not an interrupt, trap, or task gate.
•
Attempting to access an interrupt or exception handler through an interrupt or trap gate from virtual-8086
mode when the handler’s code segment DPL is greater than 0.
•
Attempting to write a 1 into a reserved bit of CR4.
•
Attempting to execute a privileged instruction when the CPL is not equal to 0 (see Section 5.9, “Privileged
Instructions,” for a list of privileged instructions).
•
Attempting to execute SGDT, SIDT, SLDT, SMSW, or STR when CR4.UMIP = 1 and the CPL is not equal to 0.
•
Writing to a reserved bit in an MSR.
•
Accessing a gate that contains a null segment selector.
•
Executing the INT n instruction when the CPL is greater than the DPL of the referenced interrupt, trap, or task
gate.
•
The segment selector in a call, interrupt, or trap gate does not point to a code segment.
•
The segment selector operand in the LLDT instruction is a local type (TI flag is set) or does not point to a
segment descriptor of the LDT type.
•
The segment selector operand in the LTR instruction is local or points to a TSS that is not available.
•
The target code-segment selector for a call, jump, or return is null.
Vol. 3A
6-41
INTERRUPT AND EXCEPTION HANDLING
• If the PAE and/or PSE flag in control register CR4 is set and the processor detects any reserved bits in a page-
directory-pointer-table entry set to 1. These bits are checked during a write to control registers CR0, CR3, or
CR4 that causes a reloading of the page-directory-pointer-table entry.
• Attempting to write a non-zero value into the reserved bits of the MXCSR register.
• Executing an SSE/SSE2/SSE3 instruction that attempts to access a 128-bit memory location that is not aligned
on a 16-byte boundary when the instruction requires 16-byte alignment. This condition also applies to the stack
segment.
A program or task can be restarted following any general-protection exception. If the exception occurs while
attempting to call an interrupt handler, the interrupted program can be restartable, but the interrupt may be lost.
Exception Error Code
The processor pushes an error code onto the exception handler's stack. If the fault condition was detected while
loading a segment descriptor, the error code contains a segment selector to or IDT vector number for the
descriptor; otherwise, the error code is 0. The source of the selector in an error code may be any of the following:
• An operand of the instruction.
• A selector from a gate which is the operand of the instruction.
• A selector from a TSS involved in a task switch.
• IDT vector number.
Saved Instruction Pointer
The saved contents of CS and EIP registers point to the instruction that generated the exception.
Program State Change
In general, a program-state change does not accompany a general-protection exception, because the invalid
instruction or operation is not executed. An exception handler can be designed to correct all of the conditions that
cause general-protection exceptions and restart the program or task without any loss of program continuity.
If a general-protection exception occurs during a task switch, it can occur before or after the commit-to-new-task
point (see Section 8.3, “Task Switching”). If it occurs before the commit point, no program state change occurs. If
it occurs after the commit point, the processor will load all the state information from the new TSS (without
performing any additional limit, present, or type checks) before it generates the exception. The general-protection
exception handler should thus not rely on being able to use the segment selectors found in the CS, SS, DS, ES, FS,
and GS registers without causing another exception. (See the Program State Change description for “Interrupt
10-Invalid TSS Exception (#TS)” in this chapter for additional information on how to handle this situation.)
General Protection Exception in 64-bit Mode
The following conditions cause general-protection exceptions in 64-bit mode:
• If the memory address is in a non-canonical form.
• If a segment descriptor memory address is in non-canonical form.
• If the target offset in a destination operand of a call or jmp is in a non-canonical form.
• If a code segment or 64-bit call gate overlaps non-canonical space.
• If the code segment descriptor pointed to by the selector in the 64-bit gate doesn't have the L-bit set and the
D-bit clear.
• If the EFLAGS.NT bit is set in IRET.
• If the stack segment selector of IRET is null when going back to compatibility mode.
• If the stack segment selector of IRET is null going back to CPL3 and 64-bit mode.
• If a null stack segment selector RPL of IRET is not equal to CPL going back to non-CPL3 and 64-bit mode.
• If the proposed new code segment descriptor of IRET has both the D-bit and the L-bit set.
6-42
Vol. 3A
|
||
|
|
|