Merge tag 'trace-3.16-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt...
[pandora-kernel.git] / mm / mmap.c
index b1202cf..129b847 100644 (file)
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -6,6 +6,8 @@
  * Address space accounting code       <alan@lxorguk.ukuu.org.uk>
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/backing-dev.h>
@@ -37,6 +39,7 @@
 #include <linux/sched/sysctl.h>
 #include <linux/notifier.h>
 #include <linux/memory.h>
+#include <linux/printk.h>
 
 #include <asm/uaccess.h>
 #include <asm/cacheflush.h>
@@ -361,20 +364,20 @@ static int browse_rb(struct rb_root *root)
                struct vm_area_struct *vma;
                vma = rb_entry(nd, struct vm_area_struct, vm_rb);
                if (vma->vm_start < prev) {
-                       printk("vm_start %lx prev %lx\n", vma->vm_start, prev);
+                       pr_info("vm_start %lx prev %lx\n", vma->vm_start, prev);
                        bug = 1;
                }
                if (vma->vm_start < pend) {
-                       printk("vm_start %lx pend %lx\n", vma->vm_start, pend);
+                       pr_info("vm_start %lx pend %lx\n", vma->vm_start, pend);
                        bug = 1;
                }
                if (vma->vm_start > vma->vm_end) {
-                       printk("vm_end %lx < vm_start %lx\n",
+                       pr_info("vm_end %lx < vm_start %lx\n",
                                vma->vm_end, vma->vm_start);
                        bug = 1;
                }
                if (vma->rb_subtree_gap != vma_compute_subtree_gap(vma)) {
-                       printk("free gap %lx, correct %lx\n",
+                       pr_info("free gap %lx, correct %lx\n",
                               vma->rb_subtree_gap,
                               vma_compute_subtree_gap(vma));
                        bug = 1;
@@ -388,7 +391,7 @@ static int browse_rb(struct rb_root *root)
        for (nd = pn; nd; nd = rb_prev(nd))
                j++;
        if (i != j) {
-               printk("backwards %d, forwards %d\n", j, i);
+               pr_info("backwards %d, forwards %d\n", j, i);
                bug = 1;
        }
        return bug ? -1 : i;
@@ -423,17 +426,17 @@ static void validate_mm(struct mm_struct *mm)
                i++;
        }
        if (i != mm->map_count) {
-               printk("map_count %d vm_next %d\n", mm->map_count, i);
+               pr_info("map_count %d vm_next %d\n", mm->map_count, i);
                bug = 1;
        }
        if (highest_address != mm->highest_vm_end) {
-               printk("mm->highest_vm_end %lx, found %lx\n",
+               pr_info("mm->highest_vm_end %lx, found %lx\n",
                       mm->highest_vm_end, highest_address);
                bug = 1;
        }
        i = browse_rb(&mm->mm_rb);
        if (i != mm->map_count) {
-               printk("map_count %d rb %d\n", mm->map_count, i);
+               pr_info("map_count %d rb %d\n", mm->map_count, i);
                bug = 1;
        }
        BUG_ON(bug);
@@ -640,11 +643,10 @@ static void vma_link(struct mm_struct *mm, struct vm_area_struct *vma,
 {
        struct address_space *mapping = NULL;
 
-       if (vma->vm_file)
+       if (vma->vm_file) {
                mapping = vma->vm_file->f_mapping;
-
-       if (mapping)
                mutex_lock(&mapping->i_mmap_mutex);
+       }
 
        __vma_link(mm, vma, prev, rb_link, rb_parent);
        __vma_link_file(vma);
@@ -2872,6 +2874,31 @@ int may_expand_vm(struct mm_struct *mm, unsigned long npages)
        return 1;
 }
 
+static int special_mapping_fault(struct vm_area_struct *vma,
+                                struct vm_fault *vmf);
+
+/*
+ * Having a close hook prevents vma merging regardless of flags.
+ */
+static void special_mapping_close(struct vm_area_struct *vma)
+{
+}
+
+static const char *special_mapping_name(struct vm_area_struct *vma)
+{
+       return ((struct vm_special_mapping *)vma->vm_private_data)->name;
+}
+
+static const struct vm_operations_struct special_mapping_vmops = {
+       .close = special_mapping_close,
+       .fault = special_mapping_fault,
+       .name = special_mapping_name,
+};
+
+static const struct vm_operations_struct legacy_special_mapping_vmops = {
+       .close = special_mapping_close,
+       .fault = special_mapping_fault,
+};
 
 static int special_mapping_fault(struct vm_area_struct *vma,
                                struct vm_fault *vmf)
@@ -2887,7 +2914,13 @@ static int special_mapping_fault(struct vm_area_struct *vma,
         */
        pgoff = vmf->pgoff - vma->vm_pgoff;
 
-       for (pages = vma->vm_private_data; pgoff && *pages; ++pages)
+       if (vma->vm_ops == &legacy_special_mapping_vmops)
+               pages = vma->vm_private_data;
+       else
+               pages = ((struct vm_special_mapping *)vma->vm_private_data)->
+                       pages;
+
+       for (; pgoff && *pages; ++pages)
                pgoff--;
 
        if (*pages) {
@@ -2900,30 +2933,11 @@ static int special_mapping_fault(struct vm_area_struct *vma,
        return VM_FAULT_SIGBUS;
 }
 
-/*
- * Having a close hook prevents vma merging regardless of flags.
- */
-static void special_mapping_close(struct vm_area_struct *vma)
-{
-}
-
-static const struct vm_operations_struct special_mapping_vmops = {
-       .close = special_mapping_close,
-       .fault = special_mapping_fault,
-};
-
-/*
- * Called with mm->mmap_sem held for writing.
- * Insert a new vma covering the given region, with the given flags.
- * Its pages are supplied by the given array of struct page *.
- * The array can be shorter than len >> PAGE_SHIFT if it's null-terminated.
- * The region past the last page supplied will always produce SIGBUS.
- * The array pointer and the pages it points to are assumed to stay alive
- * for as long as this mapping might exist.
- */
-struct vm_area_struct *_install_special_mapping(struct mm_struct *mm,
-                           unsigned long addr, unsigned long len,
-                           unsigned long vm_flags, struct page **pages)
+static struct vm_area_struct *__install_special_mapping(
+       struct mm_struct *mm,
+       unsigned long addr, unsigned long len,
+       unsigned long vm_flags, const struct vm_operations_struct *ops,
+       void *priv)
 {
        int ret;
        struct vm_area_struct *vma;
@@ -2940,8 +2954,8 @@ struct vm_area_struct *_install_special_mapping(struct mm_struct *mm,
        vma->vm_flags = vm_flags | mm->def_flags | VM_DONTEXPAND | VM_SOFTDIRTY;
        vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
 
-       vma->vm_ops = &special_mapping_vmops;
-       vma->vm_private_data = pages;
+       vma->vm_ops = ops;
+       vma->vm_private_data = priv;
 
        ret = insert_vm_struct(mm, vma);
        if (ret)
@@ -2958,16 +2972,33 @@ out:
        return ERR_PTR(ret);
 }
 
+/*
+ * Called with mm->mmap_sem held for writing.
+ * Insert a new vma covering the given region, with the given flags.
+ * Its pages are supplied by the given array of struct page *.
+ * The array can be shorter than len >> PAGE_SHIFT if it's null-terminated.
+ * The region past the last page supplied will always produce SIGBUS.
+ * The array pointer and the pages it points to are assumed to stay alive
+ * for as long as this mapping might exist.
+ */
+struct vm_area_struct *_install_special_mapping(
+       struct mm_struct *mm,
+       unsigned long addr, unsigned long len,
+       unsigned long vm_flags, const struct vm_special_mapping *spec)
+{
+       return __install_special_mapping(mm, addr, len, vm_flags,
+                                        &special_mapping_vmops, (void *)spec);
+}
+
 int install_special_mapping(struct mm_struct *mm,
                            unsigned long addr, unsigned long len,
                            unsigned long vm_flags, struct page **pages)
 {
-       struct vm_area_struct *vma = _install_special_mapping(mm,
-                           addr, len, vm_flags, pages);
+       struct vm_area_struct *vma = __install_special_mapping(
+               mm, addr, len, vm_flags, &legacy_special_mapping_vmops,
+               (void *)pages);
 
-       if (IS_ERR(vma))
-               return PTR_ERR(vma);
-       return 0;
+       return PTR_ERR_OR_ZERO(vma);
 }
 
 static DEFINE_MUTEX(mm_all_locks_mutex);
@@ -3252,7 +3283,7 @@ static struct notifier_block reserve_mem_nb = {
 static int __meminit init_reserve_notifier(void)
 {
        if (register_hotmemory_notifier(&reserve_mem_nb))
-               printk("Failed registering memory add/remove notifier for admin reserve");
+               pr_err("Failed registering memory add/remove notifier for admin reserve\n");
 
        return 0;
 }