aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteve Capper <steve.capper@linaro.org>2013-05-17 07:32:55 -0400
committerSteve Capper <steve.capper@linaro.org>2013-06-04 11:52:37 -0400
commitdde1b65110353517816bcbc58539463396202244 (patch)
tree53521a163ffd1110ea6a22cb0a9c2b62fee1198e
parente4aa937ec75df0eea0bee03bffa3303ad36c986b (diff)
ARM: mm: correct pte_same behaviour for LPAE.
For 3 levels of paging the PTE_EXT_NG bit will be set for user address ptes that are written to a page table but not for ptes created with mk_pte. This can cause some comparison tests made by pte_same to fail spuriously and lead to other problems. To correct this behaviour, we mask off PTE_EXT_NG for any pte that is present before running the comparison. Signed-off-by: Steve Capper <steve.capper@linaro.org> Reviewed-by: Will Deacon <will.deacon@arm.com>
-rw-r--r--arch/arm/include/asm/pgtable-3level.h17
1 files changed, 17 insertions, 0 deletions
diff --git a/arch/arm/include/asm/pgtable-3level.h b/arch/arm/include/asm/pgtable-3level.h
index 86b8fe398b95..70f041cb50d1 100644
--- a/arch/arm/include/asm/pgtable-3level.h
+++ b/arch/arm/include/asm/pgtable-3level.h
@@ -166,6 +166,23 @@ static inline pmd_t *pmd_offset(pud_t *pud, unsigned long addr)
166 clean_pmd_entry(pmdp); \ 166 clean_pmd_entry(pmdp); \
167 } while (0) 167 } while (0)
168 168
169/*
170 * For 3 levels of paging the PTE_EXT_NG bit will be set for user address ptes
171 * that are written to a page table but not for ptes created with mk_pte.
172 *
173 * In hugetlb_no_page, a new huge pte (new_pte) is generated and passed to
174 * hugetlb_cow, where it is compared with an entry in a page table.
175 * This comparison test fails erroneously leading ultimately to a memory leak.
176 *
177 * To correct this behaviour, we mask off PTE_EXT_NG for any pte that is
178 * present before running the comparison.
179 */
180#define __HAVE_ARCH_PTE_SAME
181#define pte_same(pte_a,pte_b) ((pte_present(pte_a) ? pte_val(pte_a) & ~PTE_EXT_NG \
182 : pte_val(pte_a)) \
183 == (pte_present(pte_b) ? pte_val(pte_b) & ~PTE_EXT_NG \
184 : pte_val(pte_b)))
185
169#define set_pte_ext(ptep,pte,ext) cpu_set_pte_ext(ptep,__pte(pte_val(pte)|(ext))) 186#define set_pte_ext(ptep,pte,ext) cpu_set_pte_ext(ptep,__pte(pte_val(pte)|(ext)))
170 187
171#endif /* __ASSEMBLY__ */ 188#endif /* __ASSEMBLY__ */