Skip to content

Commit d87731f

Browse files
nuttyliujoergroedel
authored andcommitted
iommu/vt-d: debugfs: Create/remove debugfs file per {device, pasid}
Add a debugfs directory per pair of {device, pasid} if the mappings of its page table are created and destroyed by the iommu_map/unmap() interfaces. i.e. /sys/kernel/debug/iommu/intel/<device source id>/<pasid>. Create a debugfs file in the directory for users to dump the page table corresponding to {device, pasid}. e.g. /sys/kernel/debug/iommu/intel/0000:00:02.0/1/domain_translation_struct. For the default domain without pasid, it creates a debugfs file in the debugfs device directory for users to dump its page table. e.g. /sys/kernel/debug/iommu/intel/0000:00:02.0/domain_translation_struct. When setting a domain to a PASID of device, create a debugfs file in the pasid debugfs directory for users to dump the page table of the specified pasid. Remove the debugfs device directory of the device when releasing a device. e.g. /sys/kernel/debug/iommu/intel/0000:00:01.0 Signed-off-by: Jingqi Liu <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Lu Baolu <[email protected]> Signed-off-by: Joerg Roedel <[email protected]>
1 parent e8aa45f commit d87731f

File tree

3 files changed

+69
-5
lines changed

3 files changed

+69
-5
lines changed

drivers/iommu/intel/debugfs.c

Lines changed: 48 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,8 @@ static const struct iommu_regset iommu_regs_64[] = {
111111
IOMMU_REGSET_ENTRY(VCRSP),
112112
};
113113

114+
static struct dentry *intel_iommu_debug;
115+
114116
static int iommu_regset_show(struct seq_file *m, void *unused)
115117
{
116118
struct dmar_drhd_unit *drhd;
@@ -671,16 +673,12 @@ static const struct file_operations dmar_perf_latency_fops = {
671673

672674
void __init intel_iommu_debugfs_init(void)
673675
{
674-
struct dentry *intel_iommu_debug = debugfs_create_dir("intel",
675-
iommu_debugfs_dir);
676+
intel_iommu_debug = debugfs_create_dir("intel", iommu_debugfs_dir);
676677

677678
debugfs_create_file("iommu_regset", 0444, intel_iommu_debug, NULL,
678679
&iommu_regset_fops);
679680
debugfs_create_file("dmar_translation_struct", 0444, intel_iommu_debug,
680681
NULL, &dmar_translation_struct_fops);
681-
debugfs_create_file("domain_translation_struct", 0444,
682-
intel_iommu_debug, NULL,
683-
&domain_translation_struct_fops);
684682
debugfs_create_file("invalidation_queue", 0444, intel_iommu_debug,
685683
NULL, &invalidation_queue_fops);
686684
#ifdef CONFIG_IRQ_REMAP
@@ -690,3 +688,48 @@ void __init intel_iommu_debugfs_init(void)
690688
debugfs_create_file("dmar_perf_latency", 0644, intel_iommu_debug,
691689
NULL, &dmar_perf_latency_fops);
692690
}
691+
692+
/*
693+
* Create a debugfs directory for each device, and then create a
694+
* debugfs file in this directory for users to dump the page table
695+
* of the default domain. e.g.
696+
* /sys/kernel/debug/iommu/intel/0000:00:01.0/domain_translation_struct
697+
*/
698+
void intel_iommu_debugfs_create_dev(struct device_domain_info *info)
699+
{
700+
info->debugfs_dentry = debugfs_create_dir(dev_name(info->dev), intel_iommu_debug);
701+
702+
debugfs_create_file("domain_translation_struct", 0444, info->debugfs_dentry,
703+
NULL, &domain_translation_struct_fops);
704+
}
705+
706+
/* Remove the device debugfs directory. */
707+
void intel_iommu_debugfs_remove_dev(struct device_domain_info *info)
708+
{
709+
debugfs_remove_recursive(info->debugfs_dentry);
710+
}
711+
712+
/*
713+
* Create a debugfs directory per pair of {device, pasid}, then create the
714+
* corresponding debugfs file in this directory for users to dump its page
715+
* table. e.g.
716+
* /sys/kernel/debug/iommu/intel/0000:00:01.0/1/domain_translation_struct
717+
*
718+
* The debugfs only dumps the page tables whose mappings are created and
719+
* destroyed by the iommu_map/unmap() interfaces. Check the mapping type
720+
* of the domain before creating debugfs directory.
721+
*/
722+
void intel_iommu_debugfs_create_dev_pasid(struct dev_pasid_info *dev_pasid)
723+
{
724+
struct device_domain_info *info = dev_iommu_priv_get(dev_pasid->dev);
725+
char dir_name[10];
726+
727+
sprintf(dir_name, "%x", dev_pasid->pasid);
728+
dev_pasid->debugfs_dentry = debugfs_create_dir(dir_name, info->debugfs_dentry);
729+
}
730+
731+
/* Remove the device pasid debugfs directory. */
732+
void intel_iommu_debugfs_remove_dev_pasid(struct dev_pasid_info *dev_pasid)
733+
{
734+
debugfs_remove_recursive(dev_pasid->debugfs_dentry);
735+
}

drivers/iommu/intel/iommu.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4425,6 +4425,8 @@ static struct iommu_device *intel_iommu_probe_device(struct device *dev)
44254425
}
44264426
}
44274427

