vfio iommu type1: Fix size argument to vfio_find_dma() in pin_pages/unpin_pages
Passing zero for the size to vfio_find_dma() isn't compatible with matching the start address of an existing vfio_dma. Doing so triggers a corner case. In vfio_find_dma(), when the start address is equal to dma->iova and size is 0, check for the end of search range makes it to take wrong side of RB-tree. That fails the search even though the address is present in mapped dma ranges. In functions pin_pages and unpin_pages, the iova which is being searched is base address of page to be pinned or unpinned. So here size should be set to PAGE_SIZE, as argument to vfio_find_dma(). Signed-off-by: Kirti Wankhede <kwankhede@nvidia.com> Signed-off-by: Neo Jia <cjia@nvidia.com> Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
This commit is contained in:
parent
7c03f42846
commit
2b8bb1d771
|
@ -581,7 +581,7 @@ static int vfio_iommu_type1_pin_pages(void *iommu_data,
|
|||
struct vfio_pfn *vpfn;
|
||||
|
||||
iova = user_pfn[i] << PAGE_SHIFT;
|
||||
dma = vfio_find_dma(iommu, iova, 0);
|
||||
dma = vfio_find_dma(iommu, iova, PAGE_SIZE);
|
||||
if (!dma) {
|
||||
ret = -EINVAL;
|
||||
goto pin_unwind;
|
||||
|
@ -622,7 +622,7 @@ pin_unwind:
|
|||
dma_addr_t iova;
|
||||
|
||||
iova = user_pfn[j] << PAGE_SHIFT;
|
||||
dma = vfio_find_dma(iommu, iova, 0);
|
||||
dma = vfio_find_dma(iommu, iova, PAGE_SIZE);
|
||||
vfio_unpin_page_external(dma, iova, do_accounting);
|
||||
phys_pfn[j] = 0;
|
||||
}
|
||||
|
@ -659,7 +659,7 @@ static int vfio_iommu_type1_unpin_pages(void *iommu_data,
|
|||
dma_addr_t iova;
|
||||
|
||||
iova = user_pfn[i] << PAGE_SHIFT;
|
||||
dma = vfio_find_dma(iommu, iova, 0);
|
||||
dma = vfio_find_dma(iommu, iova, PAGE_SIZE);
|
||||
if (!dma)
|
||||
goto unpin_exit;
|
||||
vfio_unpin_page_external(dma, iova, do_accounting);
|
||||
|
|
Loading…
Reference in New Issue