diff options
Diffstat (limited to 'mm/mmap.c')
-rw-r--r-- | mm/mmap.c | 20 |
1 files changed, 15 insertions, 5 deletions
@@ -1154,12 +1154,15 @@ static inline unsigned long round_hint_to_min(unsigned long hint) | |||
1154 | 1154 | ||
1155 | unsigned long do_mmap_pgoff(struct file *file, unsigned long addr, | 1155 | unsigned long do_mmap_pgoff(struct file *file, unsigned long addr, |
1156 | unsigned long len, unsigned long prot, | 1156 | unsigned long len, unsigned long prot, |
1157 | unsigned long flags, unsigned long pgoff) | 1157 | unsigned long flags, unsigned long pgoff, |
1158 | bool *populate) | ||
1158 | { | 1159 | { |
1159 | struct mm_struct * mm = current->mm; | 1160 | struct mm_struct * mm = current->mm; |
1160 | struct inode *inode; | 1161 | struct inode *inode; |
1161 | vm_flags_t vm_flags; | 1162 | vm_flags_t vm_flags; |
1162 | 1163 | ||
1164 | *populate = false; | ||
1165 | |||
1163 | /* | 1166 | /* |
1164 | * Does the application expect PROT_READ to imply PROT_EXEC? | 1167 | * Does the application expect PROT_READ to imply PROT_EXEC? |
1165 | * | 1168 | * |
@@ -1280,7 +1283,12 @@ unsigned long do_mmap_pgoff(struct file *file, unsigned long addr, | |||
1280 | } | 1283 | } |
1281 | } | 1284 | } |
1282 | 1285 | ||
1283 | return mmap_region(file, addr, len, flags, vm_flags, pgoff); | 1286 | addr = mmap_region(file, addr, len, flags, vm_flags, pgoff); |
1287 | if (!IS_ERR_VALUE(addr) && | ||
1288 | ((vm_flags & VM_LOCKED) || | ||
1289 | (flags & (MAP_POPULATE | MAP_NONBLOCK)) == MAP_POPULATE)) | ||
1290 | *populate = true; | ||
1291 | return addr; | ||
1284 | } | 1292 | } |
1285 | 1293 | ||
1286 | SYSCALL_DEFINE6(mmap_pgoff, unsigned long, addr, unsigned long, len, | 1294 | SYSCALL_DEFINE6(mmap_pgoff, unsigned long, addr, unsigned long, len, |
@@ -1531,10 +1539,12 @@ out: | |||
1531 | 1539 | ||
1532 | vm_stat_account(mm, vm_flags, file, len >> PAGE_SHIFT); | 1540 | vm_stat_account(mm, vm_flags, file, len >> PAGE_SHIFT); |
1533 | if (vm_flags & VM_LOCKED) { | 1541 | if (vm_flags & VM_LOCKED) { |
1534 | if (!mlock_vma_pages_range(vma, addr, addr + len)) | 1542 | if (!((vm_flags & VM_SPECIAL) || is_vm_hugetlb_page(vma) || |
1543 | vma == get_gate_vma(current->mm))) | ||
1535 | mm->locked_vm += (len >> PAGE_SHIFT); | 1544 | mm->locked_vm += (len >> PAGE_SHIFT); |
1536 | } else if ((flags & MAP_POPULATE) && !(flags & MAP_NONBLOCK)) | 1545 | else |
1537 | make_pages_present(addr, addr + len); | 1546 | vma->vm_flags &= ~VM_LOCKED; |
1547 | } | ||
1538 | 1548 | ||
1539 | if (file) | 1549 | if (file) |
1540 | uprobe_mmap(vma); | 1550 | uprobe_mmap(vma); |