diff options
| author | Jeff Garzik <jgarzik@pobox.com> | 2005-09-24 00:26:49 -0400 |
|---|---|---|
| committer | Jeff Garzik <jgarzik@pobox.com> | 2005-09-24 00:26:49 -0400 |
| commit | 98ed72deebfd2b55b7e1bb94c8175b1169999212 (patch) | |
| tree | f1682a68f65e0a38159f55a58c054779d749f8df /arch/arm/mm/fault.c | |
| parent | dbaa9a9d2b37d838125fb7f2b9fdc5dc5fa4eaa9 (diff) | |
| parent | 87e807b6c461bbd449496a4c3ab78ab164a4ba97 (diff) | |
Merge /spare/repo/linux-2.6/
Diffstat (limited to 'arch/arm/mm/fault.c')
| -rw-r--r-- | arch/arm/mm/fault.c | 12 |
1 files changed, 11 insertions, 1 deletions
diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c index 0b6c4db44e08..4a884baf3b9c 100644 --- a/arch/arm/mm/fault.c +++ b/arch/arm/mm/fault.c @@ -233,7 +233,17 @@ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs) if (in_interrupt() || !mm) goto no_context; - down_read(&mm->mmap_sem); + /* + * 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); + } + fault = __do_page_fault(mm, addr, fsr, tsk); up_read(&mm->mmap_sem); |
