X-Git-Url: http://pilppa.org/gitweb/gitweb.cgi?a=blobdiff_plain;f=mm%2Ffremap.c;h=7d12ca70ef7bf22c7e1efcdee186adad87a6c8c8;hb=45432371b448c80622d8069b845625996127caeb;hp=07a9c82ce1a3fa0e24da2f2da23e9416e3f1819c;hpb=233607dbbc823caf685e778cabc49fb7f679900b;p=linux-2.6-omap-h63xx.git diff --git a/mm/fremap.c b/mm/fremap.c index 07a9c82ce1a..7d12ca70ef7 100644 --- a/mm/fremap.c +++ b/mm/fremap.c @@ -15,11 +15,14 @@ #include #include #include +#include #include #include #include +#include "internal.h" + static void zap_pte(struct mm_struct *mm, struct vm_area_struct *vma, unsigned long addr, pte_t *ptep) { @@ -214,13 +217,31 @@ asmlinkage long sys_remap_file_pages(unsigned long start, unsigned long size, spin_unlock(&mapping->i_mmap_lock); } + if (vma->vm_flags & VM_LOCKED) { + /* + * drop PG_Mlocked flag for over-mapped range + */ + unsigned int saved_flags = vma->vm_flags; + munlock_vma_pages_range(vma, start, start + size); + vma->vm_flags = saved_flags; + } + + mmu_notifier_invalidate_range_start(mm, start, start + size); err = populate_range(mm, vma, start, size, pgoff); + mmu_notifier_invalidate_range_end(mm, start, start + size); if (!err && !(flags & MAP_NONBLOCK)) { - if (unlikely(has_write_lock)) { - downgrade_write(&mm->mmap_sem); - has_write_lock = 0; + if (vma->vm_flags & VM_LOCKED) { + /* + * might be mapping previously unmapped range of file + */ + mlock_vma_pages_range(vma, start, start + size); + } else { + if (unlikely(has_write_lock)) { + downgrade_write(&mm->mmap_sem); + has_write_lock = 0; + } + make_pages_present(start, start+size); } - make_pages_present(start, start+size); } /* @@ -237,4 +258,3 @@ out: return err; } -