diff options
Diffstat (limited to 'mm/memory.c')
-rw-r--r-- | mm/memory.c | 17 |
1 files changed, 17 insertions, 0 deletions
diff --git a/mm/memory.c b/mm/memory.c index 7cf762857baa..cd8e0daf1912 100644 --- a/mm/memory.c +++ b/mm/memory.c | |||
@@ -1517,6 +1517,8 @@ struct page *follow_page(struct vm_area_struct *vma, unsigned long address, | |||
1517 | page = follow_huge_pmd(mm, address, pmd, flags & FOLL_WRITE); | 1517 | page = follow_huge_pmd(mm, address, pmd, flags & FOLL_WRITE); |
1518 | goto out; | 1518 | goto out; |
1519 | } | 1519 | } |
1520 | if ((flags & FOLL_NUMA) && pmd_numa(*pmd)) | ||
1521 | goto no_page_table; | ||
1520 | if (pmd_trans_huge(*pmd)) { | 1522 | if (pmd_trans_huge(*pmd)) { |
1521 | if (flags & FOLL_SPLIT) { | 1523 | if (flags & FOLL_SPLIT) { |
1522 | split_huge_page_pmd(mm, pmd); | 1524 | split_huge_page_pmd(mm, pmd); |
@@ -1546,6 +1548,8 @@ split_fallthrough: | |||
1546 | pte = *ptep; | 1548 | pte = *ptep; |
1547 | if (!pte_present(pte)) | 1549 | if (!pte_present(pte)) |
1548 | goto no_page; | 1550 | goto no_page; |
1551 | if ((flags & FOLL_NUMA) && pte_numa(pte)) | ||
1552 | goto no_page; | ||
1549 | if ((flags & FOLL_WRITE) && !pte_write(pte)) | 1553 | if ((flags & FOLL_WRITE) && !pte_write(pte)) |
1550 | goto unlock; | 1554 | goto unlock; |
1551 | 1555 | ||
@@ -1697,6 +1701,19 @@ int __get_user_pages(struct task_struct *tsk, struct mm_struct *mm, | |||
1697 | (VM_WRITE | VM_MAYWRITE) : (VM_READ | VM_MAYREAD); | 1701 | (VM_WRITE | VM_MAYWRITE) : (VM_READ | VM_MAYREAD); |
1698 | vm_flags &= (gup_flags & FOLL_FORCE) ? | 1702 | vm_flags &= (gup_flags & FOLL_FORCE) ? |
1699 | (VM_MAYREAD | VM_MAYWRITE) : (VM_READ | VM_WRITE); | 1703 | (VM_MAYREAD | VM_MAYWRITE) : (VM_READ | VM_WRITE); |
1704 | |||
1705 | /* | ||
1706 | * If FOLL_FORCE and FOLL_NUMA are both set, handle_mm_fault | ||
1707 | * would be called on PROT_NONE ranges. We must never invoke | ||
1708 | * handle_mm_fault on PROT_NONE ranges or the NUMA hinting | ||
1709 | * page faults would unprotect the PROT_NONE ranges if | ||
1710 | * _PAGE_NUMA and _PAGE_PROTNONE are sharing the same pte/pmd | ||
1711 | * bitflag. So to avoid that, don't set FOLL_NUMA if | ||
1712 | * FOLL_FORCE is set. | ||
1713 | */ | ||
1714 | if (!(gup_flags & FOLL_FORCE)) | ||
1715 | gup_flags |= FOLL_NUMA; | ||
1716 | |||
1700 | i = 0; | 1717 | i = 0; |
1701 | 1718 | ||
1702 | do { | 1719 | do { |