4428+
intel_iommu_debugfs_create_dev(info);
4429+
44284430
return &iommu->iommu;
44294431
}
44304432

@@ -4434,6 +4436,7 @@ static void intel_iommu_release_device(struct device *dev)
44344436

44354437
dmar_remove_one_dev_info(dev);
44364438
intel_pasid_free_table(dev);
4439+
intel_iommu_debugfs_remove_dev(info);
44374440
dev_iommu_priv_set(dev, NULL);
44384441
kfree(info);
44394442
set_dma_ops(dev, NULL);
@@ -4726,6 +4729,7 @@ static void intel_iommu_remove_dev_pasid(struct device *dev, ioasid_t pasid)
47264729
spin_unlock_irqrestore(&dmar_domain->lock, flags);
47274730

47284731
domain_detach_iommu(dmar_domain, iommu);
4732+
intel_iommu_debugfs_remove_dev_pasid(dev_pasid);
47294733
kfree(dev_pasid);
47304734
out_tear_down:
47314735
intel_pasid_tear_down_entry(iommu, dev, pasid, false);
@@ -4778,6 +4782,9 @@ static int intel_iommu_set_dev_pasid(struct iommu_domain *domain,
47784782
list_add(&dev_pasid->link_domain, &dmar_domain->dev_pasids);
47794783
spin_unlock_irqrestore(&dmar_domain->lock, flags);
47804784

4785+
if (domain->type & __IOMMU_DOMAIN_PAGING)
4786+
intel_iommu_debugfs_create_dev_pasid(dev_pasid);
4787+
47814788
return 0;
47824789
out_detach_iommu:
47834790
domain_detach_iommu(dmar_domain, iommu);

drivers/iommu/intel/iommu.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -716,12 +716,18 @@ struct device_domain_info {
716716
struct intel_iommu *iommu; /* IOMMU used by this device */
717717
struct dmar_domain *domain; /* pointer to domain */
718718
struct pasid_table *pasid_table; /* pasid table */
719+
#ifdef CONFIG_INTEL_IOMMU_DEBUGFS
720+
struct dentry *debugfs_dentry; /* pointer to device directory dentry */
721+
#endif
719722
};
720723

721724
struct dev_pasid_info {
722725
struct list_head link_domain; /* link to domain siblings */
723726
struct device *dev;
724727
ioasid_t pasid;
728+
#ifdef CONFIG_INTEL_IOMMU_DEBUGFS
729+
struct dentry *debugfs_dentry; /* pointer to pasid directory dentry */
730+
#endif
725731
};
726732

727733
static inline void __iommu_flush_cache(
@@ -883,8 +889,16 @@ static inline void intel_svm_remove_dev_pasid(struct device *dev, ioasid_t pasid
883889

884890
#ifdef CONFIG_INTEL_IOMMU_DEBUGFS
885891
void intel_iommu_debugfs_init(void);
892+
void intel_iommu_debugfs_create_dev(struct device_domain_info *info);
893+
void intel_iommu_debugfs_remove_dev(struct device_domain_info *info);
894+
void intel_iommu_debugfs_create_dev_pasid(struct dev_pasid_info *dev_pasid);
895+
void intel_iommu_debugfs_remove_dev_pasid(struct dev_pasid_info *dev_pasid);
886896
#else
887897
static inline void intel_iommu_debugfs_init(void) {}
898+
static inline void intel_iommu_debugfs_create_dev(struct device_domain_info *info) {}
899+
static inline void intel_iommu_debugfs_remove_dev(struct device_domain_info *info) {}
900+
static inline void intel_iommu_debugfs_create_dev_pasid(struct dev_pasid_info *dev_pasid) {}
901+
static inline void intel_iommu_debugfs_remove_dev_pasid(struct dev_pasid_info *dev_pasid) {}
888902
#endif /* CONFIG_INTEL_IOMMU_DEBUGFS */
889903

890904
extern const struct attribute_group *intel_iommu_groups[];

0 commit comments

Comments
 (0)