]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
iommu/amd: Add debugfs support to dump IOMMU MMIO registers
authorDheeraj Kumar Srivastava <dheerajkumar.srivastava@amd.com>
Wed, 2 Jul 2025 09:37:58 +0000 (15:07 +0530)
committerWill Deacon <will@kernel.org>
Tue, 15 Jul 2025 10:41:52 +0000 (11:41 +0100)
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<x> (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 <dheerajkumar.srivastava@amd.com>
Reviewed-by: Vasant Hegde <vasant.hegde@amd.com>
Link: https://lore.kernel.org/r/20250702093804.849-3-dheerajkumar.srivastava@amd.com
Signed-off-by: Will Deacon <will@kernel.org>
drivers/iommu/amd/amd_iommu_types.h
drivers/iommu/amd/debugfs.c

index 35ee7b0648af6aa26632b3300da04b8d6539d276..e3148d7ddffe310f102800a027141d140b7279f1 100644 (file)
@@ -795,6 +795,7 @@ struct amd_iommu {
 #ifdef CONFIG_AMD_IOMMU_DEBUGFS
        /* DebugFS Info */
        struct dentry *debugfs;
+       int dbg_mmio_offset;
 #endif
 
        /* IOPF support */
index ff9520e002be85b953f69207f8d39158801d09f3..c025b4d2398de66aefc225a94b79cf8270bfeb49 100644 (file)
 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);
        }
 }