summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKirill A. Shutemov <kirill@shutemov.name>2010-07-22 13:20:22 +0100
committerRussell King <rmk+kernel@arm.linux.org.uk>2010-07-27 10:48:41 +0100
commit33a9c41bf5d8adae9d882513e617c4c645195e71 (patch)
treeadcb4a60ff55f9b3f88eaeeca628f7398300121e
parent6338a6aa7c082f11d55712251e14178c68bf5869 (diff)
downloadlinux-3.10-33a9c41bf5d8adae9d882513e617c4c645195e71.tar.gz
linux-3.10-33a9c41bf5d8adae9d882513e617c4c645195e71.tar.bz2
linux-3.10-33a9c41bf5d8adae9d882513e617c4c645195e71.zip
ARM: 6255/1: Workaround infinity loop in handling of translation faults
On ARM one Linux PGD entry contains two hardware entries (see page tables layout in pgtable.h). We normally guarantee that we always fill both L1 entries. But create_mapping() doesn't follow the rule. It can create inidividual L1 entries, so here we have to call pmd_none() check in do_translation_fault() for the entry really corresponded to address, not for the first of pair. Signed-off-by: Kirill A. Shutemov <kirill@shutemov.name> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
-rw-r--r--arch/arm/mm/fault.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c
index 84131c83243..564b1c4829e 100644
--- a/arch/arm/mm/fault.c
+++ b/arch/arm/mm/fault.c
@@ -413,7 +413,16 @@ do_translation_fault(unsigned long addr, unsigned int fsr,
pmd_k = pmd_offset(pgd_k, addr);
pmd = pmd_offset(pgd, addr);
- if (pmd_none(*pmd_k))
+ /*
+ * On ARM one Linux PGD entry contains two hardware entries (see page
+ * tables layout in pgtable.h). We normally guarantee that we always
+ * fill both L1 entries. But create_mapping() doesn't follow the rule.
+ * It can create inidividual L1 entries, so here we have to call
+ * pmd_none() check for the entry really corresponded to address, not
+ * for the first of pair.
+ */
+ index = (addr >> SECTION_SHIFT) & 1;
+ if (pmd_none(pmd_k[index]))
goto bad_area;
copy_pmd(pmd, pmd_k);