Pull asus into test branch
[sfrench/cifs-2.6.git] / mm / mremap.c
index b535438c363cfb9c6d80528c2c056962ef2e038a..5d4bd4f95b8e5ef28f269f604b61d133f341d27b 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/shm.h>
 #include <linux/mman.h>
 #include <linux/swap.h>
+#include <linux/capability.h>
 #include <linux/fs.h>
 #include <linux/highmem.h>
 #include <linux/security.h>
@@ -96,18 +97,19 @@ static void move_ptes(struct vm_area_struct *vma, pmd_t *old_pmd,
        new_pte = pte_offset_map_nested(new_pmd, new_addr);
        new_ptl = pte_lockptr(mm, new_pmd);
        if (new_ptl != old_ptl)
-               spin_lock(new_ptl);
+               spin_lock_nested(new_ptl, SINGLE_DEPTH_NESTING);
+       arch_enter_lazy_mmu_mode();
 
        for (; old_addr < old_end; old_pte++, old_addr += PAGE_SIZE,
                                   new_pte++, new_addr += PAGE_SIZE) {
                if (pte_none(*old_pte))
                        continue;
                pte = ptep_clear_flush(vma, old_addr, old_pte);
-               /* ZERO_PAGE can be dependant on virtual addr */
                pte = move_pte(pte, new_vma->vm_page_prot, old_addr, new_addr);
                set_pte_at(mm, new_addr, new_pte, pte);
        }
 
+       arch_leave_lazy_mmu_mode();
        if (new_ptl != old_ptl)
                spin_unlock(new_ptl);
        pte_unmap_nested(new_pte - 1);
@@ -323,7 +325,7 @@ unsigned long do_mremap(unsigned long addr,
        /* We can't remap across vm area boundaries */
        if (old_len > vma->vm_end - addr)
                goto out;
-       if (vma->vm_flags & VM_DONTEXPAND) {
+       if (vma->vm_flags & (VM_DONTEXPAND | VM_PFNMAP)) {
                if (new_len > old_len)
                        goto out;
        }