mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-08 12:58:12 -04:00
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: Patrick Daly <pdaly@codeaurora.org> [isaacm@codeaurora.org: resolved trivial merge conflicts] Signed-off-by: Isaac J. Manjarres <isaacm@codeaurora.org>
This commit is contained in:
parent
209228f315
commit
39cc9a4594
6 changed files with 130 additions and 4 deletions
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
drivers/iommu/iommu-logger.c
Normal file
79
drivers/iommu/iommu-logger.c
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
// 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");
|
||||
25
drivers/iommu/iommu-logger.h
Normal file
25
drivers/iommu/iommu-logger.h
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* Copyright (c) 2020, The Linux Foundation. All rights reserved. */
|
||||
|
||||
#ifndef __LINUX_QTI_IOMMU_LOGGER_H
|
||||
#define __LINUX_QTI_IOMMU_LOGGER_H
|
||||
|
||||
struct iommu_debug_attachment;
|
||||
|
||||
#if IS_ENABLED(CONFIG_QTI_IOMMU_SUPPORT)
|
||||
|
||||
int iommu_logger_register(struct iommu_debug_attachment **a,
|
||||
struct iommu_domain *domain,
|
||||
struct iommu_group *group);
|
||||
void iommu_logger_unregister(struct iommu_debug_attachment *a);
|
||||
#else
|
||||
static inline int iommu_logger_register(struct iommu_debug_attachment **a,
|
||||
struct iommu_domain *domain,
|
||||
struct iommu_group *group)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void iommu_logger_unregister(struct iommu_debug_attachment *a) {}
|
||||
#endif /* CONFIG_QTI_IOMMU_LOGGER */
|
||||
#endif /* __LINUX_QTI_IOMMU_LOGGER_H */
|
||||
Loading…
Reference in a new issue