diff --git a/mm/hugetlb.c b/mm/hugetlb.c index d3adafbea160..a4fede4be663 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -6169,16 +6169,20 @@ vm_fault_t hugetlb_fault(struct mm_struct *mm, struct vm_area_struct *vma, * NUMA hinting), so let normal hugetlb fault handling proceed. */ if (pte_protnone(vmf.orig_pte) && vma_is_accessible(vma) && - userfaultfd_rwp(vma) && huge_pte_uffd(vmf.orig_pte)) { + huge_pte_uffd(vmf.orig_pte)) { spinlock_t *ptl; pte_t pte; /* Sync: drop hugetlb locks before blocking in handle_userfault() */ - if (!userfaultfd_rwp_async(vma)) + if (userfaultfd_rwp(vma) && !userfaultfd_rwp_async(vma)) return hugetlb_handle_userfault(&vmf, mapping, VM_UFFD_RWP); ptl = huge_pte_lock(h, mm, vmf.pte); pte = huge_ptep_get(mm, vmf.address, vmf.pte); + /* + * TODO: fix all cases where uffd PTE bits remain in VMAs that + * are no longer registered with uffd. + */ if (pte_protnone(pte) && huge_pte_uffd(pte)) { unsigned int shift = huge_page_shift(h);