|
@@ -129,6 +129,7 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size,
|
|
|
struct vm_area_struct *vma;
|
|
|
int err = -EINVAL;
|
|
|
int has_write_lock = 0;
|
|
|
+ vm_flags_t vm_flags;
|
|
|
|
|
|
if (prot)
|
|
|
return err;
|
|
@@ -228,30 +229,16 @@ get_write_lock:
|
|
|
/*
|
|
|
* drop PG_Mlocked flag for over-mapped range
|
|
|
*/
|
|
|
- vm_flags_t saved_flags = vma->vm_flags;
|
|
|
if (!has_write_lock)
|
|
|
goto get_write_lock;
|
|
|
+ vm_flags = vma->vm_flags;
|
|
|
munlock_vma_pages_range(vma, start, start + size);
|
|
|
- vma->vm_flags = saved_flags;
|
|
|
+ vma->vm_flags = vm_flags;
|
|
|
}
|
|
|
|
|
|
mmu_notifier_invalidate_range_start(mm, start, start + size);
|
|
|
err = vma->vm_ops->remap_pages(vma, start, size, pgoff);
|
|
|
mmu_notifier_invalidate_range_end(mm, start, start + size);
|
|
|
- if (!err) {
|
|
|
- if (vma->vm_flags & VM_LOCKED) {
|
|
|
- /*
|
|
|
- * might be mapping previously unmapped range of file
|
|
|
- */
|
|
|
- mlock_vma_pages_range(vma, start, start + size);
|
|
|
- } else if (!(flags & MAP_NONBLOCK)) {
|
|
|
- if (unlikely(has_write_lock)) {
|
|
|
- downgrade_write(&mm->mmap_sem);
|
|
|
- has_write_lock = 0;
|
|
|
- }
|
|
|
- make_pages_present(start, start+size);
|
|
|
- }
|
|
|
- }
|
|
|
|
|
|
/*
|
|
|
* We can't clear VM_NONLINEAR because we'd have to do
|
|
@@ -260,10 +247,13 @@ get_write_lock:
|
|
|
*/
|
|
|
|
|
|
out:
|
|
|
+ vm_flags = vma->vm_flags;
|
|
|
if (likely(!has_write_lock))
|
|
|
up_read(&mm->mmap_sem);
|
|
|
else
|
|
|
up_write(&mm->mmap_sem);
|
|
|
+ if (!err && ((vm_flags & VM_LOCKED) || !(flags & MAP_NONBLOCK)))
|
|
|
+ mm_populate(start, size);
|
|
|
|
|
|
return err;
|
|
|
}
|