read_zero_pagealigned() locking fix
commitdbee2bf2f312a9d18fa3f305adc14e2ee58f65df
authorHugh Dickins <hugh@veritas.com>
Sun, 10 Dec 2006 10:18:43 +0000 (10 02:18 -0800)
committerGreg Kroah-Hartman <gregkh@suse.de>
Fri, 23 Feb 2007 23:49:52 +0000 (23 15:49 -0800)
treef15da0711e2452e6c7f90344087b217412eda39c
parentd84ad2cb50ba8c92df32ae6df47d413e5877e6ea
read_zero_pagealigned() locking fix

Ramiro Voicu hits the BUG_ON(!pte_none(*pte)) in zeromap_pte_range: kernel
bugzilla 7645.  Right: read_zero_pagealigned uses down_read of mmap_sem,
but another thread's racing read of /dev/zero, or a normal fault, can
easily set that pte again, in between zap_page_range and zeromap_page_range
getting there.  It's been wrong ever since 2.4.3.

The simple fix is to use down_write instead, but that would serialize reads
of /dev/zero more than at present: perhaps some app would be badly
affected.  So instead let zeromap_page_range return the error instead of
BUG_ON, and read_zero_pagealigned break to the slower clear_user loop in
that case - there's no need to optimize for it.

Use -EEXIST for when a pte is found: BUG_ON in mmap_zero (the other user of
zeromap_page_range), though it really isn't interesting there.  And since
mmap_zero wants -EAGAIN for out-of-memory, the zeromaps better return that
than -ENOMEM.

Signed-off-by: Hugh Dickins <hugh@veritas.com>
Cc: Ramiro Voicu: <Ramiro.Voicu@cern.ch>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Chris Wright <chrisw@sous-sol.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/char/mem.c
mm/memory.c