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

Commit a03b0808 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "iommu: qti: Track iommu domains"

parents 60b33cc6 f1746fc8
Loading
Loading
Loading
Loading
+11 −14
Original line number Diff line number Diff line
@@ -367,6 +367,14 @@ config SPAPR_TCE_IOMMU
	  Enables bits of IOMMU API required by VFIO. The iommu_ops
	  is not implemented as it is not necessary for VFIO.

config QTI_IOMMU_SUPPORT
	tristate "Support for QTI iommu drivers"
	help
	  The QTI GPU device may switch between multiple iommu domains,
	  depending on usecase. This introduces a need to track all such
	  domains in a non-driver specific manner.
	  If in doubt say N.

# ARM IOMMU support
config ARM_SMMU
	bool "ARM Ltd. System MMU (SMMU) Support"
@@ -375,6 +383,7 @@ config ARM_SMMU
	select IOMMU_IO_PGTABLE_LPAE
	select ARM_DMA_USE_IOMMU if ARM
	select ARM64_DMA_USE_IOMMU if ARM64
	select QTI_IOMMU_SUPPORT
	help
	  Support for implementations of the ARM System MMU architecture
	  versions 1 and 2.
@@ -495,26 +504,14 @@ menuconfig IOMMU_DEBUG

if IOMMU_DEBUG

config IOMMU_DEBUG_TRACKING
	bool "Track key IOMMU events"
	select IOMMU_API
	help
	  Enables additional debug tracking in the IOMMU framework code.
	  Tracking information and tests can be accessed through various
	  debugfs files.

	  Say Y here if you need to debug IOMMU issues and are okay with
	  the performance penalty of the tracking.

config IOMMU_TESTS
	bool "Interactive IOMMU performance/functional tests"
	select IOMMU_API
	select ARM64_PTDUMP_CORE
	help
	  Enables a suite of IOMMU unit tests.  The tests are runnable
	  through debugfs.  Unlike the IOMMU_DEBUG_TRACKING option, the
	  impact of enabling this option to overal system performance
	  should be minimal.
	  through debugfs. The impact of enabling this option to overall
	  system performance should be minimal.

endif # IOMMU_DEBUG

+1 −0
Original line number Diff line number Diff line
@@ -34,4 +34,5 @@ obj-$(CONFIG_TEGRA_IOMMU_SMMU) += tegra-smmu.o
obj-$(CONFIG_EXYNOS_IOMMU) += exynos-iommu.o
obj-$(CONFIG_FSL_PAMU) += fsl_pamu.o fsl_pamu_domain.o
obj-$(CONFIG_S390_IOMMU) += s390-iommu.o
obj-$(CONFIG_QTI_IOMMU_SUPPORT) += iommu-logger.o
obj-$(CONFIG_QCOM_IOMMU) += qcom_iommu.o
+16 −4
Original line number Diff line number Diff line
@@ -67,6 +67,7 @@
#include "io-pgtable.h"
#include "arm-smmu-regs.h"
#include "arm-smmu-debug.h"
#include "iommu-logger.h"
#include <linux/debugfs.h>
#include <linux/uaccess.h>

@@ -394,6 +395,7 @@ struct arm_smmu_domain {
	struct list_head		secure_pool_list;
	/* nonsecure pool protected by pgtbl_lock */
	struct list_head		nonsecure_pool;
	struct iommu_debug_attachment	*logger;
	struct iommu_domain		domain;
};

@@ -2079,17 +2081,24 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain,
	struct arm_smmu_cfg *cfg = &smmu_domain->cfg;
	unsigned long quirks = 0;
	bool dynamic;
	struct iommu_group *group;

	mutex_lock(&smmu_domain->init_mutex);
	if (smmu_domain->smmu)
		goto out_unlock;

	group = iommu_group_get(dev);
	ret = iommu_logger_register(&smmu_domain->logger, domain, group);
	iommu_group_put(group);
	if (ret)
		goto out_unlock;

	if (domain->type == IOMMU_DOMAIN_DMA) {
		ret = arm_smmu_setup_default_domain(dev, domain);
		if (ret) {
			dev_err(dev, "%s: default domain setup failed\n",
				__func__);
			goto out_unlock;
			goto out_logger;
		}
	}

