Implement a skeleton framework for debugfs support in the AMD IOMMU.
Signed-off-by: Gary R Hook <gary.h...@amd.com> --- drivers/iommu/Kconfig | 6 ++--- drivers/iommu/Makefile | 2 +- drivers/iommu/amd_iommu_debugfs.c | 47 +++++++++++++++++++++++++++++++++++++ drivers/iommu/amd_iommu_init.c | 9 ++++--- drivers/iommu/amd_iommu_proto.h | 6 +++++ drivers/iommu/amd_iommu_types.h | 3 ++ include/linux/iommu.h | 8 +++--- 7 files changed, 69 insertions(+), 12 deletions(-) create mode 100644 drivers/iommu/amd_iommu_debugfs.c diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig index d40248446214..8d50151d5bf4 100644 --- a/drivers/iommu/Kconfig +++ b/drivers/iommu/Kconfig @@ -65,9 +65,9 @@ config IOMMU_DEBUG depends on DEBUG_FS default n help - Base enablement for access to any IOMMU device. Allows individual - drivers to populate debugfs for access to IOMMU registers and - data structures. + Enable exposure of IOMMU device internals. Allow devices to + populate debugfs for access to IOMMU registers and data + structures. config IOMMU_IOVA tristate diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile index 5e5c3339681d..0ca250f626d9 100644 --- a/drivers/iommu/Makefile +++ b/drivers/iommu/Makefile @@ -11,7 +11,7 @@ obj-$(CONFIG_IOMMU_IOVA) += iova.o obj-$(CONFIG_OF_IOMMU) += of_iommu.o obj-$(CONFIG_MSM_IOMMU) += msm_iommu.o obj-$(CONFIG_AMD_IOMMU) += amd_iommu.o amd_iommu_init.o -obj-$(CONFIG_AMD_IOMMU_DEBUG) += amd_iommu_debugfs.o +obj-$(CONFIG_IOMMU_DEBUG) += amd_iommu_debugfs.o obj-$(CONFIG_AMD_IOMMU_V2) += amd_iommu_v2.o obj-$(CONFIG_ARM_SMMU) += arm-smmu.o obj-$(CONFIG_ARM_SMMU_V3) += arm-smmu-v3.o diff --git a/drivers/iommu/amd_iommu_debugfs.c b/drivers/iommu/amd_iommu_debugfs.c new file mode 100644 index 000000000000..3547ad3339c1 --- /dev/null +++ b/drivers/iommu/amd_iommu_debugfs.c @@ -0,0 +1,47 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * AMD IOMMU driver + * + * Copyright (C) 2018 Advanced Micro Devices, Inc. + * + * Author: Gary R Hook <gary.h...@amd.com> + */ + +#ifdef CONFIG_IOMMU_DEBUG + +#include <linux/debugfs.h> +#include <linux/iommu.h> +#include <linux/pci.h> +#include "amd_iommu_proto.h" +#include "amd_iommu_types.h" + +static struct dentry *iommu_debugfs_dir; +static DEFINE_RWLOCK(iommu_debugfs_lock); + +#define MAX_NAME_LEN 20 + +void amd_iommu_debugfs_setup(struct amd_iommu *iommu) +{ + char name[MAX_NAME_LEN + 1]; + struct dentry *d_top; + unsigned long flags; + + if (!debugfs_initialized()) + return; + + write_lock_irqsave(&iommu_debugfs_lock, flags); + if (!iommu_debugfs_dir && (d_top = iommu_debugfs_setup())) + iommu_debugfs_dir = debugfs_create_dir("amd", d_top); + write_unlock_irqrestore(&iommu_debugfs_lock, flags); + if (iommu_debugfs_dir) { + snprintf(name, MAX_NAME_LEN, "iommu%02d", iommu->index); + iommu->debugfs_instance = debugfs_create_dir(name, + iommu_debugfs_dir); + if (!iommu->debugfs_instance) + debugfs_remove_recursive(iommu_debugfs_dir); + } + + return; +} + +#endif diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c index 99d48c42a12f..43856c7f4ea1 100644 --- a/drivers/iommu/amd_iommu_init.c +++ b/drivers/iommu/amd_iommu_init.c @@ -89,6 +89,7 @@ #define ACPI_DEVFLAG_ATSDIS 0x10000000 #define LOOP_TIMEOUT 100000 + /* * ACPI table definitions * @@ -2720,6 +2721,7 @@ int __init amd_iommu_enable_faulting(void) */ static int __init amd_iommu_init(void) { + struct amd_iommu *iommu; int ret; ret = iommu_go_to_state(IOMMU_INITIALIZED); @@ -2729,14 +2731,15 @@ static int __init amd_iommu_init(void) disable_iommus(); free_iommu_resources(); } else { - struct amd_iommu *iommu; - uninit_device_table_dma(); for_each_iommu(iommu) iommu_flush_all_caches(iommu); } } + for_each_iommu(iommu) + amd_iommu_debugfs_setup(iommu); + return ret; } @@ -2783,8 +2786,6 @@ int __init amd_iommu_detect(void) iommu_detected = 1; x86_init.iommu.iommu_init = amd_iommu_init; -dump_stack(); - return 1; } diff --git a/drivers/iommu/amd_iommu_proto.h b/drivers/iommu/amd_iommu_proto.h index 640c286a0ab9..e19cebc5c740 100644 --- a/drivers/iommu/amd_iommu_proto.h +++ b/drivers/iommu/amd_iommu_proto.h @@ -33,6 +33,12 @@ extern void amd_iommu_uninit_devices(void); extern void amd_iommu_init_notifier(void); extern int amd_iommu_init_api(void); +#ifdef CONFIG_IOMMU_DEBUG +extern void amd_iommu_debugfs_setup(struct amd_iommu *iommu); +#else +static inline void amd_iommu_debugfs_setup(struct amd_iommu *iommu) {} +#endif + /* Needed for interrupt remapping */ extern int amd_iommu_prepare(void); extern int amd_iommu_enable(void); diff --git a/drivers/iommu/amd_iommu_types.h b/drivers/iommu/amd_iommu_types.h index f6b24c7d8b70..6dca9fe38518 100644 --- a/drivers/iommu/amd_iommu_types.h +++ b/drivers/iommu/amd_iommu_types.h @@ -591,6 +591,9 @@ struct amd_iommu { u32 flags; volatile u64 __aligned(8) cmd_sem; + + /* DebugFS Info */ + struct dentry *debugfs_instance; }; static inline struct amd_iommu *dev_to_amd_iommu(struct device *dev) diff --git a/include/linux/iommu.h b/include/linux/iommu.h index 98527f9b473b..dbfff811aa25 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -412,6 +412,10 @@ void iommu_fwspec_free(struct device *dev); int iommu_fwspec_add_ids(struct device *dev, u32 *ids, int num_ids); const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode); +#ifdef CONFIG_IOMMU_DEBUG +extern struct dentry *iommu_debugfs_setup(void); +#endif + #else /* CONFIG_IOMMU_API */ struct iommu_ops {}; @@ -696,10 +700,6 @@ const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode) return NULL; } -#ifdef CONFIG_IOMMU_DEBUG -extern struct dentry *iommu_debugfs_setup(void); -#endif - #endif /* CONFIG_IOMMU_API */ #endif /* __LINUX_IOMMU_H */