diff --git a/[refs] b/[refs] index 174c4e600f0d..242647702b8b 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 5fe10ab19046d84f3fd243436cbd5fa01019e809 +refs/heads/master: 840ff6a4f6174d7fe19c206b5f36ff64123a2f45 diff --git a/trunk/arch/arm/mm/fault.c b/trunk/arch/arm/mm/fault.c index 0b6c4db44e08..4a884baf3b9c 100644 --- a/trunk/arch/arm/mm/fault.c +++ b/trunk/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);