@@ -2147,7 +2156,7 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain,

	if (cfg->fmt == ARM_SMMU_CTX_FMT_NONE) {
		ret = -EINVAL;
		goto out_unlock;
		goto out_logger;
	}

	switch (smmu_domain->stage) {
@@ -2195,7 +2204,7 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain,
		break;
	default:
		ret = -EINVAL;
		goto out_unlock;
		goto out_logger;
	}

	if (smmu_domain->attributes & (1 << DOMAIN_ATTR_FAST))
@@ -2217,7 +2226,7 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain,

	ret = arm_smmu_alloc_cb(domain, smmu, dev);
	if (ret < 0)
		goto out_unlock;
		goto out_logger;

	cfg->cbndx = ret;

@@ -2325,6 +2334,8 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain,
out_clear_smmu:
	arm_smmu_destroy_domain_context(domain);
	smmu_domain->smmu = NULL;
out_logger:
	iommu_logger_unregister(smmu_domain->logger);
out_unlock:
	mutex_unlock(&smmu_domain->init_mutex);
	return ret;
@@ -2448,6 +2459,7 @@ static void arm_smmu_domain_free(struct iommu_domain *domain)
	 */
	arm_smmu_put_dma_cookie(domain);
	arm_smmu_destroy_domain_context(domain);
	iommu_logger_unregister(smmu_domain->logger);
	kfree(smmu_domain);
}

+0 −62
Original line number Diff line number Diff line
@@ -86,68 +86,6 @@ static const char *iommu_debug_attr_to_string(enum iommu_attr attr)
}
#endif

#ifdef CONFIG_IOMMU_DEBUG_TRACKING

static DEFINE_MUTEX(iommu_debug_attachments_lock);
static LIST_HEAD(iommu_debug_attachments);

/*
 * Each group may have more than one domain; but each domain may
 * only have one group.
 * Used by debug tools to display the name of the device(s) associated
 * with a particular domain.
 */
struct iommu_debug_attachment {
	struct iommu_domain *domain;
	struct iommu_group *group;
	struct list_head list;
};

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

	group = dev->iommu_group;
	if (!group)
		return;

	mutex_lock(&iommu_debug_attachments_lock);
	list_for_each_entry(attach, &iommu_debug_attachments, list)
		if ((attach->domain == domain) && (attach->group == group))
			goto out;

	attach = kzalloc(sizeof(*attach), GFP_KERNEL);
	if (!attach)
		goto out;

	attach->domain = domain;
	attach->group = group;
	INIT_LIST_HEAD(&attach->list);

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

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

	mutex_lock(&iommu_debug_attachments_lock);
	list_for_each_entry_safe(it, tmp, &iommu_debug_attachments, list) {
		if (it->domain != domain)
			continue;
		list_del(&it->list);
		kfree(it);
	}

	mutex_unlock(&iommu_debug_attachments_lock);
}

#endif

#ifdef CONFIG_IOMMU_TESTS

#ifdef CONFIG_64BIT

drivers/iommu/iommu-debug.h

deleted100644 → 0
+0 −27
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
 */

#ifndef IOMMU_DEBUG_H
#define IOMMU_DEBUG_H

#ifdef CONFIG_IOMMU_DEBUG_TRACKING

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

#else  /* !CONFIG_IOMMU_DEBUG_TRACKING */

static inline void iommu_debug_attach_device(struct iommu_domain *domain,
					     struct device *dev)
{
}

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

#endif  /* CONFIG_IOMMU_DEBUG_TRACKING */

#endif /* IOMMU_DEBUG_H */
Loading