From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail.linuxfoundation.org ([140.211.169.12]:59774 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752885AbeGDACl (ORCPT ); Tue, 3 Jul 2018 20:02:41 -0400 Date: Tue, 03 Jul 2018 17:02:39 -0700 From: akpm@linux-foundation.org To: stable@vger.kernel.org, mike.kravetz@oracle.com, david@redhat.com, aarcange@redhat.com, frankja@linux.ibm.com, akpm@linux-foundation.org, mm-commits@vger.kernel.org, torvalds@linux-foundation.org Subject: [patch 1/5] userfaultfd: hugetlbfs: fix userfaultfd_huge_must_wait() pte access Message-ID: <20180704000239.EeSBA%akpm@linux-foundation.org> Sender: stable-owner@vger.kernel.org List-ID: From: Janosch Frank Subject: userfaultfd: hugetlbfs: fix userfaultfd_huge_must_wait() pte access Use huge_ptep_get() to translate huge ptes to normal ptes so we can check them with the huge_pte_* functions. Otherwise some architectures will check the wrong values and will not wait for userspace to bring in the memory. Link: http://lkml.kernel.org/r/20180626132421.78084-1-frankja@linux.ibm.com Fixes: 369cd2121be4 ("userfaultfd: hugetlbfs: userfaultfd_huge_must_wait for hugepmd ranges") Signed-off-by: Janosch Frank Reviewed-by: David Hildenbrand Reviewed-by: Mike Kravetz Cc: Andrea Arcangeli Cc: Signed-off-by: Andrew Morton --- fs/userfaultfd.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff -puN fs/userfaultfd.c~userfaultfd-hugetlbfs-fix-userfaultfd_huge_must_wait-pte-access fs/userfaultfd.c --- a/fs/userfaultfd.c~userfaultfd-hugetlbfs-fix-userfaultfd_huge_must_wait-pte-access +++ a/fs/userfaultfd.c @@ -222,24 +222,26 @@ static inline bool userfaultfd_huge_must unsigned long reason) { struct mm_struct *mm = ctx->mm; - pte_t *pte; + pte_t *ptep, pte; bool ret = true; VM_BUG_ON(!rwsem_is_locked(&mm->mmap_sem)); - pte = huge_pte_offset(mm, address, vma_mmu_pagesize(vma)); - if (!pte) + ptep = huge_pte_offset(mm, address, vma_mmu_pagesize(vma)); + + if (!ptep) goto out; ret = false; + pte = huge_ptep_get(ptep); /* * Lockless access: we're in a wait_event so it's ok if it * changes under us. */ - if (huge_pte_none(*pte)) + if (huge_pte_none(pte)) ret = true; - if (!huge_pte_write(*pte) && (reason & VM_UFFD_WP)) + if (!huge_pte_write(pte) && (reason & VM_UFFD_WP)) ret = true; out: return ret; _