diff options
author | Andrea Arcangeli <aarcange@redhat.com> | 2011-01-13 18:46:54 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-01-13 20:32:42 -0500 |
commit | f66055ab6fb9731dbfce320c5202ef4441b5d77f (patch) | |
tree | de347e42d1e5cf481344a153d272e86a95b774f4 | |
parent | 05759d380a9d7f131a475186c07fce58ceaa8902 (diff) |
thp: verify pmd_trans_huge isn't leaking
pte_trans_huge must not leak in certain vmas like the mmio special pfn or
filebacked mappings.
Signed-off-by: Andrea Arcangeli <aarcange@redhat.com>
Acked-by: Rik van Riel <riel@redhat.com>
Acked-by: Mel Gorman <mel@csn.ul.ie>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | mm/memory.c | 7 |
1 files changed, 6 insertions, 1 deletions
diff --git a/mm/memory.c b/mm/memory.c index 840ce9d98f8b..c1a80e00458d 100644 --- a/mm/memory.c +++ b/mm/memory.c | |||
@@ -1451,6 +1451,7 @@ int __get_user_pages(struct task_struct *tsk, struct mm_struct *mm, | |||
1451 | pmd = pmd_offset(pud, pg); | 1451 | pmd = pmd_offset(pud, pg); |
1452 | if (pmd_none(*pmd)) | 1452 | if (pmd_none(*pmd)) |
1453 | return i ? : -EFAULT; | 1453 | return i ? : -EFAULT; |
1454 | VM_BUG_ON(pmd_trans_huge(*pmd)); | ||
1454 | pte = pte_offset_map(pmd, pg); | 1455 | pte = pte_offset_map(pmd, pg); |
1455 | if (pte_none(*pte)) { | 1456 | if (pte_none(*pte)) { |
1456 | pte_unmap(pte); | 1457 | pte_unmap(pte); |
@@ -1675,8 +1676,10 @@ pte_t *__get_locked_pte(struct mm_struct *mm, unsigned long addr, | |||
1675 | pud_t * pud = pud_alloc(mm, pgd, addr); | 1676 | pud_t * pud = pud_alloc(mm, pgd, addr); |
1676 | if (pud) { | 1677 | if (pud) { |
1677 | pmd_t * pmd = pmd_alloc(mm, pud, addr); | 1678 | pmd_t * pmd = pmd_alloc(mm, pud, addr); |
1678 | if (pmd) | 1679 | if (pmd) { |
1680 | VM_BUG_ON(pmd_trans_huge(*pmd)); | ||
1679 | return pte_alloc_map_lock(mm, pmd, addr, ptl); | 1681 | return pte_alloc_map_lock(mm, pmd, addr, ptl); |
1682 | } | ||
1680 | } | 1683 | } |
1681 | return NULL; | 1684 | return NULL; |
1682 | } | 1685 | } |
@@ -1895,6 +1898,7 @@ static inline int remap_pmd_range(struct mm_struct *mm, pud_t *pud, | |||
1895 | pmd = pmd_alloc(mm, pud, addr); | 1898 | pmd = pmd_alloc(mm, pud, addr); |
1896 | if (!pmd) | 1899 | if (!pmd) |
1897 | return -ENOMEM; | 1900 | return -ENOMEM; |
1901 | VM_BUG_ON(pmd_trans_huge(*pmd)); | ||
1898 | do { | 1902 | do { |
1899 | next = pmd_addr_end(addr, end); | 1903 | next = pmd_addr_end(addr, end); |
1900 | if (remap_pte_range(mm, pmd, addr, next, | 1904 | if (remap_pte_range(mm, pmd, addr, next, |
@@ -3471,6 +3475,7 @@ static int __follow_pte(struct mm_struct *mm, unsigned long address, | |||
3471 | goto out; | 3475 | goto out; |
3472 | 3476 | ||
3473 | pmd = pmd_offset(pud, address); | 3477 | pmd = pmd_offset(pud, address); |
3478 | VM_BUG_ON(pmd_trans_huge(*pmd)); | ||
3474 | if (pmd_none(*pmd) || unlikely(pmd_bad(*pmd))) | 3479 | if (pmd_none(*pmd) || unlikely(pmd_bad(*pmd))) |
3475 | goto out; | 3480 | goto out; |
3476 | 3481 | ||