Skip to content

Commit 4c0fa5b

Browse files
LuBaolujoergroedel
authored andcommitted
iommu/vt-d: debugfs: Add support to show inv queue internals
Export invalidation queue internals of each iommu device through the debugfs. Example of such dump on a Skylake machine: $ sudo cat /sys/kernel/debug/iommu/intel/invalidation_queue Invalidation queue on IOMMU: dmar1 Base: 0x1672c9000 Head: 80 Tail: 80 Index qw0 qw1 status 0 0000000000000004 0000000000000000 0000000000000000 1 0000000200000025 00000001672be804 0000000000000000 2 0000000000000011 0000000000000000 0000000000000000 3 0000000200000025 00000001672be80c 0000000000000000 4 00000000000000d2 0000000000000000 0000000000000000 5 0000000200000025 00000001672be814 0000000000000000 6 0000000000000014 0000000000000000 0000000000000000 7 0000000200000025 00000001672be81c 0000000000000000 8 0000000000000014 0000000000000000 0000000000000000 9 0000000200000025 00000001672be824 0000000000000000 Signed-off-by: Lu Baolu <[email protected]> Reviewed-by: Kevin Tian <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Joerg Roedel <[email protected]>
1 parent 8a1d824 commit 4c0fa5b

File tree

1 file changed

+62
-0
lines changed

1 file changed

+62
-0
lines changed

drivers/iommu/intel-iommu-debugfs.c

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,66 @@ static int domain_translation_struct_show(struct seq_file *m, void *unused)
372372
}
373373
DEFINE_SHOW_ATTRIBUTE(domain_translation_struct);
374374

375+
static void invalidation_queue_entry_show(struct seq_file *m,
376+
struct intel_iommu *iommu)
377+
{
378+
int index, shift = qi_shift(iommu);
379+
struct qi_desc *desc;
380+
int offset;
381+
382+
if (ecap_smts(iommu->ecap))
383+
seq_puts(m, "Index\t\tqw0\t\t\tqw1\t\t\tqw2\t\t\tqw3\t\t\tstatus\n");
384+
else
385+
seq_puts(m, "Index\t\tqw0\t\t\tqw1\t\t\tstatus\n");
386+
387+
for (index = 0; index < QI_LENGTH; index++) {
388+
offset = index << shift;
389+
desc = iommu->qi->desc + offset;
390+
if (ecap_smts(iommu->ecap))
391+
seq_printf(m, "%5d\t%016llx\t%016llx\t%016llx\t%016llx\t%016x\n",
392+
index, desc->qw0, desc->qw1,
393+
desc->qw2, desc->qw3,
394+
iommu->qi->desc_status[index]);
395+
else
396+
seq_printf(m, "%5d\t%016llx\t%016llx\t%016x\n",
397+
index, desc->qw0, desc->qw1,
398+
iommu->qi->desc_status[index]);
399+
}
400+
}
401+
402+
static int invalidation_queue_show(struct seq_file *m, void *unused)
403+
{
404+
struct dmar_drhd_unit *drhd;
405+
struct intel_iommu *iommu;
406+
unsigned long flags;
407+
struct q_inval *qi;
408+
int shift;
409+
410+
rcu_read_lock();
411+
for_each_active_iommu(iommu, drhd) {
412+
qi = iommu->qi;
413+
shift = qi_shift(iommu);
414+
415+
if (!qi || !ecap_qis(iommu->ecap))
416+
continue;
417+
418+
seq_printf(m, "Invalidation queue on IOMMU: %s\n", iommu->name);
419+
420+
raw_spin_lock_irqsave(&qi->q_lock, flags);
421+
seq_printf(m, " Base: 0x%llx\tHead: %lld\tTail: %lld\n",
422+
(u64)virt_to_phys(qi->desc),
423+
dmar_readq(iommu->reg + DMAR_IQH_REG) >> shift,
424+
dmar_readq(iommu->reg + DMAR_IQT_REG) >> shift);
425+
invalidation_queue_entry_show(m, iommu);
426+
raw_spin_unlock_irqrestore(&qi->q_lock, flags);
427+
seq_putc(m, '\n');
428+
}
429+
rcu_read_unlock();
430+
431+
return 0;
432+
}
433+
DEFINE_SHOW_ATTRIBUTE(invalidation_queue);
434+
375435
#ifdef CONFIG_IRQ_REMAP
376436
static void ir_tbl_remap_entry_show(struct seq_file *m,
377437
struct intel_iommu *iommu)
@@ -490,6 +550,8 @@ void __init intel_iommu_debugfs_init(void)
490550
debugfs_create_file("domain_translation_struct", 0444,
491551
intel_iommu_debug, NULL,
492552
&domain_translation_struct_fops);
553+
debugfs_create_file("invalidation_queue", 0444, intel_iommu_debug,
554+
NULL, &invalidation_queue_fops);
493555
#ifdef CONFIG_IRQ_REMAP
494556
debugfs_create_file("ir_translation_struct", 0444, intel_iommu_debug,
495557
NULL, &ir_translation_struct_fops);

0 commit comments

Comments
 (0)