*参照元 [#g449679e] #backlinks *説明 [#ae9ab168] -パス: [[linux-2.6.33/arch/arm/mm/fault.c]] -FIXME: これは何? --説明 **引数 [#c2583795] - -unsigned long addr -- -unsigned int fsr -- -struct pt_regs *regs -- --[[linux-2.6.33/pt_regs]] **返り値 [#o19a714e] - -int -- **参考 [#yae53746] *実装 [#q5f130b9] **MMU 有効の場合 [#rdd25210] #ifdef CONFIG_MMU (略) static int __kprobes do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs) { struct task_struct *tsk; struct mm_struct *mm; int fault, sig, code; - --[[linux-2.6.33/task_struct]] - --[[linux-2.6.33/mm_struct]] if (notify_page_fault(regs, fsr)) return 0; - --[[linux-2.6.33/notify_page_fault()]] tsk = current; mm = tsk->mm; - --[[linux-2.6.33/current(global)]] /* * If we're in an interrupt or have no user * context, we must not take the fault.. */ if (in_atomic() || !mm) goto no_context; - --[[linux-2.6.33/in_atomic()]] /* * As per x86, we may deadlock here. However, since the kernel only * validly references user space from well defined areas of the code, * we can bug out early if this is from code which shouldn't. */ if (!down_read_trylock(&mm->mmap_sem)) { if (!user_mode(regs) && !search_exception_tables(regs->ARM_pc)) goto no_context; down_read(&mm->mmap_sem); - --[[linux-2.6.33/down_read_trylock()]] - --[[linux-2.6.33/user_mode()]] - --[[linux-2.6.33/search_exception_tables()]] - --[[linux-2.6.33/down_read()]] } else { /* * The above down_read_trylock() might have succeeded in * which case, we'll have missed the might_sleep() from * down_read() */ might_sleep(); - --[[linux-2.6.33/might_sleep()]] #ifdef CONFIG_DEBUG_VM - --[[linux-2.6.33/CONFIG_DEBUG_VM]] if (!user_mode(regs) && !search_exception_tables(regs->ARM_pc)) goto no_context; #endif } fault = __do_page_fault(mm, addr, fsr, tsk); up_read(&mm->mmap_sem); - --[[linux-2.6.33/__do_page_fault()]] - --[[linux-2.6.33/up_read()]] /* * Handle the "normal" case first - VM_FAULT_MAJOR / VM_FAULT_MINOR */ if (likely(!(fault & (VM_FAULT_ERROR | VM_FAULT_BADMAP | VM_FAULT_BADACCESS)))) return 0; - --[[linux-2.6.33/likely()]] - --[[linux-2.6.33/VM_FAULT_ERROR]] - --[[linux-2.6.33/VM_FAULT_BADMAP]] - --[[linux-2.6.33/VM_FAULT_BADACCESS]] if (fault & VM_FAULT_OOM) { /* * We ran out of memory, call the OOM killer, and return to * userspace (which will retry the fault, or kill us if we * got oom-killed) */ pagefault_out_of_memory(); return 0; - --[[linux-2.6.33/VM_FAULT_OOM]] - --[[linux-2.6.33/pagefault_out_of_memory()]] } /* * If we are in kernel mode at this point, we * have no context to handle this fault with. */ if (!user_mode(regs)) goto no_context; if (fault & VM_FAULT_SIGBUS) { - --[[linux-2.6.33/VM_FAULT_SIGBUS]] /* * We had some memory, but were unable to * successfully fix up this page fault. */ sig = SIGBUS; code = BUS_ADRERR; - --[[linux-2.6.33/SIGBUS]] - --[[linux-2.6.33/BUS_ADRERR]] } else { /* * Something tried to access memory that * isn't in our memory map.. */ sig = SIGSEGV; code = fault == VM_FAULT_BADACCESS ? SEGV_ACCERR : SEGV_MAPERR; - --[[linux-2.6.33/SIGSEGV]] - --[[linux-2.6.33/VM_FAULT_BADACCESS]] - --[[linux-2.6.33/SEGV_ACCERR]] - --[[linux-2.6.33/SEGV_MAPERR]] } __do_user_fault(tsk, addr, fsr, sig, code, regs); return 0; - --[[linux-2.6.33/__do_user_fault()]] no_context: __do_kernel_fault(mm, addr, fsr, regs); return 0; - --[[linux-2.6.33/__do_kernel_fault()]] } **MMU 無効の場合 [#r0559ef1] #else /* CONFIG_MMU */ static int do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs) { return 0; -何もせず成功を返す。 } #endif /* CONFIG_MMU */ *コメント [#q7fd1e55]