*参照元 [#g449679e] #backlinks *説明 [#ae9ab168] -パス: [[linux-2.6.33/arch/arm/mm/fault.c]] -FIXME: これは何? --説明 **引数 [#c2583795] - -- **返り値 [#o19a714e] - -- **参考 [#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; if (notify_page_fault(regs, fsr)) return 0; tsk = current; mm = tsk->mm; /* * If we're in an interrupt or have no user * context, we must not take the fault.. */ if (in_atomic() || !mm) goto no_context; /* * 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); } else { /* * The above down_read_trylock() might have succeeded in * which case, we'll have missed the might_sleep() from * down_read() */ might_sleep(); #ifdef 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); /* * 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; 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; } /* * 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) { /* * We had some memory, but were unable to * successfully fix up this page fault. */ sig = SIGBUS; code = 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; } __do_user_fault(tsk, addr, fsr, sig, code, regs); return 0; no_context: __do_kernel_fault(mm, addr, fsr, regs); return 0; } **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]