viommu_iotlb_sync_map() and viommu_flush_iotlb_all() read nr_endpoints
without the lock its writers take: the one place left after the endpoint
helpers were introduced. Order a sync only when the device holds the
domain, and read the count under the same lock as the writers.

Signed-off-by: Anlai Lu <[email protected]>
---
 drivers/iommu/virtio-iommu.c | 19 +++++++++++++++++--
 1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/drivers/iommu/virtio-iommu.c b/drivers/iommu/virtio-iommu.c
index 7119030dbcb3..8a93d5f0668f 100644
--- a/drivers/iommu/virtio-iommu.c
+++ b/drivers/iommu/virtio-iommu.c
@@ -131,6 +131,19 @@ static bool viommu_device_live(struct viommu_dev *viommu)
        return !viommu->removed;
 }
 
+/* Does the device hold this domain for at least one endpoint? */
+static bool viommu_domain_has_endpoint(struct viommu_domain *vdomain)
+{
+       unsigned long flags;
+       bool has;
+
+       spin_lock_irqsave(&vdomain->mappings_lock, flags);
+       has = vdomain->nr_endpoints != 0;
+       spin_unlock_irqrestore(&vdomain->mappings_lock, flags);
+
+       return has;
+}
+
 static int viommu_get_req_errno(void *buf, size_t len)
 {
        struct virtio_iommu_req_tail *tail = buf + len - sizeof(*tail);
@@ -1287,8 +1300,10 @@ static int viommu_iotlb_sync_map(struct iommu_domain 
*domain,
         * May be called before the viommu is initialized including
         * while creating direct mapping
         */
-       if (!vdomain->nr_endpoints)
+       if (!viommu_domain_has_endpoint(vdomain))
                return 0;
+
+       /* Wait for this batch's MAPs, whose outcome nobody looks at */
        return viommu_sync_req(vdomain->viommu);
 }
 
@@ -1300,7 +1315,7 @@ static void viommu_flush_iotlb_all(struct iommu_domain 
*domain)
         * May be called before the viommu is initialized including
         * while creating direct mapping
         */
-       if (!vdomain->nr_endpoints)
+       if (!viommu_domain_has_endpoint(vdomain))
                return;
        viommu_sync_req(vdomain->viommu);
 }
-- 
2.55.0


Reply via email to