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

Commit 6dd80250 authored by Patrick Daly's avatar Patrick Daly
Browse files

iommu: iommu-debug: Use iommu_attach_group instead



Multiple device may be in the same iommu group. In this case
iommu_attach_group must be used instead of iommu_attach_device.
Additionally, check for any existing domains for the group prior
to attaching a new domain, since overwriting an existing domain
may cause an iommu fault.

Change-Id: I4e042ae0a1fe927e8f12f999c1393b5f0526cf4d
Signed-off-by: default avatarPatrick Daly <pdaly@codeaurora.org>
parent ad9df1f9
Loading
Loading
Loading
Loading
+20 −10
Original line number Diff line number Diff line
@@ -548,7 +548,7 @@ static void iommu_debug_device_profiling(struct seq_file *s, struct device *dev,
		}
	}

	if (iommu_attach_device(domain, dev)) {
	if (iommu_attach_group(domain, dev->iommu_group)) {
		seq_puts(s,
			 "Couldn't attach new domain to device. Is it already attached?\n");
		goto out_domain_free;
@@ -669,7 +669,7 @@ static void iommu_debug_device_profiling(struct seq_file *s, struct device *dev,
	}

out_detach:
	iommu_detach_device(domain, dev);
	iommu_detach_group(domain, dev->iommu_group);
out_domain_free:
	iommu_domain_free(domain);
}
@@ -1451,6 +1451,8 @@ static const struct file_operations iommu_debug_functional_arm_dma_api_fops = {
static int iommu_debug_attach_do_attach(struct iommu_debug_device *ddev,
					int val, bool is_secure)
{
	struct iommu_group *group = ddev->dev->iommu_group;

	ddev->domain = iommu_domain_alloc(&platform_bus_type);
	if (!ddev->domain) {
		pr_err("Couldn't allocate domain\n");
@@ -1464,8 +1466,8 @@ static int iommu_debug_attach_do_attach(struct iommu_debug_device *ddev,
		goto out_domain_free;
	}

	if (iommu_attach_device(ddev->domain, ddev->dev)) {
		pr_err("Couldn't attach new domain to device. Is it already attached?\n");
	if (iommu_attach_group(ddev->domain, group)) {
		dev_err(ddev->dev, "Couldn't attach new domain to device\n");
		goto out_domain_free;
	}

@@ -1483,6 +1485,8 @@ static ssize_t __iommu_debug_attach_write(struct file *file,
					  bool is_secure)
{
	struct iommu_debug_device *ddev = file->private_data;
	struct device *dev = ddev->dev;
	struct iommu_domain *domain;
	ssize_t retval;
	int val;

@@ -1494,12 +1498,15 @@ static ssize_t __iommu_debug_attach_write(struct file *file,

	if (val) {
		if (ddev->domain) {
			pr_err("Already attached.\n");
			pr_err("Iommu-Debug is already attached?\n");
			retval = -EINVAL;
			goto out;
		}
		if (WARN(ddev->dev->archdata.iommu,
			 "Attachment tracking out of sync with device\n")) {

		domain = iommu_get_domain_for_dev(dev);
		if (domain) {
			pr_err("Another driver is using this device's iommu\n"
				"Iommu-Debug cannot be used concurrently\n");
			retval = -EINVAL;
			goto out;
		}
@@ -1510,11 +1517,11 @@ static ssize_t __iommu_debug_attach_write(struct file *file,
		pr_err("Attached\n");
	} else {
		if (!ddev->domain) {
			pr_err("No domain. Did you already attach?\n");
			pr_err("Iommu-Debug is not attached?\n");
			retval = -EINVAL;
			goto out;
		}
		iommu_detach_device(ddev->domain, ddev->dev);
		iommu_detach_group(ddev->domain, dev->iommu_group);
		iommu_domain_free(ddev->domain);
		ddev->domain = NULL;
		pr_err("Detached\n");
@@ -1566,7 +1573,6 @@ static ssize_t iommu_debug_attach_write_secure(struct file *file,
{
	return __iommu_debug_attach_write(file, ubuf, count, offset,
					  true);

}

static const struct file_operations iommu_debug_secure_attach_fops = {
@@ -1868,6 +1874,10 @@ static int snarf_iommu_devices(struct device *dev, void *ignored)
	if (!of_find_property(dev->of_node, "iommus", NULL))
		return 0;

	/* Hold a reference count */
	if (!iommu_group_get(dev))
		return 0;

	ddev = kzalloc(sizeof(*ddev), GFP_KERNEL);
	if (!ddev)
		return -ENODEV;