On Tue, 2013-12-10 at 23:42 +0100, Thomas Gleixner wrote: > On Tue, 10 Dec 2013, Linus Torvalds wrote: > > > On Tue, Dec 10, 2013 at 1:57 PM, Linus Torvalds > > <torva...@linux-foundation.org> wrote: > > > > > > So it looks like __get_user_pages_fast() fails, and keeps failing. > > > > Hmm.. Is any of the addresses unchecked, perhaps? > > __get_user_pages_fast() does an access_ok() check, while > > get_user_pages_fast() does *not* seem to do one. > > > > That looks a bit dangerous. Yeah, users should have checked the > > address range, but there really is no reason not to do it in > > get_user_pages_fast(). > > > > And it looks like the futex code is actually seriously buggered. It > > only does the access_ok() check for the non-shared case. > > > > Why? > > The !fshared case is the fast path which does not even reach > get_user_pages_fast(). > > We had this discussion some time ago already, where the access_ok() > check was missing in the !fshared case or the check was buggered for > some reason. Need to dig up the gory details. > > And yes, I remember that we do not do an extra check for the fshared > case, because get_user_pages_fast() should do it for us already. If > not we are fubared not only in the futex code. > > But there is a subtle detail: > > err = get_user_pages_fast(address, 1, 1, &page); > > So we ask for write access as the write argument is 1. In case that > fails we have that fallback path: > > /* > * If write access is not required (eg. FUTEX_WAIT), try > * and get read-only access. > */ > if (err == -EFAULT && rw == VERIFY_READ) { > err = get_user_pages_fast(address, 1, 0, &page); > > That's a legitimate use case. And futex_requeue only requests > VERIFY_READ for the !requeue_pi case. > > Now, if that map is RO, i.e. we took the fallback path then the THP > one will fail as it has write=1 unconditionally. > > if (likely(__get_user_pages_fast(address, 1, 1, &page) == 1)) >
Is there a reason THP requires unconditional rw? Andrea? Or is the following actually the answer here? diff --git a/kernel/futex.c b/kernel/futex.c index 80ba086..02febad 100644 --- a/kernel/futex.c +++ b/kernel/futex.c @@ -288,7 +288,7 @@ again: put_page(page); /* serialize against __split_huge_page_splitting() */ local_irq_disable(); - if (likely(__get_user_pages_fast(address, 1, 1, &page) == 1)) { + if (likely(__get_user_pages_fast(address, 1, !ro, &page) == 1)) { page_head = compound_head(page); /* * page_head is valid pointer but we must pin -- Darren Hart Intel Open Source Technology Center Yocto Project - Linux Kernel -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/