diff options
author | Russell King <rmk@dyn-67.arm.linux.org.uk> | 2005-09-20 17:52:13 +0100 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2005-09-20 17:52:13 +0100 |
commit | 840ff6a4f6174d7fe19c206b5f36ff64123a2f45 (patch) | |
tree | 1b66816135fad5a97d5ea0862b95341278f4227f | |
parent | 5fe10ab19046d84f3fd243436cbd5fa01019e809 (diff) | |
download | linux-3.10-840ff6a4f6174d7fe19c206b5f36ff64123a2f45.tar.gz linux-3.10-840ff6a4f6174d7fe19c206b5f36ff64123a2f45.tar.bz2 linux-3.10-840ff6a4f6174d7fe19c206b5f36ff64123a2f45.zip |
[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>
-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 0b6c4db44e0..4a884baf3b9 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); |