usb: typec: Fix unchecked return value
[linux-2.6-block.git] / drivers / iommu / intel-iommu-debugfs.c
CommitLineData
ee2636b8
SM
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright © 2018 Intel Corporation.
4 *
5 * Authors: Gayatri Kammela <gayatri.kammela@intel.com>
6 * Sohil Mehta <sohil.mehta@intel.com>
7 * Jacob Pan <jacob.jun.pan@linux.intel.com>
8 */
9
10#include <linux/debugfs.h>
11#include <linux/dmar.h>
12#include <linux/intel-iommu.h>
13#include <linux/pci.h>
14
15#include <asm/irq_remapping.h>
16
6825d3ea
GK
17struct iommu_regset {
18 int offset;
19 const char *regs;
20};
21
22#define IOMMU_REGSET_ENTRY(_reg_) \
23 { DMAR_##_reg_##_REG, __stringify(_reg_) }
24static const struct iommu_regset iommu_regs[] = {
25 IOMMU_REGSET_ENTRY(VER),
26 IOMMU_REGSET_ENTRY(CAP),
27 IOMMU_REGSET_ENTRY(ECAP),
28 IOMMU_REGSET_ENTRY(GCMD),
29 IOMMU_REGSET_ENTRY(GSTS),
30 IOMMU_REGSET_ENTRY(RTADDR),
31 IOMMU_REGSET_ENTRY(CCMD),
32 IOMMU_REGSET_ENTRY(FSTS),
33 IOMMU_REGSET_ENTRY(FECTL),
34 IOMMU_REGSET_ENTRY(FEDATA),
35 IOMMU_REGSET_ENTRY(FEADDR),
36 IOMMU_REGSET_ENTRY(FEUADDR),
37 IOMMU_REGSET_ENTRY(AFLOG),
38 IOMMU_REGSET_ENTRY(PMEN),
39 IOMMU_REGSET_ENTRY(PLMBASE),
40 IOMMU_REGSET_ENTRY(PLMLIMIT),
41 IOMMU_REGSET_ENTRY(PHMBASE),
42 IOMMU_REGSET_ENTRY(PHMLIMIT),
43 IOMMU_REGSET_ENTRY(IQH),
44 IOMMU_REGSET_ENTRY(IQT),
45 IOMMU_REGSET_ENTRY(IQA),
46 IOMMU_REGSET_ENTRY(ICS),
47 IOMMU_REGSET_ENTRY(IRTA),
48 IOMMU_REGSET_ENTRY(PQH),
49 IOMMU_REGSET_ENTRY(PQT),
50 IOMMU_REGSET_ENTRY(PQA),
51 IOMMU_REGSET_ENTRY(PRS),
52 IOMMU_REGSET_ENTRY(PECTL),
53 IOMMU_REGSET_ENTRY(PEDATA),
54 IOMMU_REGSET_ENTRY(PEADDR),
55 IOMMU_REGSET_ENTRY(PEUADDR),
56 IOMMU_REGSET_ENTRY(MTRRCAP),
57 IOMMU_REGSET_ENTRY(MTRRDEF),
58 IOMMU_REGSET_ENTRY(MTRR_FIX64K_00000),
59 IOMMU_REGSET_ENTRY(MTRR_FIX16K_80000),
60 IOMMU_REGSET_ENTRY(MTRR_FIX16K_A0000),
61 IOMMU_REGSET_ENTRY(MTRR_FIX4K_C0000),
62 IOMMU_REGSET_ENTRY(MTRR_FIX4K_C8000),
63 IOMMU_REGSET_ENTRY(MTRR_FIX4K_D0000),
64 IOMMU_REGSET_ENTRY(MTRR_FIX4K_D8000),
65 IOMMU_REGSET_ENTRY(MTRR_FIX4K_E0000),
66 IOMMU_REGSET_ENTRY(MTRR_FIX4K_E8000),
67 IOMMU_REGSET_ENTRY(MTRR_FIX4K_F0000),
68 IOMMU_REGSET_ENTRY(MTRR_FIX4K_F8000),
69 IOMMU_REGSET_ENTRY(MTRR_PHYSBASE0),
70 IOMMU_REGSET_ENTRY(MTRR_PHYSMASK0),
71 IOMMU_REGSET_ENTRY(MTRR_PHYSBASE1),
72 IOMMU_REGSET_ENTRY(MTRR_PHYSMASK1),
73 IOMMU_REGSET_ENTRY(MTRR_PHYSBASE2),
74 IOMMU_REGSET_ENTRY(MTRR_PHYSMASK2),
75 IOMMU_REGSET_ENTRY(MTRR_PHYSBASE3),
76 IOMMU_REGSET_ENTRY(MTRR_PHYSMASK3),
77 IOMMU_REGSET_ENTRY(MTRR_PHYSBASE4),
78 IOMMU_REGSET_ENTRY(MTRR_PHYSMASK4),
79 IOMMU_REGSET_ENTRY(MTRR_PHYSBASE5),
80 IOMMU_REGSET_ENTRY(MTRR_PHYSMASK5),
81 IOMMU_REGSET_ENTRY(MTRR_PHYSBASE6),
82 IOMMU_REGSET_ENTRY(MTRR_PHYSMASK6),
83 IOMMU_REGSET_ENTRY(MTRR_PHYSBASE7),
84 IOMMU_REGSET_ENTRY(MTRR_PHYSMASK7),
85 IOMMU_REGSET_ENTRY(MTRR_PHYSBASE8),
86 IOMMU_REGSET_ENTRY(MTRR_PHYSMASK8),
87 IOMMU_REGSET_ENTRY(MTRR_PHYSBASE9),
88 IOMMU_REGSET_ENTRY(MTRR_PHYSMASK9),
89 IOMMU_REGSET_ENTRY(VCCAP),
90 IOMMU_REGSET_ENTRY(VCMD),
91 IOMMU_REGSET_ENTRY(VCRSP),
92};
93
94static int iommu_regset_show(struct seq_file *m, void *unused)
95{
96 struct dmar_drhd_unit *drhd;
97 struct intel_iommu *iommu;
98 unsigned long flag;
99 int i, ret = 0;
100 u64 value;
101
102 rcu_read_lock();
103 for_each_active_iommu(iommu, drhd) {
104 if (!drhd->reg_base_addr) {
105 seq_puts(m, "IOMMU: Invalid base address\n");
106 ret = -EINVAL;
107 goto out;
108 }
109
110 seq_printf(m, "IOMMU: %s Register Base Address: %llx\n",
111 iommu->name, drhd->reg_base_addr);
112 seq_puts(m, "Name\t\t\tOffset\t\tContents\n");
113 /*
114 * Publish the contents of the 64-bit hardware registers
115 * by adding the offset to the pointer (virtual address).
116 */
117 raw_spin_lock_irqsave(&iommu->register_lock, flag);
118 for (i = 0 ; i < ARRAY_SIZE(iommu_regs); i++) {
119 value = dmar_readq(iommu->reg + iommu_regs[i].offset);
120 seq_printf(m, "%-16s\t0x%02x\t\t0x%016llx\n",
121 iommu_regs[i].regs, iommu_regs[i].offset,
122 value);
123 }
124 raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
125 seq_putc(m, '\n');
126 }
127out:
128 rcu_read_unlock();
129
130 return ret;
131}
132DEFINE_SHOW_ATTRIBUTE(iommu_regset);
133
18f99c9b
SM
134static void ctx_tbl_entry_show(struct seq_file *m, struct intel_iommu *iommu,
135 int bus)
136{
137 struct context_entry *context;
138 int devfn;
139
140 seq_printf(m, " Context Table Entries for Bus: %d\n", bus);
141 seq_puts(m, " Entry\tB:D.F\tHigh\tLow\n");
142
143 for (devfn = 0; devfn < 256; devfn++) {
144 context = iommu_context_addr(iommu, bus, devfn, 0);
145 if (!context)
146 return;
147
148 if (!context_present(context))
149 continue;
150
151 seq_printf(m, " %-5d\t%02x:%02x.%x\t%-6llx\t%llx\n", devfn,
152 bus, PCI_SLOT(devfn), PCI_FUNC(devfn),
153 context[0].hi, context[0].lo);
154 }
155}
156
157static void root_tbl_entry_show(struct seq_file *m, struct intel_iommu *iommu)
158{
159 unsigned long flags;
160 int bus;
161
162 spin_lock_irqsave(&iommu->lock, flags);
163 seq_printf(m, "IOMMU %s: Root Table Address:%llx\n", iommu->name,
164 (u64)virt_to_phys(iommu->root_entry));
165 seq_puts(m, "Root Table Entries:\n");
166
167 for (bus = 0; bus < 256; bus++) {
168 if (!(iommu->root_entry[bus].lo & 1))
169 continue;
170
171 seq_printf(m, " Bus: %d H: %llx L: %llx\n", bus,
172 iommu->root_entry[bus].hi,
173 iommu->root_entry[bus].lo);
174
175 ctx_tbl_entry_show(m, iommu, bus);
176 seq_putc(m, '\n');
177 }
178 spin_unlock_irqrestore(&iommu->lock, flags);
179}
180
181static int dmar_translation_struct_show(struct seq_file *m, void *unused)
182{
183 struct dmar_drhd_unit *drhd;
184 struct intel_iommu *iommu;
185
186 rcu_read_lock();
187 for_each_active_iommu(iommu, drhd) {
188 root_tbl_entry_show(m, iommu);
189 seq_putc(m, '\n');
190 }
191 rcu_read_unlock();
192
193 return 0;
194}
195DEFINE_SHOW_ATTRIBUTE(dmar_translation_struct);
196
a6d268c6
SM
197#ifdef CONFIG_IRQ_REMAP
198static void ir_tbl_remap_entry_show(struct seq_file *m,
199 struct intel_iommu *iommu)
200{
201 struct irte *ri_entry;
202 unsigned long flags;
203 int idx;
204
205 seq_puts(m, " Entry SrcID DstID Vct IRTE_high\t\tIRTE_low\n");
206
207 raw_spin_lock_irqsave(&irq_2_ir_lock, flags);
208 for (idx = 0; idx < INTR_REMAP_TABLE_ENTRIES; idx++) {
209 ri_entry = &iommu->ir_table->base[idx];
210 if (!ri_entry->present || ri_entry->p_pst)
211 continue;
212
213 seq_printf(m, " %-5d %02x:%02x.%01x %08x %02x %016llx\t%016llx\n",
214 idx, PCI_BUS_NUM(ri_entry->sid),
215 PCI_SLOT(ri_entry->sid), PCI_FUNC(ri_entry->sid),
216 ri_entry->dest_id, ri_entry->vector,
217 ri_entry->high, ri_entry->low);
218 }
219 raw_spin_unlock_irqrestore(&irq_2_ir_lock, flags);
220}
221
222static void ir_tbl_posted_entry_show(struct seq_file *m,
223 struct intel_iommu *iommu)
224{
225 struct irte *pi_entry;
226 unsigned long flags;
227 int idx;
228
229 seq_puts(m, " Entry SrcID PDA_high PDA_low Vct IRTE_high\t\tIRTE_low\n");
230
231 raw_spin_lock_irqsave(&irq_2_ir_lock, flags);
232 for (idx = 0; idx < INTR_REMAP_TABLE_ENTRIES; idx++) {
233 pi_entry = &iommu->ir_table->base[idx];
234 if (!pi_entry->present || !pi_entry->p_pst)
235 continue;
236
237 seq_printf(m, " %-5d %02x:%02x.%01x %08x %08x %02x %016llx\t%016llx\n",
238 idx, PCI_BUS_NUM(pi_entry->sid),
239 PCI_SLOT(pi_entry->sid), PCI_FUNC(pi_entry->sid),
240 pi_entry->pda_h, pi_entry->pda_l << 6,
241 pi_entry->vector, pi_entry->high,
242 pi_entry->low);
243 }
244 raw_spin_unlock_irqrestore(&irq_2_ir_lock, flags);
245}
246
247/*
248 * For active IOMMUs go through the Interrupt remapping
249 * table and print valid entries in a table format for
250 * Remapped and Posted Interrupts.
251 */
252static int ir_translation_struct_show(struct seq_file *m, void *unused)
253{
254 struct dmar_drhd_unit *drhd;
255 struct intel_iommu *iommu;
256 u64 irta;
257
258 rcu_read_lock();
259 for_each_active_iommu(iommu, drhd) {
260 if (!ecap_ir_support(iommu->ecap))
261 continue;
262
263 seq_printf(m, "Remapped Interrupt supported on IOMMU: %s\n",
264 iommu->name);
265
266 if (iommu->ir_table) {
267 irta = virt_to_phys(iommu->ir_table->base);
268 seq_printf(m, " IR table address:%llx\n", irta);
269 ir_tbl_remap_entry_show(m, iommu);
270 } else {
271 seq_puts(m, "Interrupt Remapping is not enabled\n");
272 }
273 seq_putc(m, '\n');
274 }
275
276 seq_puts(m, "****\n\n");
277
278 for_each_active_iommu(iommu, drhd) {
279 if (!cap_pi_support(iommu->cap))
280 continue;
281
282 seq_printf(m, "Posted Interrupt supported on IOMMU: %s\n",
283 iommu->name);
284
285 if (iommu->ir_table) {
286 irta = virt_to_phys(iommu->ir_table->base);
287 seq_printf(m, " IR table address:%llx\n", irta);
288 ir_tbl_posted_entry_show(m, iommu);
289 } else {
290 seq_puts(m, "Interrupt Remapping is not enabled\n");
291 }
292 seq_putc(m, '\n');
293 }
294 rcu_read_unlock();
295
296 return 0;
297}
298DEFINE_SHOW_ATTRIBUTE(ir_translation_struct);
299#endif
300
ee2636b8
SM
301void __init intel_iommu_debugfs_init(void)
302{
6825d3ea
GK
303 struct dentry *intel_iommu_debug = debugfs_create_dir("intel",
304 iommu_debugfs_dir);
305
306 debugfs_create_file("iommu_regset", 0444, intel_iommu_debug, NULL,
307 &iommu_regset_fops);
18f99c9b
SM
308 debugfs_create_file("dmar_translation_struct", 0444, intel_iommu_debug,
309 NULL, &dmar_translation_struct_fops);
a6d268c6
SM
310#ifdef CONFIG_IRQ_REMAP
311 debugfs_create_file("ir_translation_struct", 0444, intel_iommu_debug,
312 NULL, &ir_translation_struct_fops);
313#endif
ee2636b8 314}