Commit 2f16b7a1 authored by Hugh Dickins's avatar Hugh Dickins Committed by Linus Torvalds

[PATCH] VmLib wrapped: mprotect flags

Sometimes /proc/<pid>/status shows VmLib: 42949..... kB.

mprotect_fixup must note oldflags on entry: if vma_merge is successful,
vma->vm_flags afterwards may be either the oldflags or the newflags, and
the extent of the change will be less than the extent of the vma.

And let's use unsigned long for these flags throughout.
Signed-off-by: default avatarHugh Dickins <hugh@veritas.com>
Acked-by: default avatarWilliam Lee Irwin III <wli@holomorphy.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 8c54a50c
...@@ -111,15 +111,17 @@ change_protection(struct vm_area_struct *vma, unsigned long start, ...@@ -111,15 +111,17 @@ change_protection(struct vm_area_struct *vma, unsigned long start,
static int static int
mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev, mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
unsigned long start, unsigned long end, unsigned int newflags) unsigned long start, unsigned long end, unsigned long newflags)
{ {
struct mm_struct * mm = vma->vm_mm; struct mm_struct * mm = vma->vm_mm;
unsigned long oldflags = vma->vm_flags;
long nrpages = (end - start) >> PAGE_SHIFT;
unsigned long charged = 0; unsigned long charged = 0;
pgprot_t newprot; pgprot_t newprot;
pgoff_t pgoff; pgoff_t pgoff;
int error; int error;
if (newflags == vma->vm_flags) { if (newflags == oldflags) {
*pprev = vma; *pprev = vma;
return 0; return 0;
} }
...@@ -133,8 +135,8 @@ mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev, ...@@ -133,8 +135,8 @@ mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
* a MAP_NORESERVE private mapping to writable will now reserve. * a MAP_NORESERVE private mapping to writable will now reserve.
*/ */
if (newflags & VM_WRITE) { if (newflags & VM_WRITE) {
if (!(vma->vm_flags & (VM_ACCOUNT|VM_WRITE|VM_SHARED|VM_HUGETLB))) { if (!(oldflags & (VM_ACCOUNT|VM_WRITE|VM_SHARED|VM_HUGETLB))) {
charged = (end - start) >> PAGE_SHIFT; charged = nrpages;
if (security_vm_enough_memory(charged)) if (security_vm_enough_memory(charged))
return -ENOMEM; return -ENOMEM;
newflags |= VM_ACCOUNT; newflags |= VM_ACCOUNT;
...@@ -176,11 +178,11 @@ mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev, ...@@ -176,11 +178,11 @@ mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
* vm_flags and vm_page_prot are protected by the mmap_sem * vm_flags and vm_page_prot are protected by the mmap_sem
* held in write mode. * held in write mode.
*/ */
vm_stat_unaccount(vma);
vma->vm_flags = newflags; vma->vm_flags = newflags;
vma->vm_page_prot = newprot; vma->vm_page_prot = newprot;
change_protection(vma, start, end, newprot); change_protection(vma, start, end, newprot);
vm_stat_account(vma); __vm_stat_account(mm, oldflags, vma->vm_file, -nrpages);
__vm_stat_account(mm, newflags, vma->vm_file, nrpages);
return 0; return 0;
fail: fail:
...@@ -246,7 +248,7 @@ sys_mprotect(unsigned long start, size_t len, unsigned long prot) ...@@ -246,7 +248,7 @@ sys_mprotect(unsigned long start, size_t len, unsigned long prot)
prev = vma; prev = vma;
for (nstart = start ; ; ) { for (nstart = start ; ; ) {
unsigned int newflags; unsigned long newflags;
/* Here we know that vma->vm_start <= nstart < vma->vm_end. */ /* Here we know that vma->vm_start <= nstart < vma->vm_end. */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment