From: Dheeraj Kumar Srivastava Date: Wed, 2 Jul 2025 09:38:02 +0000 (+0530) Subject: iommu/amd: Add debugfs support to dump device table X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b484577824452e526191cb87f297f78dadd97dda;p=thirdparty%2Flinux.git iommu/amd: Add debugfs support to dump device table IOMMU uses device table data structure to get per-device information for DMA remapping, interrupt remapping, and other functionalities. It's a valuable data structure to visualize for debugging issues related to IOMMU. eg. -> To dump device table entry for a particular device #echo 0000:c4:00.0 > /sys/kernel/debug/iommu/amd/devid #cat /sys/kernel/debug/iommu/amd/devtbl or #echo c4:00.0 > /sys/kernel/debug/iommu/amd/devid #cat /sys/kernel/debug/iommu/amd/devtbl Signed-off-by: Dheeraj Kumar Srivastava Reviewed-by: Vasant Hegde Link: https://lore.kernel.org/r/20250702093804.849-7-dheerajkumar.srivastava@amd.com Signed-off-by: Will Deacon --- diff --git a/drivers/iommu/amd/debugfs.c b/drivers/iommu/amd/debugfs.c index 065b150bba15d..b01eea2fbe03b 100644 --- a/drivers/iommu/amd/debugfs.c +++ b/drivers/iommu/amd/debugfs.c @@ -208,6 +208,53 @@ static int devid_show(struct seq_file *m, void *unused) } DEFINE_SHOW_STORE_ATTRIBUTE(devid); +static void dump_dte(struct seq_file *m, struct amd_iommu_pci_seg *pci_seg, u16 devid) +{ + struct dev_table_entry *dev_table; + struct amd_iommu *iommu; + + iommu = pci_seg->rlookup_table[devid]; + if (!iommu) + return; + + dev_table = get_dev_table(iommu); + if (!dev_table) { + seq_puts(m, "Device table not found"); + return; + } + + seq_printf(m, "%-12s %16s %16s %16s %16s iommu\n", "DeviceId", + "QWORD[3]", "QWORD[2]", "QWORD[1]", "QWORD[0]"); + seq_printf(m, "%04x:%02x:%02x.%x ", pci_seg->id, PCI_BUS_NUM(devid), + PCI_SLOT(devid), PCI_FUNC(devid)); + for (int i = 3; i >= 0; --i) + seq_printf(m, "%016llx ", dev_table[devid].data[i]); + seq_printf(m, "iommu%d\n", iommu->index); +} + +static int iommu_devtbl_show(struct seq_file *m, void *unused) +{ + struct amd_iommu_pci_seg *pci_seg; + u16 seg, devid; + + if (sbdf < 0) { + seq_puts(m, "Enter a valid device ID to 'devid' file\n"); + return 0; + } + seg = PCI_SBDF_TO_SEGID(sbdf); + devid = PCI_SBDF_TO_DEVID(sbdf); + + for_each_pci_segment(pci_seg) { + if (pci_seg->id != seg) + continue; + dump_dte(m, pci_seg, devid); + break; + } + + return 0; +} +DEFINE_SHOW_ATTRIBUTE(iommu_devtbl); + void amd_iommu_debugfs_setup(void) { struct amd_iommu *iommu; @@ -232,4 +279,6 @@ void amd_iommu_debugfs_setup(void) debugfs_create_file("devid", 0644, amd_iommu_debugfs, NULL, &devid_fops); + debugfs_create_file("devtbl", 0444, amd_iommu_debugfs, NULL, + &iommu_devtbl_fops); }