x86: don't use 'access_ok()' as a range check in get_user_pages_fast()
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 22 Jun 2009 17:25:25 +0000 (10:25 -0700)
committerGreg Kroah-Hartman <gregkh@suse.de>
Thu, 30 Jul 2009 23:06:08 +0000 (16:06 -0700)
commit034b03f44cba675abf2550324c4b2ebc1a4a85b3
treee487e1c9ab021be97f323383efca6b88cd1a3cc8
parent30629ea3f895f3329530598d6b048e116a9bc593
x86: don't use 'access_ok()' as a range check in get_user_pages_fast()

[ Upstream commit 7f8189068726492950bf1a2dcfd9b51314560abf - modified
  for stable to not use the sloppy __VIRTUAL_MASK_SHIFT ]

It's really not right to use 'access_ok()', since that is meant for the
normal "get_user()" and "copy_from/to_user()" accesses, which are done
through the TLB, rather than through the page tables.

Why? access_ok() does both too few, and too many checks.  Too many,
because it is meant for regular kernel accesses that will not honor the
'user' bit in the page tables, and because it honors the USER_DS vs
KERNEL_DS distinction that we shouldn't care about in GUP.  And too few,
because it doesn't do the 'canonical' check on the address on x86-64,
since the TLB will do that for us.

So instead of using a function that isn't meant for this, and does
something else and much more complicated, just do the real rules: we
don't want the range to overflow, and on x86-64, we want it to be a
canonical low address (on 32-bit, all addresses are canonical).

Acked-by: Ingo Molnar <mingo@elte.hu>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
arch/x86/mm/gup.c