x86/efi-bgrt: Switch all pr_err() to pr_notice() for invalid BGRT
[deliverable/linux.git] / mm / mmap.c
index 2f2415a7a688da595a996a01d0ae0e1f0f955454..bd2e1a533bc182a113523bd16b1af09e81a3c8ea 100644 (file)
--- a/mm/mmap.c
+++ b/mm/mmap.c
 #include <linux/khugepaged.h>
 #include <linux/uprobes.h>
 #include <linux/rbtree_augmented.h>
-#include <linux/sched/sysctl.h>
 #include <linux/notifier.h>
 #include <linux/memory.h>
 #include <linux/printk.h>
 #include <linux/userfaultfd_k.h>
 #include <linux/moduleparam.h>
+#include <linux/pkeys.h>
 
 #include <asm/uaccess.h>
 #include <asm/cacheflush.h>
@@ -123,130 +123,6 @@ void vma_set_page_prot(struct vm_area_struct *vma)
        }
 }
 
-
-int sysctl_overcommit_memory __read_mostly = OVERCOMMIT_GUESS;  /* heuristic overcommit */
-int sysctl_overcommit_ratio __read_mostly = 50;        /* default is 50% */
-unsigned long sysctl_overcommit_kbytes __read_mostly;
-int sysctl_max_map_count __read_mostly = DEFAULT_MAX_MAP_COUNT;
-unsigned long sysctl_user_reserve_kbytes __read_mostly = 1UL << 17; /* 128MB */
-unsigned long sysctl_admin_reserve_kbytes __read_mostly = 1UL << 13; /* 8MB */
-/*
- * Make sure vm_committed_as in one cacheline and not cacheline shared with
- * other variables. It can be updated by several CPUs frequently.
- */
-struct percpu_counter vm_committed_as ____cacheline_aligned_in_smp;
-
-/*
- * The global memory commitment made in the system can be a metric
- * that can be used to drive ballooning decisions when Linux is hosted
- * as a guest. On Hyper-V, the host implements a policy engine for dynamically
- * balancing memory across competing virtual machines that are hosted.
- * Several metrics drive this policy engine including the guest reported
- * memory commitment.
- */
-unsigned long vm_memory_committed(void)
-{
-       return percpu_counter_read_positive(&vm_committed_as);
-}
-EXPORT_SYMBOL_GPL(vm_memory_committed);
-
-/*
- * Check that a process has enough memory to allocate a new virtual
- * mapping. 0 means there is enough memory for the allocation to
- * succeed and -ENOMEM implies there is not.
- *
- * We currently support three overcommit policies, which are set via the
- * vm.overcommit_memory sysctl.  See Documentation/vm/overcommit-accounting
- *
- * Strict overcommit modes added 2002 Feb 26 by Alan Cox.
- * Additional code 2002 Jul 20 by Robert Love.
- *
- * cap_sys_admin is 1 if the process has admin privileges, 0 otherwise.
- *
- * Note this is a helper function intended to be used by LSMs which
- * wish to use this logic.
- */
-int __vm_enough_memory(struct mm_struct *mm, long pages, int cap_sys_admin)
-{
-       long free, allowed, reserve;
-
-       VM_WARN_ONCE(percpu_counter_read(&vm_committed_as) <
-                       -(s64)vm_committed_as_batch * num_online_cpus(),
-                       "memory commitment underflow");
-
-       vm_acct_memory(pages);
-
-       /*
-        * Sometimes we want to use more memory than we have
-        */
-       if (sysctl_overcommit_memory == OVERCOMMIT_ALWAYS)
-               return 0;
-
-       if (sysctl_overcommit_memory == OVERCOMMIT_GUESS) {
-               free = global_page_state(NR_FREE_PAGES);
-               free += global_page_state(NR_FILE_PAGES);
-
-               /*
-                * shmem pages shouldn't be counted as free in this
-                * case, they can't be purged, only swapped out, and
-                * that won't affect the overall amount of available
-                * memory in the system.
-                */
-               free -= global_page_state(NR_SHMEM);
-
-               free += get_nr_swap_pages();
-
-               /*
-                * Any slabs which are created with the
-                * SLAB_RECLAIM_ACCOUNT flag claim to have contents
-                * which are reclaimable, under pressure.  The dentry
-                * cache and most inode caches should fall into this
-                */
-               free += global_page_state(NR_SLAB_RECLAIMABLE);
-
-               /*
-                * Leave reserved pages. The pages are not for anonymous pages.
-                */
-               if (free <= totalreserve_pages)
-                       goto error;
-               else
-                       free -= totalreserve_pages;
-
-               /*
-                * Reserve some for root
-                */
-               if (!cap_sys_admin)
-                       free -= sysctl_admin_reserve_kbytes >> (PAGE_SHIFT - 10);
-
-               if (free > pages)
-                       return 0;
-
-               goto error;
-       }
-
-       allowed = vm_commit_limit();
-       /*
-        * Reserve some for root
-        */
-       if (!cap_sys_admin)
-               allowed -= sysctl_admin_reserve_kbytes >> (PAGE_SHIFT - 10);
-
-       /*
-        * Don't let a single process grow so big a user can't recover
-        */
-       if (mm) {
-               reserve = sysctl_user_reserve_kbytes >> (PAGE_SHIFT - 10);
-               allowed -= min_t(long, mm->total_vm / 32, reserve);
-       }
-
-       if (percpu_counter_read_positive(&vm_committed_as) < allowed)
-               return 0;
-error:
-       vm_unacct_memory(pages);
-
-       return -ENOMEM;
-}
-
 /*
  * Requires inode->i_mapping->i_mmap_rwsem
  */
