iommu/io-pgtable-arm: Add built time dependency
[cascardo/linux.git] / mm / mmap.c
index 7f684d5..da9990a 100644 (file)
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -152,7 +152,7 @@ EXPORT_SYMBOL_GPL(vm_memory_committed);
  */
 int __vm_enough_memory(struct mm_struct *mm, long pages, int cap_sys_admin)
 {
-       unsigned long free, allowed, reserve;
+       long free, allowed, reserve;
 
        VM_WARN_ONCE(percpu_counter_read(&vm_committed_as) <
                        -(s64)vm_committed_as_batch * num_online_cpus(),
@@ -220,7 +220,7 @@ int __vm_enough_memory(struct mm_struct *mm, long pages, int cap_sys_admin)
         */
        if (mm) {
                reserve = sysctl_user_reserve_kbytes >> (PAGE_SHIFT - 10);
-               allowed -= min(mm->total_vm / 32, reserve);
+               allowed -= min_t(long, mm->total_vm / 32, reserve);
        }
 
        if (percpu_counter_read_positive(&vm_committed_as) < allowed)
@@ -243,10 +243,7 @@ static void __remove_shared_vm_struct(struct vm_area_struct *vma,
                mapping_unmap_writable(mapping);
 
        flush_dcache_mmap_lock(mapping);
-       if (unlikely(vma->vm_flags & VM_NONLINEAR))
-               list_del_init(&vma->shared.nonlinear);
-       else
-               vma_interval_tree_remove(vma, &mapping->i_mmap);
+       vma_interval_tree_remove(vma, &mapping->i_mmap);
        flush_dcache_mmap_unlock(mapping);
 }
 
@@ -649,10 +646,7 @@ static void __vma_link_file(struct vm_area_struct *vma)
                        atomic_inc(&mapping->i_mmap_writable);
 
                flush_dcache_mmap_lock(mapping);
-               if (unlikely(vma->vm_flags & VM_NONLINEAR))
-                       vma_nonlinear_insert(vma, &mapping->i_mmap_nonlinear);
-               else
-                       vma_interval_tree_insert(vma, &mapping->i_mmap);
+               vma_interval_tree_insert(vma, &mapping->i_mmap);
                flush_dcache_mmap_unlock(mapping);
        }
 }
@@ -789,14 +783,11 @@ again:                    remove_next = 1 + (end > next->vm_end);
 
        if (file) {
                mapping = file->f_mapping;
-               if (!(vma->vm_flags & VM_NONLINEAR)) {
-                       root = &mapping->i_mmap;
-                       uprobe_munmap(vma, vma->vm_start, vma->vm_end);
+               root = &mapping->i_mmap;
+               uprobe_munmap(vma, vma->vm_start, vma->vm_end);
 
-                       if (adjust_next)
-                               uprobe_munmap(next, next->vm_start,
-                                                       next->vm_end);
-               }
+               if (adjust_next)
+                       uprobe_munmap(next, next->vm_start, next->vm_end);
 
                i_mmap_lock_write(mapping);
                if (insert) {
@@ -2634,6 +2625,75 @@ SYSCALL_DEFINE2(munmap, unsigned long, addr, size_t, len)
        return vm_munmap(addr, len);
 }
 
+
+/*
+ * Emulation of deprecated remap_file_pages() syscall.
+ */
+SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size,
+               unsigned long, prot, unsigned long, pgoff, unsigned long, flags)
+{
+
+       struct mm_struct *mm = current->mm;
+       struct vm_area_struct *vma;
+       unsigned long populate = 0;
+       unsigned long ret = -EINVAL;
+       struct file *file;
+
+       pr_warn_once("%s (%d) uses deprecated remap_file_pages() syscall. "
+                       "See Documentation/vm/remap_file_pages.txt.\n",
+                       current->comm, current->pid);
+
+       if (prot)
+               return ret;
+       start = start & PAGE_MASK;
+       size = size & PAGE_MASK;
+
+       if (start + size <= start)
+               return ret;
+
+       /* Does pgoff wrap? */
+       if (pgoff + (size >> PAGE_SHIFT) < pgoff)
+               return ret;
+
+       down_write(&mm->mmap_sem);
+       vma = find_vma(mm, start);
+
+       if (!vma || !(vma->vm_flags & VM_SHARED))
+               goto out;
+
+       if (start < vma->vm_start || start + size > vma->vm_end)
+               goto out;
+
+       if (pgoff == linear_page_index(vma, start)) {
+               ret = 0;
+               goto out;
+       }
+
+       prot |= vma->vm_flags & VM_READ ? PROT_READ : 0;
+       prot |= vma->vm_flags & VM_WRITE ? PROT_WRITE : 0;
+       prot |= vma->vm_flags & VM_EXEC ? PROT_EXEC : 0;
+
+       flags &= MAP_NONBLOCK;
+       flags |= MAP_SHARED | MAP_FIXED | MAP_POPULATE;
+       if (vma->vm_flags & VM_LOCKED) {
+               flags |= MAP_LOCKED;
+               /* drop PG_Mlocked flag for over-mapped range */
+               munlock_vma_pages_range(vma, start, start + size);
+       }
+
+       file = get_file(vma->vm_file);
+       ret = do_mmap_pgoff(vma->vm_file, start, size,
+                       prot, flags, pgoff, &populate);
+       fput(file);
+out:
+       up_write(&mm->mmap_sem);
+       if (populate)
+               mm_populate(ret, populate);
+       if (!IS_ERR_VALUE(ret))
+               ret = 0;
+       return ret;
+}
+
 static inline void verify_mm_writelocked(struct mm_struct *mm)
 {
 #ifdef CONFIG_DEBUG_VM
@@ -2791,9 +2851,6 @@ void exit_mmap(struct mm_struct *mm)
                vma = remove_vma(vma);
        }
        vm_unacct_memory(nr_accounted);
-
-       WARN_ON(atomic_long_read(&mm->nr_ptes) >
-                       (FIRST_USER_ADDRESS+PMD_SIZE-1)>>PMD_SHIFT);
 }
 
 /* Insert vm structure into process list sorted by address
@@ -3108,8 +3165,7 @@ static void vm_lock_mapping(struct mm_struct *mm, struct address_space *mapping)
  *
  * mmap_sem in write mode is required in order to block all operations
  * that could modify pagetables and free pages without need of
- * altering the vma layout (for example populate_range() with
- * nonlinear vmas). It's also needed in write mode to avoid new
+ * altering the vma layout. It's also needed in write mode to avoid new
  * anon_vmas to be associated with existing vmas.
  *
  * A single task can't take more than one mm_take_all_locks() in a row