Merge tag 'topic/iomem-mmap-vs-gup-2021-02-22' of git://anongit.freedesktop.org/drm/drm
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 23 Feb 2021 01:45:02 +0000 (17:45 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 23 Feb 2021 01:45:02 +0000 (17:45 -0800)
Pull follow_pfn() updates from Daniel Vetter:
 "Fixes around VM_FPNMAP and follow_pfn:

   - replace mm/frame_vector.c by get_user_pages in misc/habana and
     drm/exynos drivers, then move that into media as it's sole user

   - close race in generic_access_phys

   - s390 pci ioctl fix of this series landed in 5.11 already

   - properly revoke iomem mappings (/dev/mem, pci files)"

* tag 'topic/iomem-mmap-vs-gup-2021-02-22' of git://anongit.freedesktop.org/drm/drm:
  PCI: Revoke mappings like devmem
  PCI: Also set up legacy files only after sysfs init
  sysfs: Support zapping of binary attr mmaps
  resource: Move devmem revoke code to resource framework
  /dev/mem: Only set filp->f_mapping
  PCI: Obey iomem restrictions for procfs mmap
  mm: Close race in generic_access_phys
  media: videobuf2: Move frame_vector into media subsystem
  mm/frame-vector: Use FOLL_LONGTERM
  misc/habana: Use FOLL_LONGTERM for userptr
  misc/habana: Stop using frame_vector helpers
  drm/exynos: Use FOLL_LONGTERM for g2d cmdlists
  drm/exynos: Stop using frame_vector helpers

1  2 
drivers/char/mem.c
drivers/misc/habanalabs/common/habanalabs.h
drivers/misc/habanalabs/common/memory.c
include/linux/mm.h
mm/memory.c

Simple merge
Simple merge
diff --cc mm/memory.c
@@@ -4804,15 -4852,40 +4816,40 @@@ int generic_access_phys(struct vm_area_
        resource_size_t phys_addr;
        unsigned long prot = 0;
        void __iomem *maddr;
-       int offset = addr & (PAGE_SIZE-1);
+       pte_t *ptep, pte;
+       spinlock_t *ptl;
+       int offset = offset_in_page(addr);
+       int ret = -EINVAL;
+       if (!(vma->vm_flags & (VM_IO | VM_PFNMAP)))
+               return -EINVAL;
+ retry:
 -      if (follow_pte(vma->vm_mm, addr, NULL, &ptep, NULL, &ptl))
++      if (follow_pte(vma->vm_mm, addr, &ptep, &ptl))
+               return -EINVAL;
+       pte = *ptep;
+       pte_unmap_unlock(ptep, ptl);
  
-       if (follow_phys(vma, addr, write, &prot, &phys_addr))
+       prot = pgprot_val(pte_pgprot(pte));
+       phys_addr = (resource_size_t)pte_pfn(pte) << PAGE_SHIFT;
+       if ((write & FOLL_WRITE) && !pte_write(pte))
                return -EINVAL;
  
        maddr = ioremap_prot(phys_addr, PAGE_ALIGN(len + offset), prot);
        if (!maddr)
                return -ENOMEM;
  
 -      if (follow_pte(vma->vm_mm, addr, NULL, &ptep, NULL, &ptl))
++      if (follow_pte(vma->vm_mm, addr, &ptep, &ptl))
+               goto out_unmap;
+       if (!pte_same(pte, *ptep)) {
+               pte_unmap_unlock(ptep, ptl);
+               iounmap(maddr);
+               goto retry;
+       }
        if (write)
                memcpy_toio(maddr + offset, buf, len);
        else