提交 9b79022c 编写于 作者: L Linus Torvalds

Fix 'get_user_pages_fast()' with non-page-aligned start address

Alexey Dobriyan reported trouble with LTP with the new fast-gup code,
and Johannes Weiner debugged it to non-page-aligned addresses, where the
new get_user_pages_fast() code would do all the wrong things, including
just traversing past the end of the requested area due to 'addr' never
matching 'end' exactly.

This is not a pretty fix, and we may actually want to move the alignment
into generic code, leaving just the core code per-arch, but Alexey
verified that the vmsplice01 LTP test doesn't crash with this.
Reported-and-tested-by: NAlexey Dobriyan <adobriyan@gmail.com>
Debugged-by: NJohannes Weiner <hannes@saeurebad.de>
Cc: Nick Piggin <npiggin@suse.de>
Cc: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
上级 34ee5501
...@@ -223,14 +223,17 @@ int get_user_pages_fast(unsigned long start, int nr_pages, int write, ...@@ -223,14 +223,17 @@ int get_user_pages_fast(unsigned long start, int nr_pages, int write,
struct page **pages) struct page **pages)
{ {
struct mm_struct *mm = current->mm; struct mm_struct *mm = current->mm;
unsigned long end = start + (nr_pages << PAGE_SHIFT); unsigned long addr, len, end;
unsigned long addr = start;
unsigned long next; unsigned long next;
pgd_t *pgdp; pgd_t *pgdp;
int nr = 0; int nr = 0;
start &= PAGE_MASK;
addr = start;
len = (unsigned long) nr_pages << PAGE_SHIFT;
end = start + len;
if (unlikely(!access_ok(write ? VERIFY_WRITE : VERIFY_READ, if (unlikely(!access_ok(write ? VERIFY_WRITE : VERIFY_READ,
start, nr_pages*PAGE_SIZE))) start, len)))
goto slow_irqon; goto slow_irqon;
/* /*
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册