hrtimer: prevent migration of per CPU hrtimers
[pandora-kernel.git] / mm / mmap.c
index 971d0ed..e7a5a68 100644 (file)
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -1030,6 +1030,10 @@ unsigned long do_mmap_pgoff(struct file * file, unsigned long addr,
        } else {
                switch (flags & MAP_TYPE) {
                case MAP_SHARED:
+                       /*
+                        * Ignore pgoff.
+                        */
+                       pgoff = 0;
                        vm_flags |= VM_SHARED | VM_MAYSHARE;
                        break;
                case MAP_PRIVATE:
@@ -2273,14 +2277,14 @@ int install_special_mapping(struct mm_struct *mm,
 
 static DEFINE_MUTEX(mm_all_locks_mutex);
 
-static void vm_lock_anon_vma(struct anon_vma *anon_vma)
+static void vm_lock_anon_vma(struct mm_struct *mm, struct anon_vma *anon_vma)
 {
        if (!test_bit(0, (unsigned long *) &anon_vma->head.next)) {
                /*
                 * The LSB of head.next can't change from under us
                 * because we hold the mm_all_locks_mutex.
                 */
-               spin_lock(&anon_vma->lock);
+               spin_lock_nest_lock(&anon_vma->lock, &mm->mmap_sem);
                /*
                 * We can safely modify head.next after taking the
                 * anon_vma->lock. If some other vma in this mm shares
@@ -2296,7 +2300,7 @@ static void vm_lock_anon_vma(struct anon_vma *anon_vma)
        }
 }
 
-static void vm_lock_mapping(struct address_space *mapping)
+static void vm_lock_mapping(struct mm_struct *mm, struct address_space *mapping)
 {
        if (!test_bit(AS_MM_ALL_LOCKS, &mapping->flags)) {
                /*
@@ -2310,7 +2314,7 @@ static void vm_lock_mapping(struct address_space *mapping)
                 */
                if (test_and_set_bit(AS_MM_ALL_LOCKS, &mapping->flags))
                        BUG();
-               spin_lock(&mapping->i_mmap_lock);
+               spin_lock_nest_lock(&mapping->i_mmap_lock, &mm->mmap_sem);
        }
 }
 
@@ -2358,11 +2362,17 @@ int mm_take_all_locks(struct mm_struct *mm)
        for (vma = mm->mmap; vma; vma = vma->vm_next) {
                if (signal_pending(current))
                        goto out_unlock;
-               if (vma->anon_vma)
-                       vm_lock_anon_vma(vma->anon_vma);
                if (vma->vm_file && vma->vm_file->f_mapping)
-                       vm_lock_mapping(vma->vm_file->f_mapping);
+                       vm_lock_mapping(mm, vma->vm_file->f_mapping);
+       }
+
+       for (vma = mm->mmap; vma; vma = vma->vm_next) {
+               if (signal_pending(current))
+                       goto out_unlock;
+               if (vma->anon_vma)
+                       vm_lock_anon_vma(mm, vma->anon_vma);
        }
+
        ret = 0;
 
 out_unlock: