mm/hmm: add missing unmaps of the ptep during hmm_vma_handle_pte()
Many of the direct returns of error skipped doing the pte_unmap(). All non zero exit paths must unmap the pte. The pte_unmap() is split unnaturally like this because some of the error exit paths trigger a sleep and must release the lock before sleeping. Fixes:992de9a8b7
("mm/hmm: allow to mirror vma of a file on a DAX backed filesystem") Fixes:53f5c3f489
("mm/hmm: factor out pte and pmd handling to simplify hmm_vma_walk_pmd()") Reviewed-by: Ralph Campbell <rcampbell@nvidia.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
This commit is contained in:
Родитель
f8788d86ab
Коммит
dfdc22078f
8
mm/hmm.c
8
mm/hmm.c
|
@ -325,6 +325,7 @@ static int hmm_vma_handle_pte(struct mm_walk *walk, unsigned long addr,
|
|||
}
|
||||
|
||||
/* Report error for everything else */
|
||||
pte_unmap(ptep);
|
||||
*pfn = range->values[HMM_PFN_ERROR];
|
||||
return -EFAULT;
|
||||
} else {
|
||||
|
@ -339,10 +340,13 @@ static int hmm_vma_handle_pte(struct mm_walk *walk, unsigned long addr,
|
|||
if (pte_devmap(pte)) {
|
||||
hmm_vma_walk->pgmap = get_dev_pagemap(pte_pfn(pte),
|
||||
hmm_vma_walk->pgmap);
|
||||
if (unlikely(!hmm_vma_walk->pgmap))
|
||||
if (unlikely(!hmm_vma_walk->pgmap)) {
|
||||
pte_unmap(ptep);
|
||||
return -EBUSY;
|
||||
}
|
||||
} else if (IS_ENABLED(CONFIG_ARCH_HAS_PTE_SPECIAL) && pte_special(pte)) {
|
||||
if (!is_zero_pfn(pte_pfn(pte))) {
|
||||
pte_unmap(ptep);
|
||||
*pfn = range->values[HMM_PFN_SPECIAL];
|
||||
return -EFAULT;
|
||||
}
|
||||
|
@ -437,7 +441,7 @@ again:
|
|||
|
||||
r = hmm_vma_handle_pte(walk, addr, end, pmdp, ptep, &pfns[i]);
|
||||
if (r) {
|
||||
/* hmm_vma_handle_pte() did unmap pte directory */
|
||||
/* hmm_vma_handle_pte() did pte_unmap() */
|
||||
hmm_vma_walk->last = addr;
|
||||
return r;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче