aboutsummaryrefslogtreecommitdiffstats
path: root/mm/mprotect.c
diff options
context:
space:
mode:
authorJohannes Weiner <hannes@cmpxchg.org>2011-01-13 18:47:04 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2011-01-13 20:32:44 -0500
commitcd7548ab360c462118568eebb8c6da3bc303b02e (patch)
tree44d145e6139c8753659ee773ae35810dc3d92d0b /mm/mprotect.c
parentb36f5b0710e9e3b92484de32920fddcb17278664 (diff)
thp: mprotect: transparent huge page support
Natively handle huge pmds when changing page tables on behalf of mprotect(). I left out update_mmu_cache() because we do not need it on x86 anyway but more importantly the interface works on ptes, not pmds. Signed-off-by: Johannes Weiner <hannes@cmpxchg.org> Signed-off-by: Andrea Arcangeli <aarcange@redhat.com> Reviewed-by: Rik van Riel <riel@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm/mprotect.c')
-rw-r--r--mm/mprotect.c8
1 files changed, 7 insertions, 1 deletions
diff --git a/mm/mprotect.c b/mm/mprotect.c
index 9402080d0d4a..5a688a2756be 100644
--- a/mm/mprotect.c
+++ b/mm/mprotect.c
@@ -88,7 +88,13 @@ static inline void change_pmd_range(struct vm_area_struct *vma, pud_t *pud,
88 pmd = pmd_offset(pud, addr); 88 pmd = pmd_offset(pud, addr);
89 do { 89 do {
90 next = pmd_addr_end(addr, end); 90 next = pmd_addr_end(addr, end);
91 split_huge_page_pmd(vma->vm_mm, pmd); 91 if (pmd_trans_huge(*pmd)) {
92 if (next - addr != HPAGE_PMD_SIZE)
93 split_huge_page_pmd(vma->vm_mm, pmd);
94 else if (change_huge_pmd(vma, pmd, addr, newprot))
95 continue;
96 /* fall through */
97 }
92 if (pmd_none_or_clear_bad(pmd)) 98 if (pmd_none_or_clear_bad(pmd))
93 continue; 99 continue;
94 change_pte_range(vma->vm_mm, pmd, addr, next, newprot, 100 change_pte_range(vma->vm_mm, pmd, addr, next, newprot,