1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * AMD IOMMU driver 4 * 5 * Copyright (C) 2018 Advanced Micro Devices, Inc. 6 * 7 * Author: Gary R Hook <gary.hook@amd.com> 8 */ 9 10 #include <linux/debugfs.h> 11 #include <linux/pci.h> 12 13 #include "amd_iommu.h" 14 #include "../irq_remapping.h" 15 16 static struct dentry *amd_iommu_debugfs; 17 18 #define MAX_NAME_LEN 20 19 #define OFS_IN_SZ 8 20 #define DEVID_IN_SZ 16 21 22 static int sbdf = -1; 23 24 static ssize_t iommu_mmio_write(struct file *filp, const char __user *ubuf, 25 size_t cnt, loff_t *ppos) 26 { 27 struct seq_file *m = filp->private_data; 28 struct amd_iommu *iommu = m->private; 29 int ret, dbg_mmio_offset = iommu->dbg_mmio_offset = -1; 30 31 if (cnt > OFS_IN_SZ) 32 return -EINVAL; 33 34 ret = kstrtos32_from_user(ubuf, cnt, 0, &dbg_mmio_offset); 35 if (ret) 36 return ret; 37 38 if (dbg_mmio_offset < 0 || dbg_mmio_offset > 39 iommu->mmio_phys_end - sizeof(u64)) 40 return -EINVAL; 41 42 iommu->dbg_mmio_offset = dbg_mmio_offset; 43 return cnt; 44 } 45 46 static int iommu_mmio_show(struct seq_file *m, void *unused) 47 { 48 struct amd_iommu *iommu = m->private; 49 u64 value; 50 int dbg_mmio_offset = iommu->dbg_mmio_offset; 51 52 if (dbg_mmio_offset < 0 || dbg_mmio_offset > 53 iommu->mmio_phys_end - sizeof(u64)) { 54 seq_puts(m, "Please provide mmio register's offset\n"); 55 return 0; 56 } 57 58 value = readq(iommu->mmio_base + dbg_mmio_offset); 59 seq_printf(m, "Offset:0x%x Value:0x%016llx\n", dbg_mmio_offset, value); 60 61 return 0; 62 } 63 DEFINE_SHOW_STORE_ATTRIBUTE(iommu_mmio); 64 65 static ssize_t iommu_capability_write(struct file *filp, const char __user *ubuf, 66 size_t cnt, loff_t *ppos) 67 { 68 struct seq_file *m = filp->private_data; 69 struct amd_iommu *iommu = m->private; 70 int ret, dbg_cap_offset = iommu->dbg_cap_offset = -1; 71 72 if (cnt > OFS_IN_SZ) 73 return -EINVAL; 74 75 ret = kstrtos32_from_user(ubuf, cnt, 0, &dbg_cap_offset); 76 if (ret) 77 return ret; 78 79 /* Capability register at offset 0x14 is the last IOMMU capability register. */ 80 if (dbg_cap_offset < 0 || dbg_cap_offset > 0x14) 81 return -EINVAL; 82 83 iommu->dbg_cap_offset = dbg_cap_offset; 84 return cnt; 85 } 86 87 static int iommu_capability_show(struct seq_file *m, void *unused) 88 { 89 struct amd_iommu *iommu = m->private; 90 u32 value; 91 int err, dbg_cap_offset = iommu->dbg_cap_offset; 92 93 if (dbg_cap_offset < 0 || dbg_cap_offset > 0x14) { 94 seq_puts(m, "Please provide capability register's offset in the range [0x00 - 0x14]\n"); 95 return 0; 96 } 97 98 err = pci_read_config_dword(iommu->dev, iommu->cap_ptr + dbg_cap_offset, &value); 99 if (err) { 100 seq_printf(m, "Not able to read capability register at 0x%x\n", 101 dbg_cap_offset); 102 return 0; 103 } 104 105 seq_printf(m, "Offset:0x%x Value:0x%08x\n", dbg_cap_offset, value); 106 107 return 0; 108 } 109 DEFINE_SHOW_STORE_ATTRIBUTE(iommu_capability); 110 111 static int iommu_cmdbuf_show(struct seq_file *m, void *unused) 112 { 113 struct amd_iommu *iommu = m->private; 114 struct iommu_cmd *cmd; 115 unsigned long flag; 116 u32 head, tail; 117 int i; 118 119 raw_spin_lock_irqsave(&iommu->lock, flag); 120 head = readl(iommu->mmio_base + MMIO_CMD_HEAD_OFFSET); 121 tail = readl(iommu->mmio_base + MMIO_CMD_TAIL_OFFSET); 122 seq_printf(m, "CMD Buffer Head Offset:%d Tail Offset:%d\n", 123 (head >> 4) & 0x7fff, (tail >> 4) & 0x7fff); 124 for (i = 0; i < CMD_BUFFER_ENTRIES; i++) { 125 cmd = (struct iommu_cmd *)(iommu->cmd_buf + i * sizeof(*cmd)); 126 seq_printf(m, "%3d: %08x %08x %08x %08x\n", i, cmd->data[0], 127 cmd->data[1], cmd->data[2], cmd->data[3]); 128 } 129 raw_spin_unlock_irqrestore(&iommu->lock, flag); 130 131 return 0; 132 } 133 DEFINE_SHOW_ATTRIBUTE(iommu_cmdbuf); 134 135 static ssize_t devid_write(struct file *filp, const char __user *ubuf, 136 size_t cnt, loff_t *ppos) 137 { 138 struct amd_iommu_pci_seg *pci_seg; 139 int seg, bus, slot, func; 140 struct amd_iommu *iommu; 141 char *srcid_ptr; 142 u16 devid; 143 int i; 144 145 sbdf = -1; 146 147 if (cnt >= DEVID_IN_SZ) 148 return -EINVAL; 149 150 srcid_ptr = memdup_user_nul(ubuf, cnt); 151 if (IS_ERR(srcid_ptr)) 152 return PTR_ERR(srcid_ptr); 153 154 i = sscanf(srcid_ptr, "%x:%x:%x.%x", &seg, &bus, &slot, &func); 155 if (i != 4) { 156 i = sscanf(srcid_ptr, "%x:%x.%x", &bus, &slot, &func); 157 if (i != 3) { 158 kfree(srcid_ptr); 159 return -EINVAL; 160 } 161 seg = 0; 162 } 163 164 devid = PCI_DEVID(bus, PCI_DEVFN(slot, func)); 165 166 /* Check if user device id input is a valid input */ 167 for_each_pci_segment(pci_seg) { 168 if (pci_seg->id != seg) 169 continue; 170 if (devid > pci_seg->last_bdf) { 171 kfree(srcid_ptr); 172 return -EINVAL; 173 } 174 iommu = pci_seg->rlookup_table[devid]; 175 if (!iommu) { 176 kfree(srcid_ptr); 177 return -ENODEV; 178 } 179 sbdf = PCI_SEG_DEVID_TO_SBDF(seg, devid); 180 kfree(srcid_ptr); 181 return cnt; 182 } 183 184 kfree(srcid_ptr); 185 return -EINVAL; 186 } 187 188 static int devid_show(struct seq_file *m, void *unused) 189 { 190 u16 devid; 191 int sbdf_shadow = sbdf; 192 193 if (sbdf_shadow >= 0) { 194 devid = PCI_SBDF_TO_DEVID(sbdf_shadow); 195 seq_printf(m, "%04x:%02x:%02x.%x\n", PCI_SBDF_TO_SEGID(sbdf_shadow), 196 PCI_BUS_NUM(devid), PCI_SLOT(devid), PCI_FUNC(devid)); 197 } else 198 seq_puts(m, "No or Invalid input provided\n"); 199 200 return 0; 201 } 202 DEFINE_SHOW_STORE_ATTRIBUTE(devid); 203 204 static void dump_dte(struct seq_file *m, struct amd_iommu_pci_seg *pci_seg, u16 devid) 205 { 206 struct dev_table_entry *dev_table; 207 struct amd_iommu *iommu; 208 209 iommu = pci_seg->rlookup_table[devid]; 210 if (!iommu) 211 return; 212 213 dev_table = get_dev_table(iommu); 214 if (!dev_table) { 215 seq_puts(m, "Device table not found"); 216 return; 217 } 218 219 seq_printf(m, "%-12s %16s %16s %16s %16s iommu\n", "DeviceId", 220 "QWORD[3]", "QWORD[2]", "QWORD[1]", "QWORD[0]"); 221 seq_printf(m, "%04x:%02x:%02x.%x ", pci_seg->id, PCI_BUS_NUM(devid), 222 PCI_SLOT(devid), PCI_FUNC(devid)); 223 for (int i = 3; i >= 0; --i) 224 seq_printf(m, "%016llx ", dev_table[devid].data[i]); 225 seq_printf(m, "iommu%d\n", iommu->index); 226 } 227 228 static int iommu_devtbl_show(struct seq_file *m, void *unused) 229 { 230 struct amd_iommu_pci_seg *pci_seg; 231 u16 seg, devid; 232 int sbdf_shadow = sbdf; 233 234 if (sbdf_shadow < 0) { 235 seq_puts(m, "Enter a valid device ID to 'devid' file\n"); 236 return 0; 237 } 238 seg = PCI_SBDF_TO_SEGID(sbdf_shadow); 239 devid = PCI_SBDF_TO_DEVID(sbdf_shadow); 240 241 for_each_pci_segment(pci_seg) { 242 if (pci_seg->id != seg) 243 continue; 244 dump_dte(m, pci_seg, devid); 245 break; 246 } 247 248 return 0; 249 } 250 DEFINE_SHOW_ATTRIBUTE(iommu_devtbl); 251 252 static void dump_128_irte(struct seq_file *m, struct irq_remap_table *table, u16 int_tab_len) 253 { 254 struct irte_ga *ptr, *irte; 255 int index; 256 257 for (index = 0; index < int_tab_len; index++) { 258 ptr = (struct irte_ga *)table->table; 259 irte = &ptr[index]; 260 261 if (AMD_IOMMU_GUEST_IR_VAPIC(amd_iommu_guest_ir) && 262 !irte->lo.fields_vapic.valid) 263 continue; 264 else if (!irte->lo.fields_remap.valid) 265 continue; 266 seq_printf(m, "IRT[%04d] %016llx %016llx\n", index, irte->hi.val, irte->lo.val); 267 } 268 } 269 270 static void dump_32_irte(struct seq_file *m, struct irq_remap_table *table, u16 int_tab_len) 271 { 272 union irte *ptr, *irte; 273 int index; 274 275 for (index = 0; index < int_tab_len; index++) { 276 ptr = (union irte *)table->table; 277 irte = &ptr[index]; 278 279 if (!irte->fields.valid) 280 continue; 281 seq_printf(m, "IRT[%04d] %08x\n", index, irte->val); 282 } 283 } 284 285 static void dump_irte(struct seq_file *m, u16 devid, struct amd_iommu_pci_seg *pci_seg) 286 { 287 struct dev_table_entry *dev_table; 288 struct irq_remap_table *table; 289 struct amd_iommu *iommu; 290 unsigned long flags; 291 u16 int_tab_len; 292 293 table = pci_seg->irq_lookup_table[devid]; 294 if (!table) { 295 seq_printf(m, "IRQ lookup table not set for %04x:%02x:%02x:%x\n", 296 pci_seg->id, PCI_BUS_NUM(devid), PCI_SLOT(devid), PCI_FUNC(devid)); 297 return; 298 } 299 300 iommu = pci_seg->rlookup_table[devid]; 301 if (!iommu) 302 return; 303 304 dev_table = get_dev_table(iommu); 305 if (!dev_table) { 306 seq_puts(m, "Device table not found"); 307 return; 308 } 309 310 int_tab_len = dev_table[devid].data[2] & DTE_INTTABLEN_MASK; 311 if (int_tab_len != DTE_INTTABLEN_512 && int_tab_len != DTE_INTTABLEN_2K) { 312 seq_puts(m, "The device's DTE contains an invalid IRT length value."); 313 return; 314 } 315 316 seq_printf(m, "DeviceId %04x:%02x:%02x.%x\n", pci_seg->id, PCI_BUS_NUM(devid), 317 PCI_SLOT(devid), PCI_FUNC(devid)); 318 319 raw_spin_lock_irqsave(&table->lock, flags); 320 if (AMD_IOMMU_GUEST_IR_GA(amd_iommu_guest_ir)) 321 dump_128_irte(m, table, BIT(int_tab_len >> 1)); 322 else 323 dump_32_irte(m, table, BIT(int_tab_len >> 1)); 324 seq_puts(m, "\n"); 325 raw_spin_unlock_irqrestore(&table->lock, flags); 326 } 327 328 static int iommu_irqtbl_show(struct seq_file *m, void *unused) 329 { 330 struct amd_iommu_pci_seg *pci_seg; 331 u16 devid, seg; 332 int sbdf_shadow = sbdf; 333 334 if (!irq_remapping_enabled) { 335 seq_puts(m, "Interrupt remapping is disabled\n"); 336 return 0; 337 } 338 339 if (sbdf_shadow < 0) { 340 seq_puts(m, "Enter a valid device ID to 'devid' file\n"); 341 return 0; 342 } 343 344 seg = PCI_SBDF_TO_SEGID(sbdf_shadow); 345 devid = PCI_SBDF_TO_DEVID(sbdf_shadow); 346 347 for_each_pci_segment(pci_seg) { 348 if (pci_seg->id != seg) 349 continue; 350 dump_irte(m, devid, pci_seg); 351 break; 352 } 353 354 return 0; 355 } 356 DEFINE_SHOW_ATTRIBUTE(iommu_irqtbl); 357 358 void amd_iommu_debugfs_setup(void) 359 { 360 struct amd_iommu *iommu; 361 char name[MAX_NAME_LEN + 1]; 362 363 amd_iommu_debugfs = debugfs_create_dir("amd", iommu_debugfs_dir); 364 365 for_each_iommu(iommu) { 366 iommu->dbg_mmio_offset = -1; 367 iommu->dbg_cap_offset = -1; 368 369 snprintf(name, MAX_NAME_LEN, "iommu%02d", iommu->index); 370 iommu->debugfs = debugfs_create_dir(name, amd_iommu_debugfs); 371 372 debugfs_create_file("mmio", 0644, iommu->debugfs, iommu, 373 &iommu_mmio_fops); 374 debugfs_create_file("capability", 0644, iommu->debugfs, iommu, 375 &iommu_capability_fops); 376 debugfs_create_file("cmdbuf", 0444, iommu->debugfs, iommu, 377 &iommu_cmdbuf_fops); 378 } 379 380 debugfs_create_file("devid", 0644, amd_iommu_debugfs, NULL, 381 &devid_fops); 382 debugfs_create_file("devtbl", 0444, amd_iommu_debugfs, NULL, 383 &iommu_devtbl_fops); 384 debugfs_create_file("irqtbl", 0444, amd_iommu_debugfs, NULL, 385 &iommu_irqtbl_fops); 386 } 387