From 7a4ee419e8c144b747a8915856e91a034d7c8f34 Mon Sep 17 00:00:00 2001 From: Dheeraj Kumar Srivastava Date: Wed, 2 Jul 2025 15:07:58 +0530 Subject: [PATCH] iommu/amd: Add debugfs support to dump IOMMU MMIO registers Analyzing IOMMU MMIO registers gives a view of what IOMMU is configured with on the system and is helpful to debug issues with IOMMU. eg. -> To get mmio registers value at offset 0x18 for iommu (say, iommu00) # echo "0x18" > /sys/kernel/debug/iommu/amd/iommu00/mmio # cat /sys/kernel/debug/iommu/amd/iommu00/mmio Signed-off-by: Dheeraj Kumar Srivastava Reviewed-by: Vasant Hegde Link: https://lore.kernel.org/r/20250702093804.849-3-dheerajkumar.srivastava@amd.com Signed-off-by: Will Deacon --- drivers/iommu/amd/amd_iommu_types.h | 1 + drivers/iommu/amd/debugfs.c | 47 +++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/drivers/iommu/amd/amd_iommu_types.h b/drivers/iommu/amd/amd_iommu_types.h index 35ee7b0648af6..e3148d7ddffe3 100644 --- a/drivers/iommu/amd/amd_iommu_types.h +++ b/drivers/iommu/amd/amd_iommu_types.h @@ -795,6 +795,7 @@ struct amd_iommu { #ifdef CONFIG_AMD_IOMMU_DEBUGFS /* DebugFS Info */ struct dentry *debugfs; + int dbg_mmio_offset; #endif /* IOPF support */ diff --git a/drivers/iommu/amd/debugfs.c b/drivers/iommu/amd/debugfs.c index ff9520e002be8..c025b4d2398de 100644 --- a/drivers/iommu/amd/debugfs.c +++ b/drivers/iommu/amd/debugfs.c @@ -15,6 +15,48 @@ static struct dentry *amd_iommu_debugfs; #define MAX_NAME_LEN 20 +#define OFS_IN_SZ 8 + +static ssize_t iommu_mmio_write(struct file *filp, const char __user *ubuf, + size_t cnt, loff_t *ppos) +{ + struct seq_file *m = filp->private_data; + struct amd_iommu *iommu = m->private; + int ret; + + iommu->dbg_mmio_offset = -1; + + if (cnt > OFS_IN_SZ) + return -EINVAL; + + ret = kstrtou32_from_user(ubuf, cnt, 0, &iommu->dbg_mmio_offset); + if (ret) + return ret; + + if (iommu->dbg_mmio_offset > iommu->mmio_phys_end - 4) { + iommu->dbg_mmio_offset = -1; + return -EINVAL; + } + + return cnt; +} + +static int iommu_mmio_show(struct seq_file *m, void *unused) +{ + struct amd_iommu *iommu = m->private; + u64 value; + + if (iommu->dbg_mmio_offset < 0) { + seq_puts(m, "Please provide mmio register's offset\n"); + return 0; + } + + value = readq(iommu->mmio_base + iommu->dbg_mmio_offset); + seq_printf(m, "Offset:0x%x Value:0x%016llx\n", iommu->dbg_mmio_offset, value); + + return 0; +} +DEFINE_SHOW_STORE_ATTRIBUTE(iommu_mmio); void amd_iommu_debugfs_setup(void) { @@ -24,7 +66,12 @@ void amd_iommu_debugfs_setup(void) amd_iommu_debugfs = debugfs_create_dir("amd", iommu_debugfs_dir); for_each_iommu(iommu) { + iommu->dbg_mmio_offset = -1; + snprintf(name, MAX_NAME_LEN, "iommu%02d", iommu->index); iommu->debugfs = debugfs_create_dir(name, amd_iommu_debugfs); + + debugfs_create_file("mmio", 0644, iommu->debugfs, iommu, + &iommu_mmio_fops); } } -- 2.47.2