aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mm
diff options
context:
space:
mode:
authorRussell King <rmk@dyn-67.arm.linux.org.uk>2005-09-20 12:52:13 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2005-09-20 12:52:13 -0400
commit840ff6a4f6174d7fe19c206b5f36ff64123a2f45 (patch)
tree1b66816135fad5a97d5ea0862b95341278f4227f /arch/arm/mm
parent5fe10ab19046d84f3fd243436cbd5fa01019e809 (diff)
[ARM] Prevent deadlock in page fault handler
As per x86, we may deadlock while trying to get the mmap semaphore. Implement the same fix, which allows (eg) recursive faults to cause an oops instead of deadlocking. Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/mm')
-rw-r--r--arch/arm/mm/fault.c12
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)
233 if (in_interrupt() || !mm) 233 if (in_interrupt() || !mm)
234 goto no_context; 234 goto no_context;
235 235
236 down_read(&mm->mmap_sem); 236 /*
237 * As per x86, we may deadlock here. However, since the kernel only
238 * validly references user space from well defined areas of the code,
239 * we can bug out early if this is from code which shouldn't.
240 */
241 if (!down_read_trylock(&mm->mmap_sem)) {
242 if (!user_mode(regs) && !search_exception_tables(regs->ARM_pc))
243 goto no_context;
244 down_read(&mm->mmap_sem);
245 }
246
237 fault = __do_page_fault(mm, addr, fsr, tsk); 247 fault = __do_page_fault(mm, addr, fsr, tsk);
238 up_read(&mm->mmap_sem); 248 up_read(&mm->mmap_sem);
239 249