mirror of https://github.com/torvalds/linux.git
Before this commit, it was possible to create end of address space
mappings, but unmapping them via VFIO_IOMMU_UNMAP_DMA, replaying them
for newly added iommu domains, and querying their dirty pages via
VFIO_DMA_UNMAP_FLAG_GET_DIRTY_BITMAP was broken due to bugs caused by
comparisons against (iova + size) expressions, which overflow to zero.
Additionally, there appears to be a page pinning leak in the
vfio_iommu_type1_release() path, since vfio_unmap_unpin()'s loop body
where unmap_unpin_*() are called will never be entered due to overflow
of (iova + size) to zero.
This commit handles DMA map/unmap operations up to the addressable
limit by comparing against inclusive end-of-range limits, and changing
iteration to perform relative traversals across range sizes, rather than
absolute traversals across addresses.
vfio_link_dma() inserts a zero-sized vfio_dma into the rb-tree, and is
only used for that purpose, so discard the size from consideration for
the insertion point.
Tested-by: Alejandro Jimenez <alejandro.j.jimenez@oracle.com>
Fixes:
|
||
|---|---|---|
| .. | ||
| cdx | ||
| fsl-mc | ||
| mdev | ||
| pci | ||
| platform | ||
| Kconfig | ||
| Makefile | ||
| container.c | ||
| debugfs.c | ||
| device_cdev.c | ||
| group.c | ||
| iommufd.c | ||
| vfio.h | ||
| vfio_iommu_spapr_tce.c | ||
| vfio_iommu_type1.c | ||
| vfio_main.c | ||
| virqfd.c | ||