On 9/27/23 11:15 PM, Jingqi Liu wrote:......
Thanks. Good point.+
+/* Create a debugfs directory for each device. */
+void intel_iommu_debugfs_create_dev(struct device *dev)
+{
+ struct dentry *dev_dir;
+
+ dev_dir = debugfs_lookup(dev_name(dev), intel_iommu_debug);
+ if (!dev_dir) {
+ dev_dir = debugfs_create_dir(dev_name(dev), intel_iommu_debug);
+ if (IS_ERR(dev_dir))
+ pr_info("%s: Failed to create debugfs directory.\n",
+ dev_name(dev));
+ } else
+ dput(dev_dir);
+}
Above could simply be like this:
void intel_iommu_debugfs_create_dev(struct device *dev)
{
struct device_domain_info *info = dev_iommu_priv_get(dev);
info->debugfs_entry = debugfs_create_dir(dev_name(dev),
intel_iommu_debug);
}
Isn't it?
Yes.
+
+void intel_iommu_debugfs_remove_dev(struct device *dev)
+{
+ struct dentry *dev_dir, *sub_dir, *dentry;
+ struct list_head *plist;
+
+ dev_dir = debugfs_lookup(dev_name(dev), intel_iommu_debug);
+ if (!dev_dir)
+ return;
+
+ list_for_each(plist, &(dev_dir->d_subdirs)) {
+ sub_dir = list_entry(plist, struct dentry, d_child);
+ if(sub_dir) {
+ dentry = debugfs_lookup("domain_translation_struct",
+ sub_dir);
+ if (!dentry)
+ continue;
+
+ if (dentry->d_inode->i_private)
+ kfree(dentry->d_inode->i_private);
+
+ dput(dentry);
+ }
+ }
+
+ debugfs_remove_recursive(dev_dir);
+ dput(dev_dir);
+}
And this could simply be like this:
void intel_iommu_debugfs_remove_dev(struct device *dev)
{
struct device_domain_info *info = dev_iommu_priv_get(dev);
debugfs_remove(info->debugfs_entry);
}
Thanks.+
+/*
+ * Create a debugfs directory per pair of {device, pasid},
+ * then create the corresponding debugfs file in this directory
+ * for user to dump its page table. e.g.
+ * /sys/kernel/debug/iommu/intel/0000:00:01.0/0/domain_translation_struct
+ */
+void intel_iommu_debugfs_create_dev_pasid(struct iommu_domain *domain,
+ struct device *dev, u32 pasid)
+{
+ struct dentry *dev_dir, *pasid_dir;
+ struct show_domain_info *sinfo;
+ char dir_name[10];
+
+ /*
+ * The debugfs only dumps the page tables whose mappings are created
+ * and destroyed by the iommu_map/unmap() interfaces. Check the
+ * mapping type of the domain before creating debugfs directory.
+ */
+ if (!domain || !(domain->type & __IOMMU_DOMAIN_PAGING))
+ return;
+
+ dev_dir = debugfs_lookup(dev_name(dev), intel_iommu_debug);
+ if (!dev_dir)
+ return;
+
+ sprintf(dir_name, "%x", pasid);
+ pasid_dir = debugfs_create_dir(dir_name, dev_dir);
+ if (IS_ERR(pasid_dir))
+ goto dput_out;
+
+ sinfo = kzalloc(sizeof(*sinfo), GFP_KERNEL);
+ if (!sinfo)
+ goto dput_out;
+
+ sinfo->dev = dev;
+ sinfo->pasid = pasid;
+ debugfs_create_file("domain_translation_struct", 0444,
+ pasid_dir, sinfo,
+ &domain_translation_struct_fops);
+dput_out:
+ dput(dev_dir);
+}
And here,
void intel_iommu_debugfs_create_dev_pasid(struct iommu_domain *domain,
struct device *dev, u32 pasid)
{
sprintf(dir_name, "%x", pasid);
dev_pasid->debugfs_entry = debugfs_create_dir(dir_name,
info->debugfs_entry);
debugfs_create_file("domain_translation_struct", 0444,
dev_pasid->debugfs_entry, dev_pasid,
&domain_translation_struct_fops);
}
Yes.+
+/*
+ * Remove the debugfs directory and file corresponding to each pair of
+ * {device, pasid}.
+ */
+void intel_iommu_debugfs_remove_dev_pasid(struct device *dev, u32 pasid)
+{
+ struct dentry *dev_dir, *pasid_dir, *dentry;
+ char dir_name[10];
+
+ dev_dir = debugfs_lookup(dev_name(dev), intel_iommu_debug);
+ if (!dev_dir)
+ return;
+
+ sprintf(dir_name, "%x", pasid);
+ pasid_dir = debugfs_lookup(dir_name, dev_dir);
+ if (!pasid_dir)
+ goto dput_dev;
+
+ dentry = debugfs_lookup("domain_translation_struct", pasid_dir);
+ if (!dentry)
+ goto dput_pasid;
+
+ if (dentry->d_inode->i_private)
+ kfree(dentry->d_inode->i_private);
+
+ debugfs_remove_recursive(pasid_dir);
+
+ dput(dentry);
+dput_pasid:
+ dput(pasid_dir);
+dput_dev:
+ dput(dev_dir);
+}
The same thing here:
debugfs_remove(dev_pasid->debugfs_entry);
Indeed.diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
index dd8ff358867d..af9c989035a2 100644
--- a/drivers/iommu/intel/iommu.c
+++ b/drivers/iommu/intel/iommu.c
@@ -2488,6 +2488,13 @@ static int dmar_domain_attach_device(struct dmar_domain *domain,
iommu_enable_pci_caps(info);
+ /*
+ * Create a debugfs directory specified by RID_PASID
+ * in the debugfs device directory.
+ */
+ intel_iommu_debugfs_create_dev_pasid(&info->domain->domain,
+ dev, IOMMU_NO_PASID);
The function name is self-explained. So no need to add comments. Ditto
to all other places.