From 778d88fe9bb4d21187523736a2eac31d23ec65ec Mon Sep 17 00:00:00 2001 From: "Isaac J. Manjarres" Date: Wed, 29 Jul 2020 16:07:25 -0700 Subject: [PATCH] iommu/iommu-logger: Log IOMMU client name in debug structures Log IOMMU client name in debug structures so that tools can directly read the IOMMU client name without having to access other structures outside of the IOMMU debug attachments structure. Change-Id: I36c13fd63e6ca7260b69d01573126e276eb5835b Signed-off-by: Isaac J. Manjarres --- drivers/iommu/arm-smmu.c | 5 +---- drivers/iommu/iommu-logger.c | 29 ++++++++++++++++++++--------- drivers/iommu/iommu-logger.h | 8 +++----- 3 files changed, 24 insertions(+), 18 deletions(-) diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index d8da7e03cda1..c6e955ad36ef 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c @@ -1914,7 +1914,6 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain, &smmu_domain->pgtbl_info[1]; struct arm_smmu_cfg *cfg = &smmu_domain->cfg; unsigned long quirks = 0; - struct iommu_group *group; struct io_pgtable *iop; bool split_tables = false; @@ -2090,10 +2089,8 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain, } } - group = iommu_group_get_for_dev(smmu_domain->dev); iop = container_of(smmu_domain->pgtbl_ops[0], struct io_pgtable, ops); - ret = iommu_logger_register(&smmu_domain->logger, domain, group, iop); - iommu_group_put(group); + ret = iommu_logger_register(&smmu_domain->logger, domain, dev, iop); if (ret) goto out_clear_smmu; diff --git a/drivers/iommu/iommu-logger.c b/drivers/iommu/iommu-logger.c index 53a300f15742..aa543588b120 100644 --- a/drivers/iommu/iommu-logger.c +++ b/drivers/iommu/iommu-logger.c @@ -13,8 +13,7 @@ static DEFINE_MUTEX(iommu_debug_attachments_lock); static LIST_HEAD(iommu_debug_attachments); -static unsigned int iommu_logger_pgtable_levels(struct iommu_domain *domain, - struct io_pgtable *iop) +static unsigned int iommu_logger_pgtable_levels(struct io_pgtable *iop) { unsigned int va_bits, pte_size, bits_per_level, pg_shift; unsigned long ias = iop->cfg.ias; @@ -31,7 +30,7 @@ static unsigned int iommu_logger_pgtable_levels(struct iommu_domain *domain, return 0; } - pg_shift = __ffs(domain->pgsize_bitmap); + pg_shift = __ffs(iop->cfg.pgsize_bitmap); bits_per_level = pg_shift - ilog2(pte_size); va_bits = ias - pg_shift; return DIV_ROUND_UP(va_bits, bits_per_level); @@ -83,11 +82,13 @@ static int iommu_logger_domain_ttbrs(struct io_pgtable *iop, void **ttbr0_ptr, static struct iommu_debug_attachment *iommu_logger_init( struct iommu_domain *domain, - struct iommu_group *group, + struct device *dev, struct io_pgtable *iop) { struct iommu_debug_attachment *logger; - unsigned int levels = iommu_logger_pgtable_levels(domain, iop); + char *client_name; + struct iommu_group *group; + unsigned int levels = iommu_logger_pgtable_levels(iop); enum iommu_logger_pgtable_fmt fmt = iommu_logger_pgtable_fmt_lut( iop->fmt); void *ttbr0, *ttbr1; @@ -104,9 +105,19 @@ static struct iommu_debug_attachment *iommu_logger_init( if (!logger) return ERR_PTR(-ENOMEM); + client_name = kasprintf(GFP_KERNEL, "%s", kobject_name(&dev->kobj)); + if (!client_name) { + kfree(logger); + return ERR_PTR(-ENOMEM); + } + + group = iommu_group_get_for_dev(dev); + iommu_group_put(group); + INIT_LIST_HEAD(&logger->list); logger->domain = domain; logger->group = group; + logger->client_name = client_name; logger->fmt = fmt; logger->levels = levels; logger->ttbr0 = ttbr0; @@ -116,17 +127,16 @@ static struct iommu_debug_attachment *iommu_logger_init( } int iommu_logger_register(struct iommu_debug_attachment **logger_out, - struct iommu_domain *domain, - struct iommu_group *group, + struct iommu_domain *domain, struct device *dev, struct io_pgtable *iop) { struct iommu_debug_attachment *logger; - if (!logger_out || !domain || !group || !iop || + if (!logger_out || !dev || !iop || iop->fmt >= IO_PGTABLE_NUM_FMTS) return -EINVAL; - logger = iommu_logger_init(domain, group, iop); + logger = iommu_logger_init(domain, dev, iop); if (IS_ERR(logger)) return PTR_ERR(logger); @@ -147,6 +157,7 @@ void iommu_logger_unregister(struct iommu_debug_attachment *logger) mutex_lock(&iommu_debug_attachments_lock); list_del(&logger->list); mutex_unlock(&iommu_debug_attachments_lock); + kfree(logger->client_name); kfree(logger); } EXPORT_SYMBOL(iommu_logger_unregister); diff --git a/drivers/iommu/iommu-logger.h b/drivers/iommu/iommu-logger.h index 5e3d9dd6f194..b6e531c24737 100644 --- a/drivers/iommu/iommu-logger.h +++ b/drivers/iommu/iommu-logger.h @@ -15,12 +15,11 @@ enum iommu_logger_pgtable_fmt { /* * 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; + char *client_name; enum iommu_logger_pgtable_fmt fmt; unsigned int levels; /* @@ -35,14 +34,13 @@ 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, + struct iommu_domain *domain, struct device *dev, struct io_pgtable *iop); 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, + struct device *dev, struct io_pgtable *iop) { return 0;