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

Commit 39cc9a45 authored by Patrick Daly's avatar Patrick Daly Committed by Isaac J. Manjarres
Browse files

iommu: qti: Track iommu domains



Add a new module to track iommu domains, including those which
may not currently be active. Supports multiple types of smmu
drivers.

Change-Id: Iacb98d823db8a87a2cf0868c467914847351950b
Signed-off-by: default avatarPatrick Daly <pdaly@codeaurora.org>
[isaacm@codeaurora.org: resolved trivial merge conflicts]
Signed-off-by: default avatarIsaac J. Manjarres <isaacm@codeaurora.org>
parent 209228f3
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -399,6 +399,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
	tristate "ARM Ltd. System MMU (SMMU) Support"
@@ -406,6 +414,7 @@ config ARM_SMMU
	select IOMMU_API
	select IOMMU_IO_PGTABLE_LPAE
	select ARM_DMA_USE_IOMMU if ARM
	select QTI_IOMMU_SUPPORT
	help
	  Support for implementations of the ARM System MMU architecture
	  versions 1 and 2.
+1 −0
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ 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
obj-$(CONFIG_HYPERV_IOMMU) += hyperv-iommu.o
obj-$(CONFIG_VIRTIO_IOMMU) += virtio-iommu.o
+15 −4
Original line number Diff line number Diff line
@@ -51,6 +51,7 @@

#include <linux/qcom_scm.h>
#include "arm-smmu.h"
#include "iommu-logger.h"

#define CREATE_TRACE_POINTS
#include "arm-smmu-trace.h"
@@ -1872,17 +1873,24 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain,
	struct msm_io_pgtable_info *pgtbl_info = &smmu_domain->pgtbl_info;
	struct arm_smmu_cfg *cfg = &smmu_domain->cfg;
	unsigned long quirks = 0;
	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;
		}
	}

@@ -1939,7 +1947,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) {
@@ -1987,7 +1995,7 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain,
		break;
	default:
		ret = -EINVAL;
		goto out_unlock;
		goto out_logger;
	}

#ifdef CONFIG_IOMMU_IO_PGTABLE_FAST
@@ -2001,7 +2009,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;

@@ -2071,6 +2079,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;
@@ -2186,6 +2196,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);
}

+1 −0
Original line number Diff line number Diff line
@@ -433,6 +433,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 msm_iommu_domain		domain;
};

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

#include <linux/module.h>
#include <linux/iommu.h>
#include <linux/slab.h>

#include "iommu-logger.h"

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;
};

static struct iommu_debug_attachment *iommu_logger_init(
						struct iommu_domain *domain,
						struct iommu_group *group)
{
	struct iommu_debug_attachment *logger;

	logger = kzalloc(sizeof(*logger), GFP_KERNEL);
	if (!logger)
		return NULL;

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

	return logger;
}

int iommu_logger_register(struct iommu_debug_attachment **logger_out,
			  struct iommu_domain *domain,
			  struct iommu_group *group)
{
	struct iommu_debug_attachment *logger;

	if (!logger_out)
		return -EINVAL;

	logger = iommu_logger_init(domain, group);
	if (!logger)
		return -ENOMEM;

	mutex_lock(&iommu_debug_attachments_lock);
	list_add(&logger->list, &iommu_debug_attachments);
	mutex_unlock(&iommu_debug_attachments_lock);

	*logger_out = logger;
	return 0;
}
EXPORT_SYMBOL(iommu_logger_register);

void iommu_logger_unregister(struct iommu_debug_attachment *logger)
{
	if (!logger)
		return;

	mutex_lock(&iommu_debug_attachments_lock);
	list_del(&logger->list);
	mutex_unlock(&iommu_debug_attachments_lock);
	kfree(logger);
}
EXPORT_SYMBOL(iommu_logger_unregister);

MODULE_DESCRIPTION("QTI IOMMU SUPPORT");
MODULE_LICENSE("GPL v2");
Loading