[PATCH v6 6/8] iommu/amd: Add debugfs support to dump device table

Dheeraj Kumar Srivastava posted 8 patches 6 months, 2 weeks ago
There is a newer version of this series
[PATCH v6 6/8] iommu/amd: Add debugfs support to dump device table
Posted by Dheeraj Kumar Srivastava 6 months, 2 weeks ago
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 <dheerajkumar.srivastava@amd.com>
---
 drivers/iommu/amd/debugfs.c | 49 +++++++++++++++++++++++++++++++++++++
 1 file changed, 49 insertions(+)

diff --git a/drivers/iommu/amd/debugfs.c b/drivers/iommu/amd/debugfs.c
index 8b57ab4ab809..38d3cab5fd8d 100644
--- a/drivers/iommu/amd/debugfs.c
+++ b/drivers/iommu/amd/debugfs.c
@@ -207,6 +207,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, "Please provide valid device id input\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;
@@ -231,4 +278,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);
 }
-- 
2.25.1
Re: [PATCH v6 6/8] iommu/amd: Add debugfs support to dump device table
Posted by Vasant Hegde 5 months, 3 weeks ago
Dheeraj,


On 6/4/2025 10:06 PM, Dheeraj Kumar Srivastava wrote:
> 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 <dheerajkumar.srivastava@amd.com>
> ---
>  drivers/iommu/amd/debugfs.c | 49 +++++++++++++++++++++++++++++++++++++
>  1 file changed, 49 insertions(+)
> 
> diff --git a/drivers/iommu/amd/debugfs.c b/drivers/iommu/amd/debugfs.c
> index 8b57ab4ab809..38d3cab5fd8d 100644
> --- a/drivers/iommu/amd/debugfs.c
> +++ b/drivers/iommu/amd/debugfs.c
> @@ -207,6 +207,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, "Please provide valid device id input\n");

Where? This should clearly indicate where to provide device id.


-Vasant