Interrupt/Exception handling on the x86
Required reading: Chapter 5 (Interrupt and Exception handling)
The Intel IA32 interrupt/exception mechanism is designed so that code
running when the interrupt/exception occurs does not get to choose
arbitrarily where the kernel is entered and how.
- Kernel is only entered at a few specific well-defined entry-points which are
specified by the kernel itself
Sources of Exceptions/Interrupts
- Every exception/interrupt is given a number: its VECTOR
- 256 possible vector numbers
- vector determines what code invoked to handle interrupt.
- Hardware interrupts
- Occur essentially at random times, in response to signals from external hardware.
- The CPU generally uses interrupts to handle events external to the processor; particularly to
service peripherals.
+----------+ +--------+
| INTR|--------| PIC |---16 wires to devices
| NMI|--- | 8259A |
| CPU | +--------+
| |
+----------+
- NMI -- non-maskable interrupt -- signals hard failure
- INTR maskable -- eflags IF (one bit!!)
- IF 0 -- interrupts masked -- ie. ignored
- IF 1 -- interrupts "unmasked" -- ie. not ignored
- Software interrupts
- programmed interrupts: int $CODE
- JOS: uses these for system calls -- protected control transfers to the kernel from user processes.
- Software exception
- ex. movl %ebx,(%eax)
-- page fault or segmentation violation
if EAX contains an un-mapped virtual address
- ex. divl %eax,%eax
-- divide by zero exception if EAX is zero
- see insn set reference for each insn's possible expection
- Hardware exceptions
- New addition: Machine Check Exception
- Ex: bus errors, data parity errors, etc.
- Model specific extension.
PIC: Programmable Interrupt Controller
- mapping IRQ0-15 => into vector number
- vector = IRQ # + (programmable offset)
- vector is signaled over the INTR line
IDT: Interrupt Descriptor Table (pg 5-11)
- table of entries (8 bytes each)
- lidt instruction - tells CPU where in memory the table resides
and how big it is
- lidt instruction takes a linear address
- first 32 entries for processor exceptions
- any of the remaining 16 for hardware interrupts
- rest are for software interrupts (e.g., int $0x50)
IDT entry (pg 5-13)
- 8 bytes
- CS:EIP -- entry point of handler routine
- P -- 1 bit -- Does entry holds valid info?
- DPL -- 2 bits -- 0 for exception and external interrupts, 3 for software interrupts
- Type -- 4 bits -- task, trap, or interrupt gate
- Crazy format like GDT entries (recall SEG() macro)
- Interrupts gates -- clear IF bit of %eflags when used
- Trap gates -- don't change eflags when used
- Both clear TF, VM, RF, NT flags when used
- Example:
SETGATE (idt[IRQ_OFFSET + 0], /* vector */
0, /* istrap */
&_clock_interrupt, /* offset */
0); /* DPL */
TSS: Task State Segment
- Purpose: hardware supported multi-tasking => we don't use
- Resides in memory, must tell the CPU where:
- TSS descriptor goes in the GDT
- Contains the linear address and size of the TSS
- ltr (GD_TSS) loads the TSS descriptor into the CPU
- Only field relevant to this class:
- SS0:ESP0 -- kernel stack that processor switches to when a
interrupt/exeception happens in user mode.
- All other fields irrelevant to this class:
- Saved segment registers: GS, FS, DS, SS, CS, ES
- Saved general registers:EDI, ESI, EBP, ESP, EBX, EDX, ECX, EAX
- Other saved registers: EFLAGS, CR3
- Stack pointers for receiving calls or handling traps
at intermediate privilege levels:
SS1:ESP1, SS2:ESP2
Exception Entry Mechanism
- pg 5-16
- Like a procedure call (arguments on the stack)
- USER => KERNEL
- KERNEL => KERNEL
- why switch stacks (USER => KERNEL)?
- stack may be the cause of the fault
- triple faults cause CPU reset
- Motivation: save on stack if the registers themselves are changed
- notice: Kernel=>Kernel fault doesn't save SS:ESP.
why? because there is no stack switch (i.e., SS:ESP are not
overwritten)
- mention now or later??
- mode (user => kernel): CS -- bottom 2 bits are CPL
Exception Return Mechanism
iret -- top of stack should be old EIP
closer look at old EIP / Exception Types
- traps - old EIP -- points past instruction causing exception
- ex. int $3 -- software breakpoint trap
- faults - old EIP -- points to instruction causing exception
- ex. page faults, segmentation violations
- aborts - old EIP -- not certain -- serious problems - CPU is confused
Comparison to PDP11/40
- DEVICE INTERRUPTS
- x86: maskable by IF bit of EFLAGS; (and by the PIC)
- pdp: multiple priority levels
- DISPATCHING
- x86: IDT, which resides anywhere in memory
- pdp: dispatch table at fixed physical address
- DISPATCH ENTRY FORMAT
- x86: IDT entry -- contain CS:EIP
- pdp: trap;br7+0. -- entry point and new PSW
- MODE SWITCH
- x86: low two bits of CS hold CPL (11 -- kernel, 00 -- user)
- pdp: kernel vs user specified in PSW
- ADDRESSING SWITCH
- x86: no switch -
paging is not changed because %cr3 is not reloaded.
However, more of the VA space is accessible--notably
the KERNEL only VA regions
(this ignores segmentation since our convention
is to disable segmentation for the lab OS)
- pdp: complete switch:
kernel mode implicitely selects new set of segementation registers
- STACK SWITCH
- x86: new stack is: TSS ss0:esp0
- pdp: kernel mode -- implicitely uses kernel sp register