On 2022/4/29 05:09, Joao Martins wrote:
Today, the dirty state is lost and the page wouldn't be migrated to destination potentially leading the guest into error. Add an unmap API that reads the dirty bit and sets it in the user passed bitmap. This unmap iommu API tackles a potentially racy update to the dirty bit *when* doing DMA on a iova that is being unmapped at the same time. The new unmap_read_dirty/unmap_pages_read_dirty does not replace the unmap pages, but rather only when explicit called with an dirty bitmap data passed in. It could be said that the guest is buggy and rather than a special unmap path tackling the theoretical race ... it would suffice fetching the dirty bits (with GET_DIRTY_IOVA), and then unmap the IOVA.
I am not sure whether this API could solve the race. size_t iommu_unmap(struct iommu_domain *domain, unsigned long iova, size_t size) { struct iommu_iotlb_gather iotlb_gather; size_t ret; iommu_iotlb_gather_init(&iotlb_gather); ret = __iommu_unmap(domain, iova, size, &iotlb_gather); iommu_iotlb_sync(domain, &iotlb_gather); return ret; } The PTEs are cleared before iotlb invalidation. What if a DMA write happens after PTE clearing and before the iotlb invalidation with the PTE happening to be cached? Best regards, baolu