perf stat: Support L2 Topdown events
[linux-2.6-microblaze.git] / mm / mmap.c
index 5c8b448..dc72060 100644 (file)
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -1897,8 +1897,8 @@ out:
        return addr;
 
 unmap_and_free_vma:
+       fput(vma->vm_file);
        vma->vm_file = NULL;
-       fput(file);
 
        /* Undo any partial mapping done by a device driver. */
        unmap_region(mm, vma, prev, vma->vm_start, vma->vm_end);
@@ -2731,8 +2731,8 @@ int __split_vma(struct mm_struct *mm, struct vm_area_struct *vma,
        struct vm_area_struct *new;
        int err;
 
-       if (vma->vm_ops && vma->vm_ops->split) {
-               err = vma->vm_ops->split(vma, addr);
+       if (vma->vm_ops && vma->vm_ops->may_split) {
+               err = vma->vm_ops->may_split(vma, addr);
                if (err)
                        return err;
        }
@@ -3405,10 +3405,14 @@ static const char *special_mapping_name(struct vm_area_struct *vma)
        return ((struct vm_special_mapping *)vma->vm_private_data)->name;
 }
 
-static int special_mapping_mremap(struct vm_area_struct *new_vma)
+static int special_mapping_mremap(struct vm_area_struct *new_vma,
+                                 unsigned long flags)
 {
        struct vm_special_mapping *sm = new_vma->vm_private_data;
 
+       if (flags & MREMAP_DONTUNMAP)
+               return -EINVAL;
+
        if (WARN_ON_ONCE(current->mm != new_vma->vm_mm))
                return -EFAULT;
 
@@ -3418,6 +3422,17 @@ static int special_mapping_mremap(struct vm_area_struct *new_vma)
        return 0;
 }
 
+static int special_mapping_split(struct vm_area_struct *vma, unsigned long addr)
+{
+       /*
+        * Forbid splitting special mappings - kernel has expectations over
+        * the number of pages in mapping. Together with VM_DONTEXPAND
+        * the size of vma should stay the same over the special mapping's
+        * lifetime.
+        */
+       return -EINVAL;
+}
+
 static const struct vm_operations_struct special_mapping_vmops = {
        .close = special_mapping_close,
        .fault = special_mapping_fault,
@@ -3425,6 +3440,7 @@ static const struct vm_operations_struct special_mapping_vmops = {
        .name = special_mapping_name,
        /* vDSO code relies that VVAR can't be accessed remotely */
        .access = NULL,
+       .may_split = special_mapping_split,
 };
 
 static const struct vm_operations_struct legacy_special_mapping_vmops = {