|
@@ -1517,6 +1517,8 @@ struct page *follow_page(struct vm_area_struct *vma, unsigned long address,
|
|
|
page = follow_huge_pmd(mm, address, pmd, flags & FOLL_WRITE);
|
|
|
goto out;
|
|
|
}
|
|
|
+ if ((flags & FOLL_NUMA) && pmd_numa(*pmd))
|
|
|
+ goto no_page_table;
|
|
|
if (pmd_trans_huge(*pmd)) {
|
|
|
if (flags & FOLL_SPLIT) {
|
|
|
split_huge_page_pmd(mm, pmd);
|
|
@@ -1546,6 +1548,8 @@ split_fallthrough:
|
|
|
pte = *ptep;
|
|
|
if (!pte_present(pte))
|
|
|
goto no_page;
|
|
|
+ if ((flags & FOLL_NUMA) && pte_numa(pte))
|
|
|
+ goto no_page;
|
|
|
if ((flags & FOLL_WRITE) && !pte_write(pte))
|
|
|
goto unlock;
|
|
|
|
|
@@ -1697,6 +1701,19 @@ int __get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
|
|
|
(VM_WRITE | VM_MAYWRITE) : (VM_READ | VM_MAYREAD);
|
|
|
vm_flags &= (gup_flags & FOLL_FORCE) ?
|
|
|
(VM_MAYREAD | VM_MAYWRITE) : (VM_READ | VM_WRITE);
|
|
|
+
|
|
|
+ /*
|
|
|
+ * If FOLL_FORCE and FOLL_NUMA are both set, handle_mm_fault
|
|
|
+ * would be called on PROT_NONE ranges. We must never invoke
|
|
|
+ * handle_mm_fault on PROT_NONE ranges or the NUMA hinting
|
|
|
+ * page faults would unprotect the PROT_NONE ranges if
|
|
|
+ * _PAGE_NUMA and _PAGE_PROTNONE are sharing the same pte/pmd
|
|
|
+ * bitflag. So to avoid that, don't set FOLL_NUMA if
|
|
|
+ * FOLL_FORCE is set.
|
|
|
+ */
|
|
|
+ if (!(gup_flags & FOLL_FORCE))
|
|
|
+ gup_flags |= FOLL_NUMA;
|
|
|
+
|
|
|
i = 0;
|
|
|
|
|
|
do {
|