4 * (C) Copyright 1995 Linus Torvalds
5 * (C) Copyright 2002 Christoph Hellwig
8 #include <linux/mman.h>
12 static int mlock_fixup(struct vm_area_struct
* vma
,
13 unsigned long start
, unsigned long end
, unsigned int newflags
)
15 struct mm_struct
* mm
= vma
->vm_mm
;
18 if (newflags
== vma
->vm_flags
)
21 if (start
!= vma
->vm_start
) {
22 error
= split_vma(mm
, vma
, start
, 1);
27 if (end
!= vma
->vm_end
) {
28 error
= split_vma(mm
, vma
, end
, 0);
33 spin_lock(&mm
->page_table_lock
);
34 vma
->vm_flags
= newflags
;
35 spin_unlock(&mm
->page_table_lock
);
38 * Keep track of amount of locked VM.
40 pages
= (end
- start
) >> PAGE_SHIFT
;
41 if (newflags
& VM_LOCKED
) {
43 make_pages_present(start
, end
);
46 vma
->vm_mm
->locked_vm
-= pages
;
50 static int do_mlock(unsigned long start
, size_t len
, int on
)
52 unsigned long nstart
, end
, tmp
;
53 struct vm_area_struct
* vma
, * next
;
56 if (on
&& !capable(CAP_IPC_LOCK
))
58 len
= PAGE_ALIGN(len
);
64 vma
= find_vma(current
->mm
, start
);
65 if (!vma
|| vma
->vm_start
> start
)
68 for (nstart
= start
; ; ) {
69 unsigned int newflags
;
71 /* Here we know that vma->vm_start <= nstart < vma->vm_end. */
73 newflags
= vma
->vm_flags
| VM_LOCKED
;
75 newflags
&= ~VM_LOCKED
;
77 if (vma
->vm_end
>= end
) {
78 error
= mlock_fixup(vma
, nstart
, end
, newflags
);
84 error
= mlock_fixup(vma
, nstart
, tmp
, newflags
);
89 if (!vma
|| vma
->vm_start
!= nstart
) {
97 asmlinkage
long sys_mlock(unsigned long start
, size_t len
)
100 unsigned long lock_limit
;
103 down_write(¤t
->mm
->mmap_sem
);
104 len
= PAGE_ALIGN(len
+ (start
& ~PAGE_MASK
));
107 locked
= len
>> PAGE_SHIFT
;
108 locked
+= current
->mm
->locked_vm
;
110 lock_limit
= current
->rlim
[RLIMIT_MEMLOCK
].rlim_cur
;
111 lock_limit
>>= PAGE_SHIFT
;
113 /* check against resource limits */
114 if (locked
> lock_limit
)
117 /* we may lock at most half of physical memory... */
118 /* (this check is pretty bogus, but doesn't hurt) */
119 if (locked
> num_physpages
/2)
122 error
= do_mlock(start
, len
, 1);
124 up_write(¤t
->mm
->mmap_sem
);
128 asmlinkage
long sys_munlock(unsigned long start
, size_t len
)
132 down_write(¤t
->mm
->mmap_sem
);
133 len
= PAGE_ALIGN(len
+ (start
& ~PAGE_MASK
));
135 ret
= do_mlock(start
, len
, 0);
136 up_write(¤t
->mm
->mmap_sem
);
140 static int do_mlockall(int flags
)
143 unsigned int def_flags
;
144 struct vm_area_struct
* vma
;
146 if (!capable(CAP_IPC_LOCK
))
150 if (flags
& MCL_FUTURE
)
151 def_flags
= VM_LOCKED
;
152 current
->mm
->def_flags
= def_flags
;
155 for (vma
= current
->mm
->mmap
; vma
; vma
= vma
->vm_next
) {
156 unsigned int newflags
;
158 newflags
= vma
->vm_flags
| VM_LOCKED
;
159 if (!(flags
& MCL_CURRENT
))
160 newflags
&= ~VM_LOCKED
;
161 error
= mlock_fixup(vma
, vma
->vm_start
, vma
->vm_end
, newflags
);
168 asmlinkage
long sys_mlockall(int flags
)
170 unsigned long lock_limit
;
173 down_write(¤t
->mm
->mmap_sem
);
174 if (!flags
|| (flags
& ~(MCL_CURRENT
| MCL_FUTURE
)))
177 lock_limit
= current
->rlim
[RLIMIT_MEMLOCK
].rlim_cur
;
178 lock_limit
>>= PAGE_SHIFT
;
181 if (current
->mm
->total_vm
> lock_limit
)
184 /* we may lock at most half of physical memory... */
185 /* (this check is pretty bogus, but doesn't hurt) */
186 if (current
->mm
->total_vm
> num_physpages
/2)
189 ret
= do_mlockall(flags
);
191 up_write(¤t
->mm
->mmap_sem
);
195 asmlinkage
long sys_munlockall(void)
199 down_write(¤t
->mm
->mmap_sem
);
200 ret
= do_mlockall(0);
201 up_write(¤t
->mm
->mmap_sem
);