Merge branch 'mm-pkeys-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
[sfrench/cifs-2.6.git] / mm / memory.c
index 906d8e3b42c000f0613638aa8a36c32ef1e62951..81dca0083fcd036877f30fde66a0168ade199030 100644 (file)
@@ -65,6 +65,7 @@
 #include <linux/userfaultfd_k.h>
 
 #include <asm/io.h>
+#include <asm/mmu_context.h>
 #include <asm/pgalloc.h>
 #include <asm/uaccess.h>
 #include <asm/tlb.h>
@@ -562,8 +563,7 @@ void free_pgtables(struct mmu_gather *tlb, struct vm_area_struct *vma,
        }
 }
 
-int __pte_alloc(struct mm_struct *mm, struct vm_area_struct *vma,
-               pmd_t *pmd, unsigned long address)
+int __pte_alloc(struct mm_struct *mm, pmd_t *pmd, unsigned long address)
 {
        spinlock_t *ptl;
        pgtable_t new = pte_alloc_one(mm, address);
@@ -661,9 +661,8 @@ static void print_bad_pte(struct vm_area_struct *vma, unsigned long addr,
                        return;
                }
                if (nr_unshown) {
-                       printk(KERN_ALERT
-                               "BUG: Bad page map: %lu messages suppressed\n",
-                               nr_unshown);
+                       pr_alert("BUG: Bad page map: %lu messages suppressed\n",
+                                nr_unshown);
                        nr_unshown = 0;
                }
                nr_shown = 0;
@@ -674,15 +673,13 @@ static void print_bad_pte(struct vm_area_struct *vma, unsigned long addr,
        mapping = vma->vm_file ? vma->vm_file->f_mapping : NULL;
        index = linear_page_index(vma, addr);
 
-       printk(KERN_ALERT
-               "BUG: Bad page map in process %s  pte:%08llx pmd:%08llx\n",
-               current->comm,
-               (long long)pte_val(pte), (long long)pmd_val(*pmd));
+       pr_alert("BUG: Bad page map in process %s  pte:%08llx pmd:%08llx\n",
+                current->comm,
+                (long long)pte_val(pte), (long long)pmd_val(*pmd));
        if (page)
                dump_page(page, "bad pte");
-       printk(KERN_ALERT
-               "addr:%p vm_flags:%08lx anon_vma:%p mapping:%p index:%lx\n",
-               (void *)addr, vma->vm_flags, vma->anon_vma, mapping, index);
+       pr_alert("addr:%p vm_flags:%08lx anon_vma:%p mapping:%p index:%lx\n",
+                (void *)addr, vma->vm_flags, vma->anon_vma, mapping, index);
        /*
         * Choose text because data symbols depend on CONFIG_KALLSYMS_ALL=y
         */
@@ -1897,7 +1894,9 @@ int apply_to_page_range(struct mm_struct *mm, unsigned long addr,
        unsigned long end = addr + size;
        int err;
 
-       BUG_ON(addr >= end);
+       if (WARN_ON(addr >= end))
+               return -EINVAL;
+
        pgd = pgd_offset(mm, addr);
        do {
                next = pgd_addr_end(addr, end);
@@ -3143,8 +3142,7 @@ static int do_fault(struct mm_struct *mm, struct vm_area_struct *vma,
                unsigned long address, pte_t *page_table, pmd_t *pmd,
                unsigned int flags, pte_t orig_pte)
 {
-       pgoff_t pgoff = (((address & PAGE_MASK)
-                       - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff;
+       pgoff_t pgoff = linear_page_index(vma, address);
 
        pte_unmap(page_table);
        /* The VMA was not fully populated on mmap() or missing VM_DONTEXPAND */
@@ -3378,6 +3376,11 @@ static int __handle_mm_fault(struct mm_struct *mm, struct vm_area_struct *vma,
        pmd_t *pmd;
        pte_t *pte;
 
+       if (!arch_vma_access_permitted(vma, flags & FAULT_FLAG_WRITE,
+                                           flags & FAULT_FLAG_INSTRUCTION,
+                                           flags & FAULT_FLAG_REMOTE))
+               return VM_FAULT_SIGSEGV;
+
        if (unlikely(is_vm_hugetlb_page(vma)))
                return hugetlb_fault(mm, vma, address, flags);
 
@@ -3418,12 +3421,11 @@ static int __handle_mm_fault(struct mm_struct *mm, struct vm_area_struct *vma,
        }
 
        /*
-        * Use __pte_alloc instead of pte_alloc_map, because we can't
+        * Use pte_alloc() instead of pte_alloc_map, because we can't
         * run pte_offset_map on the pmd, if an huge pmd could
         * materialize from under us from a different thread.
         */
-       if (unlikely(pmd_none(*pmd)) &&
-           unlikely(__pte_alloc(mm, vma, pmd, address)))
+       if (unlikely(pte_alloc(mm, pmd, address)))
                return VM_FAULT_OOM;
        /*
         * If a huge pmd materialized under us just retry later.  Use
@@ -3695,7 +3697,7 @@ static int __access_remote_vm(struct task_struct *tsk, struct mm_struct *mm,
                void *maddr;
                struct page *page = NULL;
 
-               ret = get_user_pages(tsk, mm, addr, 1,
+               ret = get_user_pages_remote(tsk, mm, addr, 1,
                                write, 1, &page, &vma);
                if (ret <= 0) {
 #ifndef CONFIG_HAVE_IOREMAP_PROT