Skip to content

Commit 2e98940

Browse files
dhsrivaswilldeacon
authored andcommitted
iommu/amd: Add support for device id user input
Dumping IOMMU data structures like device table, IRT, etc., for all devices on the system will be a lot of data dumped in a file. Also, user may want to dump and analyze these data structures just for one or few devices. So dumping IOMMU data structures like device table, IRT etc for all devices is not a good approach. Add "device id" user input to be used for dumping IOMMU data structures like device table, IRT etc in AMD IOMMU debugfs. eg. 1. # echo 0000:01:00.0 > /sys/kernel/debug/iommu/amd/devid # cat /sys/kernel/debug/iommu/amd/devid Output : 0000:01:00.0 2. # echo 01:00.0 > /sys/kernel/debug/iommu/amd/devid # cat /sys/kernel/debug/iommu/amd/devid Output : 0000:01:00.0 Signed-off-by: Dheeraj Kumar Srivastava <[email protected]> Reviewed-by: Vasant Hegde <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Will Deacon <[email protected]>
1 parent fb3af1f commit 2e98940

File tree

1 file changed

+80
-0
lines changed

1 file changed

+80
-0
lines changed

drivers/iommu/amd/debugfs.c

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ static struct dentry *amd_iommu_debugfs;
1616

1717
#define MAX_NAME_LEN 20
1818
#define OFS_IN_SZ 8
19+
#define DEVID_IN_SZ 16
20+
21+
static int sbdf = -1;
1922

2023
static ssize_t iommu_mmio_write(struct file *filp, const char __user *ubuf,
2124
size_t cnt, loff_t *ppos)
@@ -131,6 +134,80 @@ static int iommu_cmdbuf_show(struct seq_file *m, void *unused)
131134
}
132135
DEFINE_SHOW_ATTRIBUTE(iommu_cmdbuf);
133136

137+
static ssize_t devid_write(struct file *filp, const char __user *ubuf,
138+
size_t cnt, loff_t *ppos)
139+
{
140+
struct amd_iommu_pci_seg *pci_seg;
141+
int seg, bus, slot, func;
142+
struct amd_iommu *iommu;
143+
char *srcid_ptr;
144+
u16 devid;
145+
int i;
146+
147+
sbdf = -1;
148+
149+
if (cnt >= DEVID_IN_SZ)
150+
return -EINVAL;
151+
152+
srcid_ptr = memdup_user_nul(ubuf, cnt);
153+
if (IS_ERR(srcid_ptr))
154+
return PTR_ERR(srcid_ptr);
155+
156+
i = sscanf(srcid_ptr, "%x:%x:%x.%x", &seg, &bus, &slot, &func);
157+
if (i != 4) {
158+
i = sscanf(srcid_ptr, "%x:%x.%x", &bus, &slot, &func);
159+
if (i != 3) {
160+
kfree(srcid_ptr);
161+
return -EINVAL;
162+
}
163+
seg = 0;
164+
}
165+
166+
devid = PCI_DEVID(bus, PCI_DEVFN(slot, func));
167+
168+
/* Check if user device id input is a valid input */
169+
for_each_pci_segment(pci_seg) {
170+
if (pci_seg->id != seg)
171+
continue;
172+
if (devid > pci_seg->last_bdf) {
173+
kfree(srcid_ptr);
174+
return -EINVAL;
175+
}
176+
iommu = pci_seg->rlookup_table[devid];
177+
if (!iommu) {
178+
kfree(srcid_ptr);
179+
return -ENODEV;
180+
}
181+
break;
182+
}
183+
184+
if (pci_seg->id != seg) {
185+
kfree(srcid_ptr);
186+
return -EINVAL;
187+
}
188+
189+
sbdf = PCI_SEG_DEVID_TO_SBDF(seg, devid);
190+
191+
kfree(srcid_ptr);
192+
193+
return cnt;
194+
}
195+
196+
static int devid_show(struct seq_file *m, void *unused)
197+
{
198+
u16 devid;
199+
200+
if (sbdf >= 0) {
201+
devid = PCI_SBDF_TO_DEVID(sbdf);
202+
seq_printf(m, "%04x:%02x:%02x.%x\n", PCI_SBDF_TO_SEGID(sbdf),
203+
PCI_BUS_NUM(devid), PCI_SLOT(devid), PCI_FUNC(devid));
204+
} else
205+
seq_puts(m, "No or Invalid input provided\n");
206+
207+
return 0;
208+
}
209+
DEFINE_SHOW_STORE_ATTRIBUTE(devid);
210+
134211
void amd_iommu_debugfs_setup(void)
135212
{
136213
struct amd_iommu *iommu;
@@ -152,4 +229,7 @@ void amd_iommu_debugfs_setup(void)
152229
debugfs_create_file("cmdbuf", 0444, iommu->debugfs, iommu,
153230
&iommu_cmdbuf_fops);
154231
}
232+
233+
debugfs_create_file("devid", 0644, amd_iommu_debugfs, NULL,
234+
&devid_fops);
155235
}

0 commit comments

Comments
 (0)