Merge tag 'sound-fix-6.0-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai...
[linux-block.git] / mm / memory.c
index 1c6027adc5426b48f89e3e4e820e0c0144d5a579..4ba73f5aa8bb7771c584ac7097c66fba8222ddaa 100644 (file)
@@ -624,6 +624,14 @@ struct page *vm_normal_page(struct vm_area_struct *vma, unsigned long addr,
                if (is_zero_pfn(pfn))
                        return NULL;
                if (pte_devmap(pte))
+               /*
+                * NOTE: New users of ZONE_DEVICE will not set pte_devmap()
+                * and will have refcounts incremented on their struct pages
+                * when they are inserted into PTEs, thus they are safe to
+                * return here. Legacy ZONE_DEVICE pages that set pte_devmap()
+                * do not have refcounts. Example of legacy ZONE_DEVICE is
+                * MEMORY_DEVICE_FS_DAX type in pmem or virtio_fs drivers.
+                */
                        return NULL;
 
                print_bad_pte(vma, addr, pte, NULL);
@@ -736,7 +744,7 @@ static void restore_exclusive_pte(struct vm_area_struct *vma,
                 * Currently device exclusive access only supports anonymous
                 * memory so the entry shouldn't point to a filebacked page.
                 */
-               WARN_ON_ONCE(!PageAnon(page));
+               WARN_ON_ONCE(1);
 
        set_pte_at(vma->vm_mm, address, ptep, pte);
 
@@ -1245,7 +1253,7 @@ vma_needs_copy(struct vm_area_struct *dst_vma, struct vm_area_struct *src_vma)
        if (userfaultfd_wp(dst_vma))
                return true;
 
-       if (src_vma->vm_flags & (VM_HUGETLB | VM_PFNMAP | VM_MIXEDMAP))
+       if (src_vma->vm_flags & (VM_PFNMAP | VM_MIXEDMAP))
                return true;
 
        if (src_vma->anon_vma)
@@ -3020,7 +3028,7 @@ static vm_fault_t fault_dirty_shared_page(struct vm_fault *vmf)
                balance_dirty_pages_ratelimited(mapping);
                if (fpin) {
                        fput(fpin);
-                       return VM_FAULT_RETRY;
+                       return VM_FAULT_COMPLETED;
                }
        }
 
@@ -4434,10 +4442,6 @@ late_initcall(fault_around_debugfs);
  * It uses vm_ops->map_pages() to map the pages, which skips the page if it's
  * not ready to be mapped: not up-to-date, locked, etc.
  *
- * This function is called with the page table lock taken. In the split ptlock
- * case the page table lock only protects only those entries which belong to
- * the page table corresponding to the fault address.
- *
  * This function doesn't cross the VMA boundaries, in order to call map_pages()
  * only once.
  *
@@ -4696,7 +4700,7 @@ static vm_fault_t do_numa_page(struct vm_fault *vmf)
        pte = pte_modify(old_pte, vma->vm_page_prot);
 
        page = vm_normal_page(vma, vmf->address, pte);
-       if (!page)
+       if (!page || is_zone_device_page(page))
                goto out_map;
 
        /* TODO: handle PTE-mapped THP */
@@ -4966,6 +4970,7 @@ static vm_fault_t __handle_mm_fault(struct vm_area_struct *vma,
                .gfp_mask = __get_fault_gfp_mask(vma),
        };
        struct mm_struct *mm = vma->vm_mm;
+       unsigned long vm_flags = vma->vm_flags;
        pgd_t *pgd;
        p4d_t *p4d;
        vm_fault_t ret;
@@ -4979,7 +4984,8 @@ static vm_fault_t __handle_mm_fault(struct vm_area_struct *vma,
        if (!vmf.pud)
                return VM_FAULT_OOM;
 retry_pud:
-       if (pud_none(*vmf.pud) && __transparent_hugepage_enabled(vma)) {
+       if (pud_none(*vmf.pud) &&
+           hugepage_vma_check(vma, vm_flags, false, true)) {
                ret = create_huge_pud(&vmf);
                if (!(ret & VM_FAULT_FALLBACK))
                        return ret;
@@ -5012,7 +5018,8 @@ retry_pud:
        if (pud_trans_unstable(vmf.pud))
                goto retry_pud;
 
-       if (pmd_none(*vmf.pmd) && __transparent_hugepage_enabled(vma)) {
+       if (pmd_none(*vmf.pmd) &&
+           hugepage_vma_check(vma, vm_flags, false, true)) {
                ret = create_huge_pmd(&vmf);
                if (!(ret & VM_FAULT_FALLBACK))
                        return ret;