X-Git-Url: https://repo.jachan.dev/linux.git/blobdiff_plain/d532dd102151cc69fcd00b13e5a9689b23c0c8d9..a88d0092b24b:/mm/hmm.c diff --git a/mm/hmm.c b/mm/hmm.c index 601a99ce3c84..6a151c09de5e 100644 --- a/mm/hmm.c +++ b/mm/hmm.c @@ -492,8 +492,21 @@ static int hmm_vma_walk_hugetlb_entry(pte_t *pte, unsigned long hmask, required_fault = hmm_pte_need_fault(hmm_vma_walk, pfn_req_flags, cpu_flags); if (required_fault) { + int ret; + spin_unlock(ptl); - return hmm_vma_fault(addr, end, required_fault, walk); + hugetlb_vma_unlock_read(vma); + /* + * Avoid deadlock: drop the vma lock before calling + * hmm_vma_fault(), which will itself potentially take and + * drop the vma lock. This is also correct from a + * protection point of view, because there is no further + * use here of either pte or ptl after dropping the vma + * lock. + */ + ret = hmm_vma_fault(addr, end, required_fault, walk); + hugetlb_vma_lock_read(vma); + return ret; } pfn = pte_pfn(entry) + ((start & ~hmask) >> PAGE_SHIFT);