#[repr(C, align(16))]pub struct InterruptDescriptorTable {Show 25 fields
pub divide_error: Entry<unsafe extern "x86-interrupt" fn(_: InterruptStack)>,
pub debug: Entry<unsafe extern "x86-interrupt" fn(_: InterruptStack)>,
pub non_maskable_interrupt: Entry<unsafe extern "x86-interrupt" fn(_: InterruptStack)>,
pub breakpoint: Entry<unsafe extern "x86-interrupt" fn(_: InterruptStack)>,
pub overflow: Entry<unsafe extern "x86-interrupt" fn(_: InterruptStack)>,
pub bound_range_exceeded: Entry<unsafe extern "x86-interrupt" fn(_: InterruptStack)>,
pub invalid_opcode: Entry<unsafe extern "x86-interrupt" fn(_: InterruptStack)>,
pub device_not_available: Entry<unsafe extern "x86-interrupt" fn(_: InterruptStack)>,
pub double_fault: Entry<unsafe extern "x86-interrupt" fn(_: InterruptStack, error_code: u32) -> !>,
coprocessor_segment_overrun: Entry<unsafe extern "x86-interrupt" fn(_: InterruptStack)>,
pub invalid_tss: Entry<unsafe extern "x86-interrupt" fn(_: InterruptStack, error_code: u32)>,
pub segment_not_present: Entry<unsafe extern "x86-interrupt" fn(_: InterruptStack, error_code: u32)>,
pub stack_segment_fault: Entry<unsafe extern "x86-interrupt" fn(_: InterruptStack, error_code: u32)>,
pub general_protection_fault: Entry<unsafe extern "x86-interrupt" fn(_: InterruptStack, error_code: u32)>,
pub page_fault: Entry<unsafe extern "x86-interrupt" fn(_: InterruptStack, error_code: PageFaultError)>,
reserved_1: Entry<unsafe extern "x86-interrupt" fn(_: InterruptStack)>,
pub x87_floating_point: Entry<unsafe extern "x86-interrupt" fn(_: InterruptStack)>,
pub alignment_check: Entry<unsafe extern "x86-interrupt" fn(_: InterruptStack, error_code: u32)>,
pub machine_check: Entry<unsafe extern "x86-interrupt" fn(_: InterruptStack) -> !>,
pub simd_floating_point: Entry<unsafe extern "x86-interrupt" fn(_: InterruptStack)>,
pub virtualization: Entry<unsafe extern "x86-interrupt" fn(_: InterruptStack)>,
reserved_2: [Entry<unsafe extern "x86-interrupt" fn(_: InterruptStack)>; 9],
pub security_exception: Entry<unsafe extern "x86-interrupt" fn(_: InterruptStack, error_code: u32)>,
reserved_3: Entry<unsafe extern "x86-interrupt" fn(_: InterruptStack)>,
interrupts: [Entry<unsafe extern "x86-interrupt" fn(_: InterruptStack)>; 224],
}
Expand description
An Interrupt Descriptor Table with 256 entries.
The first 32 entries are used for CPU exceptions. These entries can be either accessed through
fields on this struct or through an index operation, e.g. idt[0]
returns the
first entry, the entry for the divide_error
exception. Note that the index access is
not possible for entries for which an error code is pushed.
The remaining entries are used for interrupts. They can be accesed through index
operations on the idt, e.g. idt[32]
returns the first interrupt entry, which is the 32nd IDT
entry).
The field descriptions are taken from the AMD64 manual volume 2 (with slight modifications).
Fields§
§divide_error: Entry<unsafe extern "x86-interrupt" fn(_: InterruptStack)>
A divide error (#DE
) occurs when the denominator of a DIV instruction or
an IDIV instruction is 0. A #DE
also occurs if the result is too large to be
represented in the destination.
The saved instruction pointer points to the instruction that caused the #DE
.
The vector number of the #DE
exception is 0.
debug: Entry<unsafe extern "x86-interrupt" fn(_: InterruptStack)>
When the debug-exception mechanism is enabled, a #DB
exception can occur under any
of the following circumstances:
- Instruction execution.
- Instruction single stepping.
- Data read.
- Data write.
- I/O read.
- I/O write.
- Task switch.
- Debug-register access, or general detect fault (debug register access when DR7.GD=1).
- Executing the INT1 instruction (opcode 0F1h).
#DB
conditions are enabled and disabled using the debug-control register, DR7
and RFLAGS.TF
.
In the following cases, the saved instruction pointer points to the instruction that
caused the #DB
:
- Instruction execution.
- Invalid debug-register access, or general detect.
In all other cases, the instruction that caused the #DB
is completed, and the saved
instruction pointer points to the instruction after the one that caused the #DB
.
The vector number of the #DB
exception is 1.
non_maskable_interrupt: Entry<unsafe extern "x86-interrupt" fn(_: InterruptStack)>
An non maskable interrupt exception (NMI) occurs as a result of system logic signaling a non-maskable interrupt to the processor.
The processor recognizes an NMI at an instruction boundary. The saved instruction pointer points to the instruction immediately following the boundary where the NMI was recognized.
The vector number of the NMI exception is 2.
breakpoint: Entry<unsafe extern "x86-interrupt" fn(_: InterruptStack)>
A breakpoint (#BP
) exception occurs when an INT3
instruction is executed. The
INT3
is normally used by debug software to set instruction breakpoints by replacing
The saved instruction pointer points to the byte after the INT3
instruction.
The vector number of the #BP
exception is 3.
overflow: Entry<unsafe extern "x86-interrupt" fn(_: InterruptStack)>
An overflow exception (#OF
) occurs as a result of executing an INTO
instruction
while the overflow bit in RFLAGS
is set to 1.
The saved instruction pointer points to the instruction following the INTO
instruction that caused the #OF
.
The vector number of the #OF
exception is 4.
bound_range_exceeded: Entry<unsafe extern "x86-interrupt" fn(_: InterruptStack)>
A bound-range exception (#BR
) exception can occur as a result of executing
the BOUND
instruction. The BOUND
instruction compares an array index (first
operand) with the lower bounds and upper bounds of an array (second operand).
If the array index is not within the array boundary, the #BR
occurs.
The saved instruction pointer points to the BOUND
instruction that caused the #BR
.
The vector number of the #BR
exception is 5.
invalid_opcode: Entry<unsafe extern "x86-interrupt" fn(_: InterruptStack)>
An invalid opcode exception (#UD
) occurs when an attempt is made to execute an
invalid or undefined opcode. The validity of an opcode often depends on the
processor operating mode.
A `#UD` occurs under the following conditions:
- Execution of any reserved or undefined opcode in any mode.
- Execution of the
UD2
instruction. - Use of the
LOCK
prefix on an instruction that cannot be locked. - Use of the
LOCK
prefix on a lockable instruction with a non-memory target location. - Execution of an instruction with an invalid-operand type.
- Execution of the
SYSENTER
orSYSEXIT
instructions in long mode. - Execution of any of the following instructions in 64-bit mode:
AAA
,AAD
,AAM
,AAS
,BOUND
,CALL
(opcode 9A),DAA
,DAS
,DEC
,INC
,INTO
,JMP
(opcode EA),LDS
,LES
,POP
(DS
,ES
,SS
),POPA
,PUSH
(CS
,DS
,ES
,SS
),PUSHA
,SALC
. - Execution of the
ARPL
,LAR
,LLDT
,LSL
,LTR
,SLDT
,STR
,VERR
, orVERW
instructions when protected mode is not enabled, or when virtual-8086 mode is enabled. - Execution of any legacy SSE instruction when
CR4.OSFXSR
is cleared to 0. - Execution of any SSE instruction (uses
YMM
/XMM
registers), or 64-bit media instruction (usesMMXTM
registers) whenCR0.EM
= 1. - Execution of any SSE floating-point instruction (uses
YMM
/XMM
registers) that causes a numeric exception whenCR4.OSXMMEXCPT
= 0. - Use of the
DR4
orDR5
debug registers whenCR4.DE
= 1. - Execution of
RSM
when not inSMM
mode.
The saved instruction pointer points to the instruction that caused the #UD
.
The vector number of the #UD
exception is 6.
device_not_available: Entry<unsafe extern "x86-interrupt" fn(_: InterruptStack)>
A device not available exception (#NM
) occurs under any of the following conditions:
- An
FWAIT
/WAIT
instruction is executed whenCR0.MP=1
andCR0.TS=1
. - Any x87 instruction other than
FWAIT
is executed whenCR0.EM=1
. - Any x87 instruction is executed when
CR0.TS=1
. TheCR0.MP
bit controls whether theFWAIT
/WAIT
instruction causes an#NM
exception whenTS=1
. - Any 128-bit or 64-bit media instruction when
CR0.TS=1
.
The saved instruction pointer points to the instruction that caused the #NM
.
The vector number of the #NM
exception is 7.
double_fault: Entry<unsafe extern "x86-interrupt" fn(_: InterruptStack, error_code: u32) -> !>
A double fault (#DF
) exception can occur when a second exception occurs during
the handling of a prior (first) exception or interrupt handler.
Usually, the first and second exceptions can be handled sequentially without
resulting in a #DF
. In this case, the first exception is considered benign, as
it does not harm the ability of the processor to handle the second exception. In some
cases, however, the first exception adversely affects the ability of the processor to
handle the second exception. These exceptions contribute to the occurrence of a #DF
,
and are called contributory exceptions. The following exceptions are contributory:
- Invalid-TSS Exception
- Segment-Not-Present Exception
- Stack Exception
- General-Protection Exception
A double-fault exception occurs in the following cases:
- If a contributory exception is followed by another contributory exception.
- If a divide-by-zero exception is followed by a contributory exception.
- If a page fault is followed by another page fault or a contributory exception.
If a third interrupting event occurs while transferring control to the #DF
handler,
the processor shuts down.
The returned error code is always zero. The saved instruction pointer is undefined, and the program cannot be restarted.
The vector number of the #DF
exception is 8.
coprocessor_segment_overrun: Entry<unsafe extern "x86-interrupt" fn(_: InterruptStack)>
This interrupt vector is reserved. It is for a discontinued exception originally used by processors that supported external x87-instruction coprocessors. On those processors, the exception condition is caused by an invalid-segment or invalid-page access on an x87-instruction coprocessor-instruction operand. On current processors, this condition causes a general-protection exception to occur.
invalid_tss: Entry<unsafe extern "x86-interrupt" fn(_: InterruptStack, error_code: u32)>
An invalid TSS exception (#TS
) occurs only as a result of a control transfer through
a gate descriptor that results in an invalid stack-segment reference using an SS
selector in the TSS.
The returned error code is the SS
segment selector. The saved instruction pointer
points to the control-transfer instruction that caused the #TS
.
The vector number of the #TS
exception is 10.
segment_not_present: Entry<unsafe extern "x86-interrupt" fn(_: InterruptStack, error_code: u32)>
An segment-not-present exception (#NP
) occurs when an attempt is made to load a
segment or gate with a clear present bit.
The returned error code is the segment-selector index of the segment descriptor
causing the #NP
exception. The saved instruction pointer points to the instruction
that loaded the segment selector resulting in the #NP
.
The vector number of the #NP
exception is 11.
stack_segment_fault: Entry<unsafe extern "x86-interrupt" fn(_: InterruptStack, error_code: u32)>
An stack segment exception (#SS
) can occur in the following situations:
- Implied stack references in which the stack address is not in canonical
form. Implied stack references include all push and pop instructions, and any
instruction using
RSP
orRBP
as a base register. - Attempting to load a stack-segment selector that references a segment descriptor containing a clear present bit.
- Any stack access that fails the stack-limit check.
The returned error code depends on the cause of the #SS
. If the cause is a cleared
present bit, the error code is the corresponding segment selector. Otherwise, the
error code is zero. The saved instruction pointer points to the instruction that
caused the #SS
.
The vector number of the #NP
exception is 12.
general_protection_fault: Entry<unsafe extern "x86-interrupt" fn(_: InterruptStack, error_code: u32)>
A general protection fault (#GP
) can occur in various situations. Common causes include:
- Executing a privileged instruction while
CPL > 0
. - Writing a 1 into any register field that is reserved, must be zero (MBZ).
- Attempting to execute an SSE instruction specifying an unaligned memory operand.
- Loading a non-canonical base address into the
GDTR
orIDTR
. - Using WRMSR to write a read-only MSR.
- Any long-mode consistency-check violation.
The returned error code is a segment selector, if the cause of the #GP
is
segment-related, and zero otherwise. The saved instruction pointer points to
the instruction that caused the #GP
.
The vector number of the #GP
exception is 13.
page_fault: Entry<unsafe extern "x86-interrupt" fn(_: InterruptStack, error_code: PageFaultError)>
A page fault (#PF
) can occur during a memory access in any of the following situations:
- A page-translation-table entry or physical page involved in translating the memory access is not present in physical memory. This is indicated by a cleared present bit in the translation-table entry.
- An attempt is made by the processor to load the instruction TLB with a translation for a non-executable page.
- The memory access fails the paging-protection checks (user/supervisor, read/write, or both).
- A reserved bit in one of the page-translation-table entries is set to 1. A
#PF
occurs for this reason only whenCR4.PSE=1
orCR4.PAE=1
.
The virtual (linear) address that caused the #PF
is stored in the CR2
register.
The saved instruction pointer points to the instruction that caused the #PF
.
The page-fault error code is described by the
PageFaultErrorCode
struct.
The vector number of the #PF
exception is 14.
reserved_1: Entry<unsafe extern "x86-interrupt" fn(_: InterruptStack)>
vector nr. 15
x87_floating_point: Entry<unsafe extern "x86-interrupt" fn(_: InterruptStack)>
The x87 Floating-Point Exception-Pending exception (#MF
) is used to handle unmasked x87
floating-point exceptions. In 64-bit mode, the x87 floating point unit is not used
anymore, so this exception is only relevant when executing programs in the 32-bit
compatibility mode.
The vector number of the #MF
exception is 16.
alignment_check: Entry<unsafe extern "x86-interrupt" fn(_: InterruptStack, error_code: u32)>
An alignment check exception (#AC
) occurs when an unaligned-memory data reference
is performed while alignment checking is enabled. An #AC
can occur only when CPL=3.
The returned error code is always zero. The saved instruction pointer points to the
instruction that caused the #AC
.
The vector number of the #AC
exception is 17.
machine_check: Entry<unsafe extern "x86-interrupt" fn(_: InterruptStack) -> !>
The machine check exception (#MC
) is model specific. Processor implementations
are not required to support the #MC
exception, and those implementations that do
support #MC
can vary in how the #MC
exception mechanism works.
There is no reliable way to restart the program.
The vector number of the #MC
exception is 18.
simd_floating_point: Entry<unsafe extern "x86-interrupt" fn(_: InterruptStack)>
The SIMD Floating-Point Exception (#XF
) is used to handle unmasked SSE
floating-point exceptions. The SSE floating-point exceptions reported by
the #XF
exception are (including mnemonics):
- IE: Invalid-operation exception (also called #I).
- DE: Denormalized-operand exception (also called #D).
- ZE: Zero-divide exception (also called #Z).
- OE: Overflow exception (also called #O).
- UE: Underflow exception (also called #U).
- PE: Precision exception (also called #P or inexact-result exception).
The saved instruction pointer points to the instruction that caused the #XF
.
The vector number of the #XF
exception is 19.
virtualization: Entry<unsafe extern "x86-interrupt" fn(_: InterruptStack)>
vector nr. 20
reserved_2: [Entry<unsafe extern "x86-interrupt" fn(_: InterruptStack)>; 9]
vector nr. 21-29
security_exception: Entry<unsafe extern "x86-interrupt" fn(_: InterruptStack, error_code: u32)>
The Security Exception (#SX
) signals security-sensitive events that occur while
executing the VMM, in the form of an exception so that the VMM may take appropriate
action. (A VMM would typically intercept comparable sensitive events in the guest.)
In the current implementation, the only use of the #SX
is to redirect external INITs
into an exception so that the VMM may — among other possibilities.
The only error code currently defined is 1, and indicates redirection of INIT has occurred.
The vector number of the #SX
exception is 30.
reserved_3: Entry<unsafe extern "x86-interrupt" fn(_: InterruptStack)>
vector nr. 31
interrupts: [Entry<unsafe extern "x86-interrupt" fn(_: InterruptStack)>; 224]
User-defined interrupts can be initiated either by system logic or software. They occur when:
- System logic signals an external interrupt request to the processor. The signaling mechanism and the method of communicating the interrupt vector to the processor are implementation dependent.
- Software executes an
INTn
instruction. TheINTn
instruction operand provides the interrupt vector number.
Both methods can be used to initiate an interrupt into vectors 0 through 255. However, because vectors 0 through 31 are defined or reserved by the AMD64 architecture, software should not use vectors in this range for purposes other than their defined use.
The saved instruction pointer depends on the interrupt source:
- External interrupts are recognized on instruction boundaries. The saved instruction pointer points to the instruction immediately following the boundary where the external interrupt was recognized.
- If the interrupt occurs as a result of executing the INTn instruction, the saved instruction pointer points to the instruction after the INTn.
Implementations§
source§impl InterruptDescriptorTable
impl InterruptDescriptorTable
sourcepub fn new() -> InterruptDescriptorTable
pub fn new() -> InterruptDescriptorTable
Creates a new IDT filled with non-present entries.
sourcefn pointer(&self) -> DescriptorTablePointer
fn pointer(&self) -> DescriptorTablePointer
Creates the descriptor pointer for this table. This pointer can only be safely used if the table is never modified or destroyed while in use.
Trait Implementations§
source§impl Clone for InterruptDescriptorTable
impl Clone for InterruptDescriptorTable
source§fn clone(&self) -> InterruptDescriptorTable
fn clone(&self) -> InterruptDescriptorTable
1.0.0§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source
. Read moresource§impl Index<usize> for InterruptDescriptorTable
impl Index<usize> for InterruptDescriptorTable
source§fn index(&self, index: usize) -> &Self::Output
fn index(&self, index: usize) -> &Self::Output
Returns the IDT entry with the specified index.
Panics if index is outside the IDT (i.e. greater than 255) or if the entry is an exception that pushes an error code (use the struct fields for accessing these entries).
§type Output = Entry<unsafe extern "x86-interrupt" fn(_: InterruptStack)>
type Output = Entry<unsafe extern "x86-interrupt" fn(_: InterruptStack)>
source§impl IndexMut<usize> for InterruptDescriptorTable
impl IndexMut<usize> for InterruptDescriptorTable
source§fn index_mut(&mut self, index: usize) -> &mut Self::Output
fn index_mut(&mut self, index: usize) -> &mut Self::Output
Returns a mutable reference to the IDT entry with the specified index.
Panics if index is outside the IDT (i.e. greater than 255) or if the entry is an exception that pushes an error code (use the struct fields for accessing these entries).