Merge branch 'akpm' (patches from Andrew)
Merge misc fixes from Andrew Morton: "2 fixes" * emailed patches from Andrew Morton <akpm@linux-foundation.org>: hugetlbfs: fix races and page leaks during migration kasan: turn off asan-stack for clang-8 and earlier
此提交包含在:
16
mm/hugetlb.c
16
mm/hugetlb.c
@@ -3624,7 +3624,6 @@ retry_avoidcopy:
|
||||
copy_user_huge_page(new_page, old_page, address, vma,
|
||||
pages_per_huge_page(h));
|
||||
__SetPageUptodate(new_page);
|
||||
set_page_huge_active(new_page);
|
||||
|
||||
mmu_notifier_range_init(&range, mm, haddr, haddr + huge_page_size(h));
|
||||
mmu_notifier_invalidate_range_start(&range);
|
||||
@@ -3645,6 +3644,7 @@ retry_avoidcopy:
|
||||
make_huge_pte(vma, new_page, 1));
|
||||
page_remove_rmap(old_page, true);
|
||||
hugepage_add_new_anon_rmap(new_page, vma, haddr);
|
||||
set_page_huge_active(new_page);
|
||||
/* Make the old page be freed below */
|
||||
new_page = old_page;
|
||||
}
|
||||
@@ -3729,6 +3729,7 @@ static vm_fault_t hugetlb_no_page(struct mm_struct *mm,
|
||||
pte_t new_pte;
|
||||
spinlock_t *ptl;
|
||||
unsigned long haddr = address & huge_page_mask(h);
|
||||
bool new_page = false;
|
||||
|
||||
/*
|
||||
* Currently, we are forced to kill the process in the event the
|
||||
@@ -3790,7 +3791,7 @@ retry:
|
||||
}
|
||||
clear_huge_page(page, address, pages_per_huge_page(h));
|
||||
__SetPageUptodate(page);
|
||||
set_page_huge_active(page);
|
||||
new_page = true;
|
||||
|
||||
if (vma->vm_flags & VM_MAYSHARE) {
|
||||
int err = huge_add_to_page_cache(page, mapping, idx);
|
||||
@@ -3861,6 +3862,15 @@ retry:
|
||||
}
|
||||
|
||||
spin_unlock(ptl);
|
||||
|
||||
/*
|
||||
* Only make newly allocated pages active. Existing pages found
|
||||
* in the pagecache could be !page_huge_active() if they have been
|
||||
* isolated for migration.
|
||||
*/
|
||||
if (new_page)
|
||||
set_page_huge_active(page);
|
||||
|
||||
unlock_page(page);
|
||||
out:
|
||||
return ret;
|
||||
@@ -4095,7 +4105,6 @@ int hugetlb_mcopy_atomic_pte(struct mm_struct *dst_mm,
|
||||
* the set_pte_at() write.
|
||||
*/
|
||||
__SetPageUptodate(page);
|
||||
set_page_huge_active(page);
|
||||
|
||||
mapping = dst_vma->vm_file->f_mapping;
|
||||
idx = vma_hugecache_offset(h, dst_vma, dst_addr);
|
||||
@@ -4163,6 +4172,7 @@ int hugetlb_mcopy_atomic_pte(struct mm_struct *dst_mm,
|
||||
update_mmu_cache(dst_vma, dst_addr, dst_pte);
|
||||
|
||||
spin_unlock(ptl);
|
||||
set_page_huge_active(page);
|
||||
if (vm_shared)
|
||||
unlock_page(page);
|
||||
ret = 0;
|
||||
|
11
mm/migrate.c
11
mm/migrate.c
@@ -1315,6 +1315,16 @@ static int unmap_and_move_huge_page(new_page_t get_new_page,
|
||||
lock_page(hpage);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check for pages which are in the process of being freed. Without
|
||||
* page_mapping() set, hugetlbfs specific move page routine will not
|
||||
* be called and we could leak usage counts for subpools.
|
||||
*/
|
||||
if (page_private(hpage) && !page_mapping(hpage)) {
|
||||
rc = -EBUSY;
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
if (PageAnon(hpage))
|
||||
anon_vma = page_get_anon_vma(hpage);
|
||||
|
||||
@@ -1345,6 +1355,7 @@ put_anon:
|
||||
put_new_page = NULL;
|
||||
}
|
||||
|
||||
out_unlock:
|
||||
unlock_page(hpage);
|
||||
out:
|
||||
if (rc != -EAGAIN)
|
||||
|
新增問題並參考
封鎖使用者