debugfs.c 9.2 KB

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