@@ -1270,6 +1146,7 @@ unsigned long do_mmap(struct file *file, unsigned long addr,
                        unsigned long pgoff, unsigned long *populate)
 {
        struct mm_struct *mm = current->mm;
+       int pkey = 0;
 
        *populate = 0;
 
@@ -1309,11 +1186,17 @@ unsigned long do_mmap(struct file *file, unsigned long addr,
        if (offset_in_page(addr))
                return addr;
 
+       if (prot == PROT_EXEC) {
+               pkey = execute_only_pkey(mm);
+               if (pkey < 0)
+                       pkey = 0;
+       }
+
        /* Do simple checking here so the lower-level routines won't have
         * to. we assume access permissions have been handled by the open
         * of the memory object, so we don't do any here.
         */
-       vm_flags |= calc_vm_prot_bits(prot) | calc_vm_flag_bits(flags) |
+       vm_flags |= calc_vm_prot_bits(prot, pkey) | calc_vm_flag_bits(flags) |
                        mm->def_flags | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC;
 
        if (flags & MAP_LOCKED)
@@ -2642,9 +2525,8 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size,
        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);
+       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;
@@ -2664,12 +2546,29 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size,
        if (!vma || !(vma->vm_flags & VM_SHARED))
                goto out;
 
-       if (start < vma->vm_start || start + size > vma->vm_end)
+       if (start < vma->vm_start)
                goto out;
 
-       if (pgoff == linear_page_index(vma, start)) {
-               ret = 0;
-               goto out;
+       if (start + size > vma->vm_end) {
+               struct vm_area_struct *next;
+
+               for (next = vma->vm_next; next; next = next->vm_next) {
+                       /* hole between vmas ? */
+                       if (next->vm_start != next->vm_prev->vm_end)
+                               goto out;
+
+                       if (next->vm_file != vma->vm_file)
+                               goto out;
+
+                       if (next->vm_flags != vma->vm_flags)
+                               goto out;
+
+                       if (start + size <= next->vm_end)
+                               break;
+               }
+
+               if (!next)
+                       goto out;
        }
 
        prot |= vma->vm_flags & VM_READ ? PROT_READ : 0;
@@ -2679,9 +2578,16 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size,
        flags &= MAP_NONBLOCK;
        flags |= MAP_SHARED | MAP_FIXED | MAP_POPULATE;
        if (vma->vm_flags & VM_LOCKED) {
+               struct vm_area_struct *tmp;
                flags |= MAP_LOCKED;
+
                /* drop PG_Mlocked flag for over-mapped range */
-               munlock_vma_pages_range(vma, start, start + size);
+               for (tmp = vma; tmp->vm_start >= start + size;
+                               tmp = tmp->vm_next) {
+                       munlock_vma_pages_range(tmp,
+                                       max(tmp->vm_start, start),
+                                       min(tmp->vm_end, start + size));
+               }
        }
 
        file = get_file(vma->vm_file);
@@ -2986,8 +2892,7 @@ bool may_expand_vm(struct mm_struct *mm, vm_flags_t flags, unsigned long npages)
        if (is_data_mapping(flags) &&
            mm->data_vm + npages > rlimit(RLIMIT_DATA) >> PAGE_SHIFT) {
                if (ignore_rlimit_data)
-                       pr_warn_once("%s (%d): VmData %lu exceed data ulimit "
-                                    "%lu. Will be forbidden soon.\n",
+                       pr_warn_once("%s (%d): VmData %lu exceed data ulimit %lu. Will be forbidden soon.\n",
                                     current->comm, current->pid,
                                     (mm->data_vm + npages) << PAGE_SHIFT,
                                     rlimit(RLIMIT_DATA));
@@ -3042,11 +2947,16 @@ static int special_mapping_fault(struct vm_area_struct *vma,
        pgoff_t pgoff;
        struct page **pages;
 
-       if (vma->vm_ops == &legacy_special_mapping_vmops)
+       if (vma->vm_ops == &legacy_special_mapping_vmops) {
                pages = vma->vm_private_data;
-       else
-               pages = ((struct vm_special_mapping *)vma->vm_private_data)->
-                       pages;
+       } else {
+               struct vm_special_mapping *sm = vma->vm_private_data;
+
+               if (sm->fault)
+                       return sm->fault(sm, vma, vmf);
+
+               pages = sm->pages;
+       }
 
        for (pgoff = vmf->pgoff; pgoff && *pages; ++pages)
                pgoff--;
This page took 0.026485 seconds and 5 git commands to generate.