Commit d2fa8630 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] mlock error handling fix

make_pages_present() can fail: propagate that failure back.

Spotted by Bill Irwin.
parent c3d9871e
...@@ -1655,6 +1655,8 @@ int make_pages_present(unsigned long addr, unsigned long end) ...@@ -1655,6 +1655,8 @@ int make_pages_present(unsigned long addr, unsigned long end)
len = (end+PAGE_SIZE-1)/PAGE_SIZE-addr/PAGE_SIZE; len = (end+PAGE_SIZE-1)/PAGE_SIZE-addr/PAGE_SIZE;
ret = get_user_pages(current, current->mm, addr, ret = get_user_pages(current, current->mm, addr,
len, write, 0, NULL, NULL); len, write, 0, NULL, NULL);
if (ret < 0)
return ret;
return ret == len ? 0 : -1; return ret == len ? 0 : -1;
} }
......
...@@ -13,21 +13,24 @@ static int mlock_fixup(struct vm_area_struct * vma, ...@@ -13,21 +13,24 @@ static int mlock_fixup(struct vm_area_struct * vma,
unsigned long start, unsigned long end, unsigned int newflags) unsigned long start, unsigned long end, unsigned int newflags)
{ {
struct mm_struct * mm = vma->vm_mm; struct mm_struct * mm = vma->vm_mm;
int pages, error; int pages;
int ret = 0;
if (newflags == vma->vm_flags) if (newflags == vma->vm_flags)
return 0; goto out;
if (start != vma->vm_start) { if (start != vma->vm_start) {
error = split_vma(mm, vma, start, 1); if (split_vma(mm, vma, start, 1)) {
if (error) ret = -EAGAIN;
return -EAGAIN; goto out;
}
} }
if (end != vma->vm_end) { if (end != vma->vm_end) {
error = split_vma(mm, vma, end, 0); if (split_vma(mm, vma, end, 0)) {
if (error) ret = -EAGAIN;
return -EAGAIN; goto out;
}
} }
spin_lock(&mm->page_table_lock); spin_lock(&mm->page_table_lock);
...@@ -40,11 +43,12 @@ static int mlock_fixup(struct vm_area_struct * vma, ...@@ -40,11 +43,12 @@ static int mlock_fixup(struct vm_area_struct * vma,
pages = (end - start) >> PAGE_SHIFT; pages = (end - start) >> PAGE_SHIFT;
if (newflags & VM_LOCKED) { if (newflags & VM_LOCKED) {
pages = -pages; pages = -pages;
make_pages_present(start, end); ret = make_pages_present(start, end);
} }
vma->vm_mm->locked_vm -= pages; vma->vm_mm->locked_vm -= pages;
return 0; out:
return ret;
} }
static int do_mlock(unsigned long start, size_t len, int on) static int do_mlock(unsigned long start, size_t len, int on)
......
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