iii timer interrupts interrupt management
play

III. Timer Interrupts Interrupt Management Hardware timer interrupt - PowerPoint PPT Presentation

III. Timer Interrupts Interrupt Management Hardware timer interrupt can be set to expire after specified delay controller (time or instructions) interrupt when it does, control is passed back to the kernel Interrupt controllers implements


  1. III. Timer Interrupts Interrupt Management Hardware timer interrupt can be set to expire after specified delay controller (time or instructions) interrupt when it does, control is passed back to the kernel Interrupt controllers implements interrupt priorities: Other interrupts (e.g. I/O completion) also Interrupts include descriptor of interrupting device give control to kernel Priority selector circuit examines all interrupting devices, reports highest level to the CPU Controller can also buffer interrupts coming from different devices more on this later… Interrupt Management Types of Interrupts Exceptions interrupt controller process missteps (e.g. division by zero) interrupt attempt to perform a privileged instruction sometime on purpose! (breakpoints) System calls/traps Maskable interrupts synchronous/non-maskable user program requests can be turned off by the CPU for critical processing OS service Nonmaskable interrupts synchronous/non- Interrupts maskable indicate serious errors (power out warning, HW device requires OS service unrecoverable memory error, etc.) timer, I/O device, interprocessor asynchronous/maskable

  2. Interrupt Handling A Tale of Two Stack Pointers Interrupt is a program: it needs a stack! Two objectives so, each process has two stacks pointers: handle the interrupt and remove the cause one when running in kernel mode another when running in user mode restore what was running before the interrupt state may have been modified on purpose Why not using the user-level stack pointer? Two “actors” in handling the interrupt user SP may be badly aligned or pointing to non writable memory the hardware goes first user stack may not be large enough, and may spill to the kernel code takes control by running the overwrite important data interrupt handler security: kernel could leave sensitive data on stack pointing SP to kernel address could corrupt kernel Handling Interrupts: HW Handling Interrupts: SW On interrupt, hardware: We are now running the interrupt handler! sets supervisor mode (if not set already) IH first pushes the registers’ contents on the interrupt stack (part of the PCB) disable (masks) interrupts (partially privileged) need registers to run the IH kernel interrupts pushes PC, SP, and PSW Condition codes mode bit enabled bit only saves necessary registers (that’ s why done in of user program on interrupt stack SW, not HW) sets PC to point to the first instruction of the appropriate interrupt handler Interrupt Vector I/O interrupt handler depends on interrupt type System Call handler interrupt handler specified in Page fault handler interrupt vector loaded at boot time …

  3. Typical Interrupt Returning from an Handler Code Interrupt Hardware pops PC, SP, PSW HandleInterruptX: Depending on content of PSW PUSH %Rn } only need to save registers not switch to user mode … saved by the handler function enable interrupts PUSH %R1 From exception and system call, increment PC CALL _handleX on return (we don’ t want to execute again the POP %R1 } same instruction) … restore the registers saved above on exception, handler changes PC at the base of POP %Rn the stack RETURN_FROM_INTERRUPT on system call, increment is done by hw when saving user level state Interrupt Handling Starting a new process: on x86 the recipe User-level Registers Kernel Process Stack segment Offset 1. Allocate & initialize PCB Stack Code Code Code segment Offset SS:ESP pointer 2. Setup initial page table (to initialize a new address space) foo() { handler() { CS:EIP Program counter while(...) { pusha 3. Load program intro address space EFLAGS x = x+1; Flags ... y = y-2 4. Allocate user-level and kernel-level stacks. } Other } Registers: } 5.Copy arguments (if any) to the base of the user-level stack EAX, EBX, 6. Simulate an interrupt Stack ... Interrupt Stack a)push initial PC, user SP b)push PSW (supervisor mode off, interrupts enabled) 7.Clear all other registers 8.RETURN_FROM_INTERRUPT

  4. Interrupt Handling Interrupt Handling on x86 on x86 User-level User-level Registers Kernel Registers Kernel Process Process Code Stack Code Code Code SS:ESP SS:ESP pointer SS:ESP foo() { foo() { handler() { handler() { CS:EIP CS:EIP Program CS:EIP while(...) { counter while(...) { pusha pusha EFLAGS EFLAGS EFLAGS x = x+1; x = x+1; Flags ... ... y = y-2 y = y-2 } } Other Other } } SS:ESP CS:EIP Registers: Registers: } } EFLAGS EAX, EBX, EAX, EBX, ... ... Stack Interrupt Stack Stack Interrupt Stack Hardware performs these steps Hardware performs these steps 1. Change mode bit 1. Change mode bit 2. Disable interrupts 2. Disable interrupts 3. Save key registers to temporary location 3. Save key registers to temporary location 4. Switch onto the kernel interrupt stack 4. Switch onto the kernel interrupt stack 5. Push key registers onto new stack Interrupt Handling Interrupt Handling on x86 on x86 User-level User-level Registers Kernel Registers Kernel Process Process Code Code Code Code SS:ESP SS:ESP foo() { foo() { handler() { handler() { CS:EIP CS:EIP while(...) { while(...) { pusha pusha EFLAGS EFLAGS x = x+1; x = x+1; ... ... y = y-2 y = y-2 } } Other Other } } Registers: Registers: } } EAX, EBX, EAX, EBX, Stack ... Interrupt Stack Stack ... Interrupt Stack SS:ESP SS:ESP Hardware performs these steps Hardware performs these steps CS:EIP CS:EIP 1. Change mode bit EFLAGS 1. Change mode bit EFLAGS 2. Disable interrupts 2. Disable interrupts 3. Save key registers to temporary location 3. Save key registers to temporary location 4. Switch onto the kernel interrupt stack 4. Switch onto the kernel interrupt stack 5. Push key registers onto new stack 5. Push key registers onto new stack 6. Save error code (optional)

  5. Interrupt Handling Interrupt Handling on x86 on x86 User-level User-level Registers Kernel Registers Kernel Process Process Code Code Code Code SS:ESP SS:ESP foo() { foo() { handler() { handler() { CS:EIP CS:EIP while(...) { while(...) { pusha pusha EFLAGS EFLAGS x = x+1; x = x+1; ... ... y = y-2 y = y-2 } } Other Other } } Registers: Registers: } } EAX, EBX, EAX, EBX, ... ... Stack Interrupt Stack Stack Interrupt Stack SS:ESP SS:ESP Hardware performs these steps Hardware performs these steps CS:EIP CS:EIP 1. Change mode bit 1. Change mode bit EFLAGS EFLAGS 2. Disable interrupts 2. Disable interrupts Error Error 3. Save key registers to temporary location 3. Save key registers to temporary location 4. Switch onto the kernel interrupt stack 4. Switch onto the kernel interrupt stack 5. Push key registers onto new stack 5. Push key registers onto new stack Software (handler) performs this step 6. Save error code (optional) 6. Save error code (optional) 8. Handler pushes all registers on stack 7 . Transfer control to interrupt handler Interrupt Handling Interrupt Handling on x86 on x86 User-level User-level Registers Kernel Registers Kernel Process Process Code Code Code Code SS:ESP SS:ESP foo() { foo() { handler() { handler() { CS:EIP CS:EIP while(...) { while(...) { pusha pusha EFLAGS EFLAGS x = x+1; x = x+1; ... ... y = y-2 y = y-2 } } Other Other } } Registers: Registers: } } EAX, EBX, EAX, EBX, Stack ... Interrupt Stack Stack ... Interrupt Stack Hardware performs these steps Hardware performs these steps SS:ESP SS:ESP 1. Change mode bit 1. Change mode bit CS:EIP CS:EIP 2. Disable interrupts 2. Disable interrupts EFLAGS EFLAGS 3. Save key registers to temporary location 3. Save key registers to temporary location 4. Switch onto the kernel interrupt stack Error 4. Switch onto the kernel interrupt stack Error 5. Push key registers onto new stack 5. Push key registers onto new stack All Registers: 6. Save error code (optional) 6. Save error code (optional) SS, ESP, EAX, EBX,... 7 . Transfer control to interrupt handler 7 . Transfer control to interrupt handler Software (handler) performs this step Software (handler) performs this step 8. Handler pushes all registers on stack 8. Handler pushes all registers on stack

  6. Interrupt Safety Interrupt Race Example Kernel should disable device interrupts as little Disk interrupt handler enqueues a task to be as possible executed after a particular time interrupts are best serviced quickly while clock interrupts are enabled Thus, device interrupts are often disabled selectively Clock interrupt handler checks queue for tasks to be executed e.g., clock interrupts enabled during disk interrupt handling may remove tasks from the queue This leads to potential “race conditions” Clock interrupt may happen during enqueue system’ s behavior depends on timing of uncontrollable Concurrent access to a shared events data structure (the queue!) Making code Example of interrupt-safe Interrupt-Safe Code Make sure interrupts are disabled void enqueue(struct task *task) { while accessing mutable data! int level = interrupt_disable(); /* update queue */ But don’ t we have locks? interrupt_restore(level); Consider void function () } { lock(mtx); Why not simply re-enable interrupts? /* code */ unlock(mtx); Say we did. What if then we call enqueue from } code that expects interrupts to be disabled? Oops… Is function thread-safe? Is function interrupt-safe? Operates correctly when accessed Instead, remember interrupt level at time of call; Operates correctly when called again simultaneously by multiple threads (re-entered) before it completes when done, restore that level To make it so, grab a lock To make it so, disable interrupts

Recommend


More recommend