Commit a7d6e4ecdb7648478ddec76d30d87d03d6e22b31

Authored by Andrea Arcangeli
Committed by Linus Torvalds
1 parent 09f586b35d

thp: prevent hugepages during args/env copying into the user stack

Transparent hugepages can only be created if rmap is fully
functional. So we must prevent hugepages to be created while
is_vma_temporary_stack() is true.

This also optmizes away some harmless but unnecessary setting of
khugepaged_scan.address and it switches some BUG_ON to VM_BUG_ON.

Signed-off-by: Andrea Arcangeli <aarcange@redhat.com>
Acked-by: Rik van Riel <riel@redhat.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

Showing 2 changed files with 18 additions and 20 deletions Side-by-side Diff

include/linux/huge_mm.h
... ... @@ -57,7 +57,8 @@
57 57 (transparent_hugepage_flags & \
58 58 (1<<TRANSPARENT_HUGEPAGE_REQ_MADV_FLAG) && \
59 59 ((__vma)->vm_flags & VM_HUGEPAGE))) && \
60   - !((__vma)->vm_flags & VM_NOHUGEPAGE))
  60 + !((__vma)->vm_flags & VM_NOHUGEPAGE) && \
  61 + !is_vma_temporary_stack(__vma))
61 62 #define transparent_hugepage_defrag(__vma) \
62 63 ((transparent_hugepage_flags & \
63 64 (1<<TRANSPARENT_HUGEPAGE_DEFRAG_FLAG)) || \
... ... @@ -1811,6 +1811,8 @@
1811 1811 /* VM_PFNMAP vmas may have vm_ops null but vm_file set */
1812 1812 if (!vma->anon_vma || vma->vm_ops || vma->vm_file)
1813 1813 goto out;
  1814 + if (is_vma_temporary_stack(vma))
  1815 + goto out;
1814 1816 VM_BUG_ON(is_linear_pfn_mapping(vma) || is_pfn_mapping(vma));
1815 1817  
1816 1818 pgd = pgd_offset(mm, address);
1817 1819  
1818 1820  
1819 1821  
1820 1822  
... ... @@ -2032,32 +2034,27 @@
2032 2034 if ((!(vma->vm_flags & VM_HUGEPAGE) &&
2033 2035 !khugepaged_always()) ||
2034 2036 (vma->vm_flags & VM_NOHUGEPAGE)) {
  2037 + skip:
2035 2038 progress++;
2036 2039 continue;
2037 2040 }
2038   -
2039 2041 /* VM_PFNMAP vmas may have vm_ops null but vm_file set */
2040   - if (!vma->anon_vma || vma->vm_ops || vma->vm_file) {
2041   - khugepaged_scan.address = vma->vm_end;
2042   - progress++;
2043   - continue;
2044   - }
  2042 + if (!vma->anon_vma || vma->vm_ops || vma->vm_file)
  2043 + goto skip;
  2044 + if (is_vma_temporary_stack(vma))
  2045 + goto skip;
  2046 +
2045 2047 VM_BUG_ON(is_linear_pfn_mapping(vma) || is_pfn_mapping(vma));
2046 2048  
2047 2049 hstart = (vma->vm_start + ~HPAGE_PMD_MASK) & HPAGE_PMD_MASK;
2048 2050 hend = vma->vm_end & HPAGE_PMD_MASK;
2049   - if (hstart >= hend) {
2050   - progress++;
2051   - continue;
2052   - }
  2051 + if (hstart >= hend)
  2052 + goto skip;
  2053 + if (khugepaged_scan.address > hend)
  2054 + goto skip;
2053 2055 if (khugepaged_scan.address < hstart)
2054 2056 khugepaged_scan.address = hstart;
2055   - if (khugepaged_scan.address > hend) {
2056   - khugepaged_scan.address = hend + HPAGE_PMD_SIZE;
2057   - progress++;
2058   - continue;
2059   - }
2060   - BUG_ON(khugepaged_scan.address & ~HPAGE_PMD_MASK);
  2057 + VM_BUG_ON(khugepaged_scan.address & ~HPAGE_PMD_MASK);
2061 2058  
2062 2059 while (khugepaged_scan.address < hend) {
2063 2060 int ret;
... ... @@ -2086,7 +2083,7 @@
2086 2083 breakouterloop_mmap_sem:
2087 2084  
2088 2085 spin_lock(&khugepaged_mm_lock);
2089   - BUG_ON(khugepaged_scan.mm_slot != mm_slot);
  2086 + VM_BUG_ON(khugepaged_scan.mm_slot != mm_slot);
2090 2087 /*
2091 2088 * Release the current mm_slot if this mm is about to die, or
2092 2089 * if we scanned all vmas of this mm.
2093 2090  
... ... @@ -2241,9 +2238,9 @@
2241 2238  
2242 2239 for (;;) {
2243 2240 mutex_unlock(&khugepaged_mutex);
2244   - BUG_ON(khugepaged_thread != current);
  2241 + VM_BUG_ON(khugepaged_thread != current);
2245 2242 khugepaged_loop();
2246   - BUG_ON(khugepaged_thread != current);
  2243 + VM_BUG_ON(khugepaged_thread != current);
2247 2244  
2248 2245 mutex_lock(&khugepaged_mutex);
2249 2246 if (!khugepaged_enabled())