Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e66aa5bc authored by Susheel Khiani's avatar Susheel Khiani Committed by Patrick Daly
Browse files

iommu/iommu-debug: Maintain list of domains during alloc



Current list of domains in iommu-debug was only
maintained during attach/detach calls. But for
masters like graphics this won't account for all
the domains, as it allocates multiple different
domains but attaches only one domain at a time.

Add support for maintaining list of unattached
domains too by adding them to debug_attachments
list during domain alloc but keeping dev as NULL.
We would add entry in debugfs attachment directory
only on actual attach call.

Change-Id: Ifde043e5c39f356b4187a30cbdf020ee943618f1
Signed-off-by: default avatarSusheel Khiani <skhiani@codeaurora.org>
Signed-off-by: default avatarPatrick Daly <pdaly@codeaurora.org>
parent 70b7511c
Loading
Loading
Loading
Loading
+64 −17
Original line number Diff line number Diff line
@@ -97,8 +97,7 @@ static int iommu_debug_attach_add_debugfs(
	return -EIO;
}

void iommu_debug_attach_device(struct iommu_domain *domain,
			       struct device *dev)
void iommu_debug_domain_add(struct iommu_domain *domain)
{
	struct iommu_debug_attachment *attach;

@@ -109,6 +108,47 @@ void iommu_debug_attach_device(struct iommu_domain *domain,
		goto out_unlock;

	attach->domain = domain;
	attach->dev = NULL;
	list_add(&attach->list, &iommu_debug_attachments);

out_unlock:
	mutex_unlock(&iommu_debug_attachments_lock);
}

void iommu_debug_domain_remove(struct iommu_domain *domain)
{
	struct iommu_debug_attachment *it;

	mutex_lock(&iommu_debug_attachments_lock);
	list_for_each_entry(it, &iommu_debug_attachments, list)
		if (it->domain == domain && it->dev == NULL)
			break;

	if (&it->list == &iommu_debug_attachments) {
		WARN(1, "Couldn't find debug attachment for domain=0x%p",
				domain);
	} else {
		list_del(&it->list);
		kfree(it);
	}
	mutex_unlock(&iommu_debug_attachments_lock);
}

void iommu_debug_attach_device(struct iommu_domain *domain,
			       struct device *dev)
{
	struct iommu_debug_attachment *attach;

	mutex_lock(&iommu_debug_attachments_lock);

	list_for_each_entry(attach, &iommu_debug_attachments, list)
		if (attach->domain == domain && attach->dev == NULL)
			break;

	if (&attach->list == &iommu_debug_attachments) {
		WARN(1, "Couldn't find debug attachment for domain=0x%p dev=%s",
		     domain, dev_name(dev));
	} else {
		attach->dev = dev;

		/*
@@ -118,11 +158,11 @@ void iommu_debug_attach_device(struct iommu_domain *domain,
		 * directory (by calling debugfs_create_dir with a NULL
		 * parent). These will be flushed out later once we init.
		 */

		if (debugfs_attachments_dir)
			iommu_debug_attach_add_debugfs(attach);
	}

	list_add(&attach->list, &iommu_debug_attachments);
out_unlock:
	mutex_unlock(&iommu_debug_attachments_lock);
}

@@ -140,9 +180,15 @@ void iommu_debug_detach_device(struct iommu_domain *domain,
		WARN(1, "Couldn't find debug attachment for domain=0x%p dev=%s",
		     domain, dev_name(dev));
	} else {
		list_del(&it->list);
		/*
		 * Just remove debugfs entry and mark dev as NULL on
		 * iommu_detach call. We would remove the actual
		 * attachment entry from the list only on domain_free call.
		 * This is to ensure we keep track of unattached domains too.
		 */

		debugfs_remove_recursive(it->dentry);
		kfree(it);
		it->dev = NULL;
	}
	mutex_unlock(&iommu_debug_attachments_lock);
}
@@ -163,6 +209,7 @@ static int iommu_debug_init_tracking(void)

	/* set up debugfs entries for attachments made during early boot */
	list_for_each_entry(attach, &iommu_debug_attachments, list)
		if (attach->dev)
			iommu_debug_attach_add_debugfs(attach);

out_unlock:
+10 −0
Original line number Diff line number Diff line
@@ -17,6 +17,8 @@

void iommu_debug_attach_device(struct iommu_domain *domain, struct device *dev);
void iommu_debug_detach_device(struct iommu_domain *domain, struct device *dev);
void iommu_debug_domain_add(struct iommu_domain *domain);
void iommu_debug_domain_remove(struct iommu_domain *domain);

#else  /* !CONFIG_IOMMU_DEBUG_TRACKING */

@@ -30,6 +32,14 @@ static inline void iommu_debug_detach_device(struct iommu_domain *domain,
{
}

static inline void iommu_debug_domain_add(struct iommu_domain *domain)
{
}

static inline void iommu_debug_domain_remove(struct iommu_domain *domain)
{
}

#endif  /* CONFIG_IOMMU_DEBUG_TRACKING */

#endif /* IOMMU_DEBUG_H */
+3 −0
Original line number Diff line number Diff line
@@ -1066,6 +1066,8 @@ static struct iommu_domain *__iommu_domain_alloc(struct bus_type *bus,
	/* Assume all sizes by default; the driver may override this later */
	domain->pgsize_bitmap  = bus->iommu_ops->pgsize_bitmap;

	iommu_debug_domain_add(domain);

	return domain;
}

@@ -1077,6 +1079,7 @@ EXPORT_SYMBOL_GPL(iommu_domain_alloc);

void iommu_domain_free(struct iommu_domain *domain)
{
	iommu_debug_domain_remove(domain);
	domain->ops->domain_free(domain);
}
EXPORT_SYMBOL_GPL(iommu_domain_free);