interrupts and system
play

Interrupts and System if (y) { //... y = 2 / x; Calls } - PDF document

2/18/13 Background: Control Flow pc // x = 2, y = true void printf(va_args) { Interrupts and System if (y) { //... y = 2 / x; Calls } printf(x); Don Porter } //... CSE 306 Regular control flow: branches and calls (logically


  1. 2/18/13 ¡ Background: Control Flow pc // x = 2, y = true void printf(va_args) { Interrupts and System if (y) { //... y = 2 / x; Calls } printf(x); Don Porter } //... CSE 306 Regular control flow: branches and calls (logically follows source code) Background: Control Flow Lecture goal ò Understand the hardware tools available for irregular pc // x = 0, y = true void handle_divzero() Divide by zero! control flow. { Program can’t make if (y) { progress! ò I.e., things other than a branch in a running program y = 2; y = 2 / x; ò Building blocks for context switching, device } management, etc. printf(x); } //... Irregular control flow: exceptions, system calls, etc. Two types of interrupts Asynchronous Example Stack Stack ò Synchronous: will happen every time an instruction executes (with a given program state) Disk ESP ESP Interrupt! ò Divide by zero ò System call ò Bad pointer dereference ò Asynchronous: caused by an external event EIP EIP if (x) { Disk_handler (){ printf(“Boo”); ò Usually device I/O ... ... } ò Timer ticks (well, clocks can be considered a device) printf(va_args…){ ... User Kernel 1 ¡

  2. 2/18/13 ¡ Intel nomenclature Lecture outline ò Interrupt – only refers to asynchronous interrupts ò Overview ò Exception – synchronous control transfer ò How interrupts work in hardware ò How interrupt handlers work in software ò Note: from the programmer’s perspective, these are ò How system calls work handled with the same abstractions ò New system call hardware on x86 Interrupt overview x86 interrupt table Device IRQs 128 = Linux ò Each interrupt or exception includes a number indicating System Call its type ò E.g., 14 is a page fault, 3 is a debug breakpoint … … … ò This number is the index into an interrupt table 0 31 47 255 Software Configurable Reserved for the CPU x86 interrupt overview Software interrupts ò Each type of interrupt is assigned an index from 0—255. ò The int <num> instruction allows software to raise an interrupt ò 0—31 are for processor interrupts; generally fixed by Intel ò 0x80 is just a Linux convention. ò E.g., 14 is always for page faults ò You could change it to use 0x81! ò 32—255 are software configured ò There are a lot of spare indices ò 32—47 are often for device interrupts (IRQs) ò You could have multiple system call tables for different Most device’s IRQ line can be configured ò purposes or types of processes! ò Look up APICs for more info (Ch 4 of Bovet and Cesati) ò Windows does: one for the kernel and one for win32k ò 0x80 issues system call in Linux (more on this later) 2 ¡

  3. 2/18/13 ¡ Software interrupts, cont What happens (generally): ò Control jumps to the kernel ò OS sets ring level required to raise an interrupt ò At a prescribed address (the interrupt handler) ò Generally, user programs can’t issue an int 14 (page ò The register state of the program is dumped on the kernel’s fault manually) stack ò An unauthorized int instruction causes a general protection fault ò Sometimes, extra info is loaded into CPU registers ò E.g., page faults store the address that caused the fault in the ò Interrupt 13 cr2 register ò Kernel code runs and handles the interrupt ò When handler completes, resume program (see iret instr.) How it works (HW) How is this configured? ò How does HW know what to execute? ò Kernel creates an array of Interrupt descriptors in memory, called Interrupt Descriptor Table, or IDT ò Where does the HW dump the registers; what does it use as the interrupt handler’s stack? ò Can be anywhere in physical memory ò Pointed to by special register ( idtr ) ò c.f., segment registers and gdtr and ldtr � ò Entry 0 configures interrupt 0, and so on x86 interrupt table x86 interrupt table idtr idtr … … … … … … 0 31 47 255 0 31 47 255 14 Code Segment: Kernel Code Segment Offset: &page_fault_handler //linear addr Ring: 0 // kernel Address of Interrupt Table Present: 1 Gate Type: Exception 3 ¡

  4. 2/18/13 ¡ Interrupt Descriptor x86 interrupt table idtr ò Code segment selector ò Almost always the same (kernel code segment) … … … ò Recall, this was designed before paging on x86! ò Segment offset of the code to run 0 3 31 47 255 ò Kernel segment is “flat”, so this is just the linear address ò Privilege Level (ring) ò Interrupts can be sent directly to user code. Why? Code Segment: Kernel Code Segment Offset: &breakpoint_handler //linear addr ò Present bit – disable unused interrupts Ring: 3 // user ò Gate type (interrupt or trap/exception) – more in a bit Present: 1 Gate Type: Exception Interrupt Descriptors, ctd. How it works (HW) ò In-memory layout is a bit confusing ò How does HW know what to execute? ò Like a lot of the x86 architecture, many interfaces were ò Interrupt descriptor table specifies what code to run and at later deprecated what privilege ò This can be set up once during boot for the whole system ò Where does the HW dump the registers; what does it use as the interrupt handler’s stack? ò Specified in the Task State Segment Task State Segment (TSS) TSS, cont. ò Another magic control block ò Simple model: specify a TSS for each process ò Pointed to by special task register (tr) ò Optimization (for a simple uniprocessor OS): ò Actually stored in the segment table (more on segmentation later) ò Why not just share one TSS and kernel stack per-process? ò Hardware-specified layout ò Linux generalization: ò Lots of fields for rarely-used features ò One TSS per CPU ò Two features we care about in a modern OS: ò Modify TSS fields as part of context switching ò 1) Location of kernel stack (fields ss0/esp0) ò 2) I/O Port privileges (more in a later lecture) 4 ¡

  5. 2/18/13 ¡ Summary Lecture outline ò Most interrupt handling hardware state set during boot ò Overview ò Each interrupt has an IDT entry specifying: ò How interrupts work in hardware ò What code to execute, privilege level to raise the interrupt ò How interrupt handlers work in software ò Stack to use specified in the TSS ò How system calls work ò New system call hardware on x86 Interrupt handlers Lecture outline ò Just plain old code in the kernel ò Overview ò Sort of like exception handlers in Java ò How interrupts work in hardware ò But separated from the control flow of the program ò How interrupt handlers work in software ò The IDT stores a pointer to the right handler routine ò How system calls work ò New system call hardware on x86 What is a system call? System call “interrupt” ò Originally, system calls issued using int instruction ò A function provided to applications by the OS kernel ò Dispatch routine was just an interrupt handler ò Generally to use a hardware abstraction (file, socket) ò Or OS-provided software abstraction (IPC, scheduling) ò Like interrupts, system calls are arranged in a table ò Why not put these directly in the application? ò See arch/x86/kernel/syscall_table*.S in Linux source ò Program selects the one it wants by placing index in eax ò Protection of the OS/hardware from buggy/malicious programs register ò Applications are not allowed to directly interact with ò Arguments go in the other registers by calling convention hardware, or access kernel data structures ò Return value goes in eax � 5 ¡

  6. 2/18/13 ¡ How many system calls? But why use interrupts? ò Also protection ò Linux exports about 350 system calls ò Forces applications to call well-defined “public” functions ò Windows exports about 400 system calls for core APIs, and another 800 for GUI methods ò Rather than calling arbitrary internal kernel functions ò Example: public foo() { if (!permission_ok()) return –EPERM; Calling _foo() directly would return _foo(); // no permission check circumvent } permission check Summary Lecture outline ò System calls are the “public” OS APIs ò Overview ò Kernel leverages interrupts to restrict applications to ò How interrupts work in hardware specific functions ò How interrupt handlers work in software ò Lab 1 hint: How to issue a Linux system call? ò How system calls work ò int $0x80 , with system call number in eax register ò New system call hardware on x86 Around P4 era… Idea ò Processors got very deeply pipelined ò What if we cache the IDT entry for a system call in a special CPU register? ò Pipeline stalls/flushes became very expensive ò No more cache misses for the IDT! ò Cache misses can cause pipeline stalls ò Maybe we can also do more optimizations ò System calls took twice as long from P3 to P4 ò Assumption: system calls are frequent enough to be ò Why? worth the transistor budget to implement this ò IDT entry may not be in the cache ò What else could you do with extra transistors that helps ò Different permissions constrain instruction reordering performance? 6 ¡

Download Presentation
Download Policy: The content available on the website is offered to you 'AS IS' for your personal information and use only. It cannot be commercialized, licensed, or distributed on other websites without prior consent from the author. To download a presentation, simply click this link. If you encounter any difficulties during the download process, it's possible that the publisher has removed the file from their server.

Recommend


More recommend