aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorImre Deak <imre.deak@nokia.com>2009-10-05 08:40:44 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2009-10-05 12:55:55 -0400
commit1d2127123db9b1821959c2b8b7473dd7ffcdf527 (patch)
tree17134cbb3a6d7a077e5f05877964b1258d1f30c8
parente89e04fcdce6146cab3a34d4073f8a1714b457ec (diff)
ARM: 5742/1: ARM: add debug check for invalid kernel page faults
According to the following in arch/arm/mm/fault.c page faults from kernel mode are invalid if mmap_sem is already held and there is no exception handler defined for the faulting instruction: /* * 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; Since mmap_sem can be held at arbitrary times by another thread this also means that any page faults from kernel mode are invalid if no exception handler is defined for them, regardless whether mmap_sem is held at the time of fault. To easier detect code that can trigger the above error, add a check also for the case where mmap_sem is acquired. As this has an overhead make it a VM debug check. Signed-off-by: Imre Deak <imre.deak@nokia.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
-rw-r--r--arch/arm/mm/fault.c5
1 files changed, 5 insertions, 0 deletions
diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c
index ae0e25f5a70e..10e06801afb3 100644
--- a/arch/arm/mm/fault.c
+++ b/arch/arm/mm/fault.c
@@ -292,6 +292,11 @@ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
292 * down_read() 292 * down_read()
293 */ 293 */
294 might_sleep(); 294 might_sleep();
295#ifdef CONFIG_DEBUG_VM
296 if (!user_mode(regs) &&
297 !search_exception_tables(regs->ARM_pc))
298 goto no_context;
299#endif
295 } 300 }
296 301
297 fault = __do_page_fault(mm, addr, fsr, tsk); 302 fault = __do_page_fault(mm, addr, fsr, tsk);