1
2
3
4
5
6
7
8#include <linux/capability.h>
9#include <linux/mman.h>
10#include <linux/mm.h>
11#include <linux/swap.h>
12#include <linux/swapops.h>
13#include <linux/pagemap.h>
14#include <linux/pagevec.h>
15#include <linux/mempolicy.h>
16#include <linux/syscalls.h>
17#include <linux/sched.h>
18#include <linux/export.h>
19#include <linux/rmap.h>
20#include <linux/mmzone.h>
21#include <linux/hugetlb.h>
22#include <linux/memcontrol.h>
23#include <linux/mm_inline.h>
24
25#include "internal.h"
26
27bool can_do_mlock(void)
28{
29 if (rlimit(RLIMIT_MEMLOCK) != 0)
30 return true;
31 if (capable(CAP_IPC_LOCK))
32 return true;
33 return false;
34}
35EXPORT_SYMBOL(can_do_mlock);
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57void clear_page_mlock(struct page *page)
58{
59 if (!TestClearPageMlocked(page))
60 return;
61
62 mod_zone_page_state(page_zone(page), NR_MLOCK,
63 -hpage_nr_pages(page));
64 count_vm_event(UNEVICTABLE_PGCLEARED);
65 if (!isolate_lru_page(page)) {
66 putback_lru_page(page);
67 } else {
68
69
70
71 if (PageUnevictable(page))
72 count_vm_event(UNEVICTABLE_PGSTRANDED);
73 }
74}
75
76
77
78
79
80void mlock_vma_page(struct page *page)
81{
82
83 BUG_ON(!PageLocked(page));
84
85 VM_BUG_ON_PAGE(PageTail(page), page);
86 VM_BUG_ON_PAGE(PageCompound(page) && PageDoubleMap(page), page);
87
88 if (!TestSetPageMlocked(page)) {
89 mod_zone_page_state(page_zone(page), NR_MLOCK,
90 hpage_nr_pages(page));
91 count_vm_event(UNEVICTABLE_PGMLOCKED);
92 if (!isolate_lru_page(page))
93 putback_lru_page(page);
94 }
95}
96
97
98
99
100
101static bool __munlock_isolate_lru_page(struct page *page, bool getpage)
102{
103 if (PageLRU(page)) {
104 struct lruvec *lruvec;
105
106 lruvec = mem_cgroup_page_lruvec(page, page_zone(page));
107 if (getpage)
108 get_page(page);
109 ClearPageLRU(page);
110 del_page_from_lru_list(page, lruvec, page_lru(page));
111 return true;
112 }
113
114 return false;
115}
116
117
118
119
120
121
122
123static void __munlock_isolated_page(struct page *page)
124{
125 int ret = SWAP_AGAIN;
126
127
128
129
130
131 if (page_mapcount(page) > 1)
132 ret = try_to_munlock(page);
133
134
135 if (ret != SWAP_MLOCK)
136 count_vm_event(UNEVICTABLE_PGMUNLOCKED);
137
138 putback_lru_page(page);
139}
140
141
142
143
144
145
146
147
148
149
150static void __munlock_isolation_failed(struct page *page)
151{
152 if (PageUnevictable(page))
153 __count_vm_event(UNEVICTABLE_PGSTRANDED);
154 else
155 __count_vm_event(UNEVICTABLE_PGMUNLOCKED);
156}
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176unsigned int munlock_vma_page(struct page *page)
177{
178 int nr_pages;
179 struct zone *zone = page_zone(page);
180
181
182 BUG_ON(!PageLocked(page));
183
184 VM_BUG_ON_PAGE(PageTail(page), page);
185
186
187
188
189
190
191 spin_lock_irq(&zone->lru_lock);
192
193 nr_pages = hpage_nr_pages(page);
194 if (!TestClearPageMlocked(page))
195 goto unlock_out;
196
197 __mod_zone_page_state(zone, NR_MLOCK, -nr_pages);
198
199 if (__munlock_isolate_lru_page(page, true)) {
200 spin_unlock_irq(&zone->lru_lock);
201 __munlock_isolated_page(page);
202 goto out;
203 }
204 __munlock_isolation_failed(page);
205
206unlock_out:
207 spin_unlock_irq(&zone->lru_lock);
208
209out:
210 return nr_pages - 1;
211}
212
213
214
215
216static int __mlock_posix_error_return(long retval)
217{
218 if (retval == -EFAULT)
219 retval = -ENOMEM;
220 else if (retval == -ENOMEM)
221 retval = -EAGAIN;
222 return retval;
223}
224
225
226
227
228
229
230
231
232
233
234
235
236
237static bool __putback_lru_fast_prepare(struct page *page, struct pagevec *pvec,
238 int *pgrescued)
239{
240 VM_BUG_ON_PAGE(PageLRU(page), page);
241 VM_BUG_ON_PAGE(!PageLocked(page), page);
242
243 if (page_mapcount(page) <= 1 && page_evictable(page)) {
244 pagevec_add(pvec, page);
245 if (TestClearPageUnevictable(page))
246 (*pgrescued)++;
247 unlock_page(page);
248 return true;
249 }
250
251 return false;
252}
253
254
255
256
257
258
259
260static void __putback_lru_fast(struct pagevec *pvec, int pgrescued)
261{
262 count_vm_events(UNEVICTABLE_PGMUNLOCKED, pagevec_count(pvec));
263
264
265
266
267 __pagevec_lru_add(pvec);
268 count_vm_events(UNEVICTABLE_PGRESCUED, pgrescued);
269}
270
271
272
273
274
275
276
277
278
279
280
281static void __munlock_pagevec(struct pagevec *pvec, struct zone *zone)
282{
283 int i;
284 int nr = pagevec_count(pvec);
285 int delta_munlocked;
286 struct pagevec pvec_putback;
287 int pgrescued = 0;
288
289 pagevec_init(&pvec_putback, 0);
290
291
292 spin_lock_irq(&zone->lru_lock);
293 for (i = 0; i < nr; i++) {
294 struct page *page = pvec->pages[i];
295
296 if (TestClearPageMlocked(page)) {
297
298
299
300
301 if (__munlock_isolate_lru_page(page, false))
302 continue;
303 else
304 __munlock_isolation_failed(page);
305 }
306
307
308
309
310
311
312
313 pagevec_add(&pvec_putback, pvec->pages[i]);
314 pvec->pages[i] = NULL;
315 }
316 delta_munlocked = -nr + pagevec_count(&pvec_putback);
317 __mod_zone_page_state(zone, NR_MLOCK, delta_munlocked);
318 spin_unlock_irq(&zone->lru_lock);
319
320
321 pagevec_release(&pvec_putback);
322
323
324 for (i = 0; i < nr; i++) {
325 struct page *page = pvec->pages[i];
326
327 if (page) {
328 lock_page(page);
329 if (!__putback_lru_fast_prepare(page, &pvec_putback,
330 &pgrescued)) {
331
332
333
334
335 get_page(page);
336 __munlock_isolated_page(page);
337 unlock_page(page);
338 put_page(page);
339 }
340 }
341 }
342
343
344
345
346
347 if (pagevec_count(&pvec_putback))
348 __putback_lru_fast(&pvec_putback, pgrescued);
349}
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364static unsigned long __munlock_pagevec_fill(struct pagevec *pvec,
365 struct vm_area_struct *vma, int zoneid, unsigned long start,
366 unsigned long end)
367{
368 pte_t *pte;
369 spinlock_t *ptl;
370
371
372
373
374
375
376 pte = get_locked_pte(vma->vm_mm, start, &ptl);
377
378 end = pgd_addr_end(start, end);
379 end = pud_addr_end(start, end);
380 end = pmd_addr_end(start, end);
381
382
383 start += PAGE_SIZE;
384 while (start < end) {
385 struct page *page = NULL;
386 pte++;
387 if (pte_present(*pte))
388 page = vm_normal_page(vma, start, *pte);
389
390
391
392
393 if (!page || page_zone_id(page) != zoneid)
394 break;
395
396
397
398
399
400 if (PageTransCompound(page))
401 break;
402
403 get_page(page);
404
405
406
407
408 start += PAGE_SIZE;
409 if (pagevec_add(pvec, page) == 0)
410 break;
411 }
412 pte_unmap_unlock(pte, ptl);
413 return start;
414}
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434void munlock_vma_pages_range(struct vm_area_struct *vma,
435 unsigned long start, unsigned long end)
436{
437 vma->vm_flags &= VM_LOCKED_CLEAR_MASK;
438
439 while (start < end) {
440 struct page *page;
441 unsigned int page_mask;
442 unsigned long page_increm;
443 struct pagevec pvec;
444 struct zone *zone;
445 int zoneid;
446
447 pagevec_init(&pvec, 0);
448
449
450
451
452
453
454
455 page = follow_page_mask(vma, start, FOLL_GET | FOLL_DUMP,
456 &page_mask);
457
458 if (page && !IS_ERR(page)) {
459 if (PageTransTail(page)) {
460 VM_BUG_ON_PAGE(PageMlocked(page), page);
461 put_page(page);
462 } else if (PageTransHuge(page)) {
463 lock_page(page);
464
465
466
467
468
469
470 page_mask = munlock_vma_page(page);
471 unlock_page(page);
472 put_page(page);
473 } else {
474
475
476
477
478
479 pagevec_add(&pvec, page);
480 zone = page_zone(page);
481 zoneid = page_zone_id(page);
482
483
484
485
486
487
488
489 start = __munlock_pagevec_fill(&pvec, vma,
490 zoneid, start, end);
491 __munlock_pagevec(&pvec, zone);
492 goto next;
493 }
494 }
495 page_increm = 1 + page_mask;
496 start += page_increm * PAGE_SIZE;
497next:
498 cond_resched();
499 }
500}
501
502
503
504
505
506
507
508
509
510
511static int mlock_fixup(struct vm_area_struct *vma, struct vm_area_struct **prev,
512 unsigned long start, unsigned long end, vm_flags_t newflags)
513{
514 struct mm_struct *mm = vma->vm_mm;
515 pgoff_t pgoff;
516 int nr_pages;
517 int ret = 0;
518 int lock = !!(newflags & VM_LOCKED);
519
520 if (newflags == vma->vm_flags || (vma->vm_flags & VM_SPECIAL) ||
521 is_vm_hugetlb_page(vma) || vma == get_gate_vma(current->mm))
522
523 goto out;
524
525 pgoff = vma->vm_pgoff + ((start - vma->vm_start) >> PAGE_SHIFT);
526 *prev = vma_merge(mm, *prev, start, end, newflags, vma->anon_vma,
527 vma->vm_file, pgoff, vma_policy(vma),
528 vma->vm_userfaultfd_ctx);
529 if (*prev) {
530 vma = *prev;
531 goto success;
532 }
533
534 if (start != vma->vm_start) {
535 ret = split_vma(mm, vma, start, 1);
536 if (ret)
537 goto out;
538 }
539
540 if (end != vma->vm_end) {
541 ret = split_vma(mm, vma, end, 0);
542 if (ret)
543 goto out;
544 }
545
546success:
547
548
549
550 nr_pages = (end - start) >> PAGE_SHIFT;
551 if (!lock)
552 nr_pages = -nr_pages;
553 mm->locked_vm += nr_pages;
554
555
556
557
558
559
560
561 if (lock)
562 vma->vm_flags = newflags;
563 else
564 munlock_vma_pages_range(vma, start, end);
565
566out:
567 *prev = vma;
568 return ret;
569}
570
571static int apply_vma_lock_flags(unsigned long start, size_t len,
572 vm_flags_t flags)
573{
574 unsigned long nstart, end, tmp;
575 struct vm_area_struct * vma, * prev;
576 int error;
577
578 VM_BUG_ON(offset_in_page(start));
579 VM_BUG_ON(len != PAGE_ALIGN(len));
580 end = start + len;
581 if (end < start)
582 return -EINVAL;
583 if (end == start)
584 return 0;
585 vma = find_vma(current->mm, start);
586 if (!vma || vma->vm_start > start)
587 return -ENOMEM;
588
589 prev = vma->vm_prev;
590 if (start > vma->vm_start)
591 prev = vma;
592
593 for (nstart = start ; ; ) {
594 vm_flags_t newflags = vma->vm_flags & VM_LOCKED_CLEAR_MASK;
595
596 newflags |= flags;
597
598
599 tmp = vma->vm_end;
600 if (tmp > end)
601 tmp = end;
602 error = mlock_fixup(vma, &prev, nstart, tmp, newflags);
603 if (error)
604 break;
605 nstart = tmp;
606 if (nstart < prev->vm_end)
607 nstart = prev->vm_end;
608 if (nstart >= end)
609 break;
610
611 vma = prev->vm_next;
612 if (!vma || vma->vm_start != nstart) {
613 error = -ENOMEM;
614 break;
615 }
616 }
617 return error;
618}
619
620static int do_mlock(unsigned long start, size_t len, vm_flags_t flags)
621{
622 unsigned long locked;
623 unsigned long lock_limit;
624 int error = -ENOMEM;
625
626 if (!can_do_mlock())
627 return -EPERM;
628
629 lru_add_drain_all();
630
631 len = PAGE_ALIGN(len + (offset_in_page(start)));
632 start &= PAGE_MASK;
633
634 lock_limit = rlimit(RLIMIT_MEMLOCK);
635 lock_limit >>= PAGE_SHIFT;
636 locked = len >> PAGE_SHIFT;
637
638 down_write(¤t->mm->mmap_sem);
639
640 locked += current->mm->locked_vm;
641
642
643 if ((locked <= lock_limit) || capable(CAP_IPC_LOCK))
644 error = apply_vma_lock_flags(start, len, flags);
645
646 up_write(¤t->mm->mmap_sem);
647 if (error)
648 return error;
649
650 error = __mm_populate(start, len, 0);
651 if (error)
652 return __mlock_posix_error_return(error);
653 return 0;
654}
655
656SYSCALL_DEFINE2(mlock, unsigned long, start, size_t, len)
657{
658 return do_mlock(start, len, VM_LOCKED);
659}
660
661SYSCALL_DEFINE3(mlock2, unsigned long, start, size_t, len, int, flags)
662{
663 vm_flags_t vm_flags = VM_LOCKED;
664
665 if (flags & ~MLOCK_ONFAULT)
666 return -EINVAL;
667
668 if (flags & MLOCK_ONFAULT)
669 vm_flags |= VM_LOCKONFAULT;
670
671 return do_mlock(start, len, vm_flags);
672}
673
674SYSCALL_DEFINE2(munlock, unsigned long, start, size_t, len)
675{
676 int ret;
677
678 len = PAGE_ALIGN(len + (offset_in_page(start)));
679 start &= PAGE_MASK;
680
681 down_write(¤t->mm->mmap_sem);
682 ret = apply_vma_lock_flags(start, len, 0);
683 up_write(¤t->mm->mmap_sem);
684
685 return ret;
686}
687
688
689
690
691
692
693
694
695
696
697
698static int apply_mlockall_flags(int flags)
699{
700 struct vm_area_struct * vma, * prev = NULL;
701 vm_flags_t to_add = 0;
702
703 current->mm->def_flags &= VM_LOCKED_CLEAR_MASK;
704 if (flags & MCL_FUTURE) {
705 current->mm->def_flags |= VM_LOCKED;
706
707 if (flags & MCL_ONFAULT)
708 current->mm->def_flags |= VM_LOCKONFAULT;
709
710 if (!(flags & MCL_CURRENT))
711 goto out;
712 }
713
714 if (flags & MCL_CURRENT) {
715 to_add |= VM_LOCKED;
716 if (flags & MCL_ONFAULT)
717 to_add |= VM_LOCKONFAULT;
718 }
719
720 for (vma = current->mm->mmap; vma ; vma = prev->vm_next) {
721 vm_flags_t newflags;
722
723 newflags = vma->vm_flags & VM_LOCKED_CLEAR_MASK;
724 newflags |= to_add;
725
726
727 mlock_fixup(vma, &prev, vma->vm_start, vma->vm_end, newflags);
728 cond_resched_rcu_qs();
729 }
730out:
731 return 0;
732}
733
734SYSCALL_DEFINE1(mlockall, int, flags)
735{
736 unsigned long lock_limit;
737 int ret;
738
739 if (!flags || (flags & ~(MCL_CURRENT | MCL_FUTURE | MCL_ONFAULT)))
740 return -EINVAL;
741
742 if (!can_do_mlock())
743 return -EPERM;
744
745 if (flags & MCL_CURRENT)
746 lru_add_drain_all();
747
748 lock_limit = rlimit(RLIMIT_MEMLOCK);
749 lock_limit >>= PAGE_SHIFT;
750
751 ret = -ENOMEM;
752 down_write(¤t->mm->mmap_sem);
753
754 if (!(flags & MCL_CURRENT) || (current->mm->total_vm <= lock_limit) ||
755 capable(CAP_IPC_LOCK))
756 ret = apply_mlockall_flags(flags);
757 up_write(¤t->mm->mmap_sem);
758 if (!ret && (flags & MCL_CURRENT))
759 mm_populate(0, TASK_SIZE);
760
761 return ret;
762}
763
764SYSCALL_DEFINE0(munlockall)
765{
766 int ret;
767
768 down_write(¤t->mm->mmap_sem);
769 ret = apply_mlockall_flags(0);
770 up_write(¤t->mm->mmap_sem);
771 return ret;
772}
773
774
775
776
777
778static DEFINE_SPINLOCK(shmlock_user_lock);
779
780int user_shm_lock(size_t size, struct user_struct *user)
781{
782 unsigned long lock_limit, locked;
783 int allowed = 0;
784
785 locked = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
786 lock_limit = rlimit(RLIMIT_MEMLOCK);
787 if (lock_limit == RLIM_INFINITY)
788 allowed = 1;
789 lock_limit >>= PAGE_SHIFT;
790 spin_lock(&shmlock_user_lock);
791 if (!allowed &&
792 locked + user->locked_shm > lock_limit && !capable(CAP_IPC_LOCK))
793 goto out;
794 get_uid(user);
795 user->locked_shm += locked;
796 allowed = 1;
797out:
798 spin_unlock(&shmlock_user_lock);
799 return allowed;
800}
801
802void user_shm_unlock(size_t size, struct user_struct *user)
803{
804 spin_lock(&shmlock_user_lock);
805 user->locked_shm -= (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
806 spin_unlock(&shmlock_user_lock);
807 free_uid(user);
808}
809