ARM: OMAP3: PM: remove access to PRM_VOLTCTRL register
[pandora-kernel.git] / mm / mmap.c
index eae90af..6182c8a 100644 (file)
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -1368,7 +1368,7 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
        struct vm_area_struct *vma;
        unsigned long start_addr;
 
-       if (len > TASK_SIZE)
+       if (len > TASK_SIZE - mmap_min_addr)
                return -ENOMEM;
 
        if (flags & MAP_FIXED)
@@ -1377,7 +1377,7 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
        if (addr) {
                addr = PAGE_ALIGN(addr);
                vma = find_vma(mm, addr);
-               if (TASK_SIZE - len >= addr &&
+               if (TASK_SIZE - len >= addr && addr >= mmap_min_addr &&
                    (!vma || addr + len <= vma->vm_start))
                        return addr;
        }
@@ -1442,9 +1442,10 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
        struct vm_area_struct *vma;
        struct mm_struct *mm = current->mm;
        unsigned long addr = addr0;
+       unsigned long low_limit = max(PAGE_SIZE, mmap_min_addr);
 
        /* requested length too big for entire address space */
-       if (len > TASK_SIZE)
+       if (len > TASK_SIZE - mmap_min_addr)
                return -ENOMEM;
 
        if (flags & MAP_FIXED)
@@ -1454,7 +1455,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
        if (addr) {
                addr = PAGE_ALIGN(addr);
                vma = find_vma(mm, addr);
-               if (TASK_SIZE - len >= addr &&
+               if (TASK_SIZE - len >= addr && addr >= mmap_min_addr &&
                                (!vma || addr + len <= vma->vm_start))
                        return addr;
        }
@@ -1469,14 +1470,14 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
        addr = mm->free_area_cache;
 
        /* make sure it can fit in the remaining address space */
-       if (addr > len) {
+       if (addr >= low_limit + len) {
                vma = find_vma(mm, addr-len);
                if (!vma || addr <= vma->vm_start)
                        /* remember the address as a hint for next time */
                        return (mm->free_area_cache = addr-len);
        }
 
-       if (mm->mmap_base < len)
+       if (mm->mmap_base < low_limit + len)
                goto bottomup;
 
        addr = mm->mmap_base-len;
@@ -1498,7 +1499,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
 
                /* try just below the current vma->vm_start */
                addr = vma->vm_start-len;
-       } while (len < vma->vm_start);
+       } while (vma->vm_start >= low_limit + len);
 
 bottomup:
        /*
@@ -1573,7 +1574,7 @@ struct vm_area_struct *find_vma(struct mm_struct *mm, unsigned long addr)
        if (mm) {
                /* Check the cache first. */
                /* (Cache hit rate is typically around 35%.) */
-               vma = mm->mmap_cache;
+               vma = ACCESS_ONCE(mm->mmap_cache);
                if (!(vma && vma->vm_end > addr && vma->vm_start <= addr)) {
                        struct rb_node * rb_node;