On Mon, 4 Jul 2005, [EMAIL PROTECTED] wrote: > in do_page_fault() (kernel 2.6.11.11) include one piece of code as > follow: > > > if (!down_read_trylock(&mm->mmap_sem)) { > if ((error_code & 4) == 0 && > !search_exception_tables(regs->eip)) > goto bad_area_nosemaphore; > down_read(&mm->mmap_sem); > } > > > I think I can understand these operations on mm->mmap_sem and > "error_code&4". > but how "search_exception_tables(regs->eip)" work here?
This is pretty much linker magic :-) Look at the code in copy_from_user and friends. It also gets quite confusing on intel. Down in the bowels you might get to a function/macro like __copy_user. This function is used to copy to and from a user space program address that we can't trust. Here you see three different linker sections: We start in the normal .text section " cmp $7,%0\n" \ " jbe 1f\n" \ " movl %1,%0\n" \ " negl %0\n" \ " andl $7,%0\n" \ " subl %0,%3\n" \ labels 4 and 0 store the address of a bad read (we are reading from a user address that might not be in memory either because it is swapped out, or is just a bad memory location. Can't trust those users ;-) "4: rep; movsb\n" \ " movl %3,%0\n" \ " shrl $2,%0\n" \ " andl $3,%3\n" \ " .align 2,0x90\n" \ "0: rep; movsl\n" \ " movl %3,%0\n" \ "1: rep; movsb\n" \ "2:\n" \ The fixup section is what to do if it was a bad read, that is, it's not swapped out, but the user sent us a bad address. ".section .fixup,\"ax\"\n" \ "5: addl %3,%0\n" \ " jmp 2b\n" \ "3: lea 0(%3,%0,4),%0\n" \ " jmp 2b\n" \ ".previous\n" \ This adds to the exception table. On error at address of label 4 we jump to label 5, on error at label 0 we jump to label 3 and so on. ".section __ex_table,\"a\"\n" \ " .align 4\n" \ " .long 4b,5b\n" \ " .long 0b,3b\n" \ " .long 1b,2b\n" \ The linker will put all sections of __ex_table together. The function you are wondering about "search_exception_tables" calls search_extable passing in the address of the start of the __ex_table section and the end of that section. Then, if it finds an address in the section, it then returns that entry of the table (the address,fixup pair). Later down in do_page_fault, fixup_exception is called, and this will again search the execption tables (this might be optimized better to do the search once!), and if it finds the entry, it will then jump to the fixup part of the code, and that will do what is expected if the user passed in a bad address. Hope this helps, -- Steve - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/