Thread (14 messages) 14 messages, 3 authors, 2023-09-25

Re: [PATCH v2 1/2] iommu/virtio: Make use of ops->iotlb_sync_map

From: Jason Gunthorpe <jgg@ziepe.ca>
Date: 2023-09-19 14:48:15
Also in: linux-iommu, lkml

On Tue, Sep 19, 2023 at 09:15:19AM +0100, Jean-Philippe Brucker wrote:
On Mon, Sep 18, 2023 at 05:37:47PM +0100, Robin Murphy wrote:
quoted
quoted
diff --git a/drivers/iommu/virtio-iommu.c b/drivers/iommu/virtio-iommu.c
index 17dcd826f5c2..3649586f0e5c 100644
--- a/drivers/iommu/virtio-iommu.c
+++ b/drivers/iommu/virtio-iommu.c
@@ -189,6 +189,12 @@ static int viommu_sync_req(struct viommu_dev *viommu)
  	int ret;
  	unsigned long flags;
+	/*
+	 * .iotlb_sync_map and .flush_iotlb_all may be called before the viommu
+	 * is initialized e.g. via iommu_create_device_direct_mappings()
+	 */
+	if (!viommu)
+		return 0;
Minor nit: I'd be inclined to make that check explicitly in the places where
it definitely is expected, rather than allowing *any* sync to silently do
nothing if called incorrectly. Plus then they could use
vdomain->nr_endpoints for consistency with the equivalent checks elsewhere
(it did take me a moment to figure out how we could get to .iotlb_sync_map
with a NULL viommu without viommu_map_pages() blowing up first...)
This makes more sense to me

Ultimately this driver should reach a point where every iommu_domain
always has a non-null domain->viommu because it will be set during
alloc.

But it can still have nr_endpoints == 0, doesn't it make sense to
avoid sync in this case?

(btw this driver is missing locking around vdomain->nr_endpoints)
They're not strictly equivalent: this check works around a temporary issue
with the IOMMU core, which calls map/unmap before the domain is
finalized.
Where? The above points to iommu_create_device_direct_mappings() but
it doesn't because the pgsize_bitmap == 0:

static int iommu_create_device_direct_mappings(struct iommu_domain *domain,
					       struct device *dev)
{
	struct iommu_resv_region *entry;
	struct list_head mappings;
	unsigned long pg_size;
	int ret = 0;

	pg_size = domain->pgsize_bitmap ? 1UL << __ffs(domain->pgsize_bitmap) : 0;
	INIT_LIST_HEAD(&mappings);

	if (WARN_ON_ONCE(iommu_is_dma_domain(domain) && !pg_size))

Indeed, the driver should be failing all map's until the domain is
finalized because it has no way to check the IOVA matches the eventual
aperture.

Jason
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help