Linux virtualization list
 help / color / mirror / Atom feed
* [PATCH] iommu/virtio: Add debugfs state dump
@ 2026-07-31  1:48 LiMing Wu
  2026-08-17  3:41 ` kernel test robot
  2026-08-17  4:42 ` kernel test robot
  0 siblings, 2 replies; 3+ messages in thread
From: LiMing Wu @ 2026-07-31  1:48 UTC (permalink / raw)
  To: Jean-Philippe Brucker, Joerg Roedel (AMD)
  Cc: Will Deacon, Robin Murphy, virtualization, iommu, angus.chen,
	Liming Wu

From: Liming Wu <liming.wu@jaguarmicro.com>

Expose basic virtio-iommu runtime state through debugfs so that the
relationship between endpoints, IOMMU groups, domains and active mappings
can be inspected from a running guest.

Create per-device files under /sys/kernel/debug/iommu/virtio/:

  status    - negotiated virtio-iommu features and geometry
  endpoints - endpoint, group and attached domain information
  domains   - domain type, endpoint count and mapping count
  mappings  - active IOVA mappings tracked by the driver

Assisted-by: Codex:gpt-5.5
Signed-off-by: Liming Wu <liming.wu@jaguarmicro.com>
---
 drivers/iommu/virtio-iommu.c | 317 ++++++++++++++++++++++++++++++++++-
 1 file changed, 316 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/virtio-iommu.c b/drivers/iommu/virtio-iommu.c
index 587fc13197f1..9f2355bcf144 100644
--- a/drivers/iommu/virtio-iommu.c
+++ b/drivers/iommu/virtio-iommu.c
@@ -8,13 +8,16 @@
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
 #include <linux/delay.h>
+#include <linux/debugfs.h>
 #include <linux/dma-map-ops.h>
 #include <linux/freezer.h>
 #include <linux/interval_tree.h>
 #include <linux/iommu.h>
 #include <linux/module.h>
+#include <linux/mutex.h>
 #include <linux/of.h>
 #include <linux/pci.h>
+#include <linux/seq_file.h>
 #include <linux/virtio.h>
 #include <linux/virtio_config.h>
 #include <linux/virtio_ids.h>
@@ -52,6 +55,14 @@ struct viommu_dev {
 	/* Supported MAP flags */
 	u32				map_flags;
 	u32				probe_size;
+
+#ifdef CONFIG_IOMMU_DEBUGFS
+	struct dentry			*debugfs_dir;
+	/* Protects debugfs_domains and debugfs_endpoints. */
+	struct mutex			debugfs_lock;
+	struct list_head		debugfs_domains;
+	struct list_head		debugfs_endpoints;
+#endif
 };
 
 struct viommu_mapping {
@@ -70,6 +81,10 @@ struct viommu_domain {
 	struct rb_root_cached		mappings;
 
 	unsigned long			nr_endpoints;
+
+#ifdef CONFIG_IOMMU_DEBUGFS
+	struct list_head		debugfs_node;
+#endif
 };
 
 struct viommu_endpoint {
@@ -77,6 +92,10 @@ struct viommu_endpoint {
 	struct viommu_dev		*viommu;
 	struct viommu_domain		*vdomain;
 	struct list_head		resv_regions;
+
+#ifdef CONFIG_IOMMU_DEBUGFS
+	struct list_head		debugfs_node;
+#endif
 };
 
 struct viommu_request {
@@ -101,6 +120,283 @@ static struct viommu_domain viommu_identity_domain;
 #define to_viommu_domain(domain)	\
 	container_of(domain, struct viommu_domain, domain)
 
+#ifdef CONFIG_IOMMU_DEBUGFS
+static struct dentry *viommu_debugfs_root;
+
+static const char *viommu_domain_type_name(unsigned int type)
+{
+	switch (type) {
+	case IOMMU_DOMAIN_BLOCKED:
+		return "blocked";
+	case IOMMU_DOMAIN_IDENTITY:
+		return "identity";
+	case IOMMU_DOMAIN_UNMANAGED:
+		return "unmanaged";
+	case IOMMU_DOMAIN_DMA:
+		return "dma";
+	case IOMMU_DOMAIN_DMA_FQ:
+		return "dma-fq";
+	case IOMMU_DOMAIN_SVA:
+		return "sva";
+	case IOMMU_DOMAIN_PLATFORM:
+		return "platform";
+	case IOMMU_DOMAIN_NESTED:
+		return "nested";
+	default:
+		return "unknown";
+	}
+}
+
+static void viommu_debugfs_feature(struct seq_file *s,
+				   struct viommu_dev *viommu,
+				   unsigned int feature,
+				   const char *name)
+{
+	seq_printf(s, "  %-24s %s\n", name,
+		   virtio_has_feature(viommu->vdev, feature) ? "yes" : "no");
+}
+
+static int viommu_debugfs_status_show(struct seq_file *s, void *unused)
+{
+	struct viommu_dev *viommu = s->private;
+
+	seq_printf(s, "device: %s\n", virtio_bus_name(viommu->vdev));
+	seq_printf(s, "input_range: %#llx-%#llx\n",
+		   viommu->geometry.aperture_start,
+		   viommu->geometry.aperture_end);
+	seq_printf(s, "page_size_mask: %#llx\n", viommu->pgsize_bitmap);
+	seq_printf(s, "domain_range: %u-%u\n", viommu->first_domain,
+		   viommu->last_domain);
+	seq_printf(s, "identity_domain_id: %u\n",
+		   viommu->identity_domain_id);
+	seq_printf(s, "probe_size: %u\n", viommu->probe_size);
+	seq_printf(s, "map_flags: %#x\n", viommu->map_flags);
+	seq_puts(s, "features:\n");
+	viommu_debugfs_feature(s, viommu, VIRTIO_IOMMU_F_MAP_UNMAP,
+			       "map_unmap");
+	viommu_debugfs_feature(s, viommu, VIRTIO_IOMMU_F_INPUT_RANGE,
+			       "input_range");
+	viommu_debugfs_feature(s, viommu, VIRTIO_IOMMU_F_DOMAIN_RANGE,
+			       "domain_range");
+	viommu_debugfs_feature(s, viommu, VIRTIO_IOMMU_F_PROBE, "probe");
+	viommu_debugfs_feature(s, viommu, VIRTIO_IOMMU_F_MMIO, "mmio");
+	viommu_debugfs_feature(s, viommu, VIRTIO_IOMMU_F_BYPASS_CONFIG,
+			       "bypass_config");
+
+	return 0;
+}
+DEFINE_SHOW_ATTRIBUTE(viommu_debugfs_status);
+
+static void viommu_debugfs_print_endpoint(struct seq_file *s,
+					  struct viommu_endpoint *vdev)
+{
+	int i;
+	u32 domain_id = 0;
+	const char *domain_type = "none";
+	struct iommu_group *group;
+	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(vdev->dev);
+
+	if (vdev->vdomain) {
+		domain_type = viommu_domain_type_name(vdev->vdomain->domain.type);
+		if (vdev->vdomain == &viommu_identity_domain)
+			domain_id = vdev->viommu->identity_domain_id;
+		else
+			domain_id = vdev->vdomain->id;
+	}
+
+	group = iommu_group_get(vdev->dev);
+	seq_printf(s, "endpoint=%s group_id=%d domain_type=%s",
+		   dev_name(vdev->dev), group ? iommu_group_id(group) : -1,
+		   domain_type);
+	if (vdev->vdomain)
+		seq_printf(s, " domain_id=%u", domain_id);
+	if (fwspec) {
+		seq_puts(s, " ids=");
+		for (i = 0; i < fwspec->num_ids; i++)
+			seq_printf(s, "%s%u", i ? "," : "", fwspec->ids[i]);
+	}
+	seq_putc(s, '\n');
+
+	iommu_group_put(group);
+}
+
+static int viommu_debugfs_endpoints_show(struct seq_file *s, void *unused)
+{
+	struct viommu_dev *viommu = s->private;
+	struct viommu_endpoint *vdev;
+
+	mutex_lock(&viommu->debugfs_lock);
+	list_for_each_entry(vdev, &viommu->debugfs_endpoints, debugfs_node)
+		viommu_debugfs_print_endpoint(s, vdev);
+	mutex_unlock(&viommu->debugfs_lock);
+
+	return 0;
+}
+DEFINE_SHOW_ATTRIBUTE(viommu_debugfs_endpoints);
+
+static unsigned long viommu_debugfs_count_mappings(struct viommu_domain *vdomain)
+{
+	unsigned long count = 0;
+	struct interval_tree_node *node;
+
+	for (node = interval_tree_iter_first(&vdomain->mappings, 0, ULLONG_MAX);
+	     node; node = interval_tree_iter_next(node, 0, ULLONG_MAX))
+		count++;
+
+	return count;
+}
+
+static void viommu_debugfs_print_domain(struct seq_file *s,
+					struct viommu_domain *vdomain)
+{
+	unsigned long flags;
+	unsigned long mappings;
+
+	spin_lock_irqsave(&vdomain->mappings_lock, flags);
+	mappings = viommu_debugfs_count_mappings(vdomain);
+	spin_unlock_irqrestore(&vdomain->mappings_lock, flags);
+
+	seq_printf(s,
+		   "id=%u type=%s endpoints=%lu mappings=%lu aperture=%#llx-%#llx pgsize_bitmap=%#lx map_flags=%#x\n",
+		   vdomain->id, viommu_domain_type_name(vdomain->domain.type),
+		   vdomain->nr_endpoints, mappings,
+		   vdomain->domain.geometry.aperture_start,
+		   vdomain->domain.geometry.aperture_end,
+		   vdomain->domain.pgsize_bitmap, vdomain->map_flags);
+}
+
+static int viommu_debugfs_domains_show(struct seq_file *s, void *unused)
+{
+	struct viommu_dev *viommu = s->private;
+	struct viommu_domain *vdomain;
+
+	mutex_lock(&viommu->debugfs_lock);
+	if (viommu_identity_domain.nr_endpoints) {
+		seq_printf(s, "id=%u type=%s endpoints=%lu mappings=identity\n",
+			   viommu->identity_domain_id,
+			   viommu_domain_type_name(viommu_identity_domain.domain.type),
+			   viommu_identity_domain.nr_endpoints);
+	}
+	list_for_each_entry(vdomain, &viommu->debugfs_domains, debugfs_node)
+		viommu_debugfs_print_domain(s, vdomain);
+	mutex_unlock(&viommu->debugfs_lock);
+
+	return 0;
+}
+DEFINE_SHOW_ATTRIBUTE(viommu_debugfs_domains);
+
+static void viommu_debugfs_print_mapping(struct seq_file *s,
+					 struct viommu_domain *vdomain)
+{
+	unsigned long flags;
+	struct viommu_mapping *mapping;
+	struct interval_tree_node *node;
+
+	spin_lock_irqsave(&vdomain->mappings_lock, flags);
+	for (node = interval_tree_iter_first(&vdomain->mappings, 0, ULLONG_MAX);
+	     node; node = interval_tree_iter_next(node, 0, ULLONG_MAX)) {
+		mapping = container_of(node, struct viommu_mapping, iova);
+		seq_printf(s,
+			   "domain_id=%u iova=%#lx-%#lx phys=%pa size=%#lx flags=%#x\n",
+			   vdomain->id, mapping->iova.start, mapping->iova.last,
+			   &mapping->paddr,
+			   mapping->iova.last - mapping->iova.start + 1,
+			   mapping->flags);
+	}
+	spin_unlock_irqrestore(&vdomain->mappings_lock, flags);
+}
+
+static int viommu_debugfs_mappings_show(struct seq_file *s, void *unused)
+{
+	struct viommu_dev *viommu = s->private;
+	struct viommu_domain *vdomain;
+
+	mutex_lock(&viommu->debugfs_lock);
+	list_for_each_entry(vdomain, &viommu->debugfs_domains, debugfs_node)
+		viommu_debugfs_print_mapping(s, vdomain);
+	mutex_unlock(&viommu->debugfs_lock);
+
+	return 0;
+}
+DEFINE_SHOW_ATTRIBUTE(viommu_debugfs_mappings);
+
+static void viommu_debugfs_init(struct viommu_dev *viommu)
+{
+	struct dentry *parent;
+
+	if (!iommu_debugfs_dir)
+		return;
+
+	if (!viommu_debugfs_root)
+		viommu_debugfs_root = debugfs_create_dir("virtio",
+							 iommu_debugfs_dir);
+
+	parent = viommu_debugfs_root ?: iommu_debugfs_dir;
+	viommu->debugfs_dir = debugfs_create_dir(virtio_bus_name(viommu->vdev),
+						 parent);
+	if (IS_ERR_OR_NULL(viommu->debugfs_dir))
+		return;
+
+	debugfs_create_file("status", 0444, viommu->debugfs_dir, viommu,
+			    &viommu_debugfs_status_fops);
+	debugfs_create_file("endpoints", 0444, viommu->debugfs_dir, viommu,
+			    &viommu_debugfs_endpoints_fops);
+	debugfs_create_file("domains", 0444, viommu->debugfs_dir, viommu,
+			    &viommu_debugfs_domains_fops);
+	debugfs_create_file("mappings", 0444, viommu->debugfs_dir, viommu,
+			    &viommu_debugfs_mappings_fops);
+}
+
+static void viommu_debugfs_remove(struct viommu_dev *viommu)
+{
+	debugfs_remove_recursive(viommu->debugfs_dir);
+	viommu->debugfs_dir = NULL;
+}
+
+static void viommu_debugfs_add_domain(struct viommu_domain *vdomain)
+{
+	struct viommu_dev *viommu = vdomain->viommu;
+
+	mutex_lock(&viommu->debugfs_lock);
+	list_add_tail(&vdomain->debugfs_node, &viommu->debugfs_domains);
+	mutex_unlock(&viommu->debugfs_lock);
+}
+
+static void viommu_debugfs_remove_domain(struct viommu_domain *vdomain)
+{
+	struct viommu_dev *viommu = vdomain->viommu;
+
+	mutex_lock(&viommu->debugfs_lock);
+	list_del(&vdomain->debugfs_node);
+	mutex_unlock(&viommu->debugfs_lock);
+}
+
+static void viommu_debugfs_add_endpoint(struct viommu_endpoint *vdev)
+{
+	struct viommu_dev *viommu = vdev->viommu;
+
+	mutex_lock(&viommu->debugfs_lock);
+	list_add_tail(&vdev->debugfs_node, &viommu->debugfs_endpoints);
+	mutex_unlock(&viommu->debugfs_lock);
+}
+
+static void viommu_debugfs_remove_endpoint(struct viommu_endpoint *vdev)
+{
+	struct viommu_dev *viommu = vdev->viommu;
+
+	mutex_lock(&viommu->debugfs_lock);
+	list_del(&vdev->debugfs_node);
+	mutex_unlock(&viommu->debugfs_lock);
+}
+#else
+static void viommu_debugfs_init(struct viommu_dev *viommu) {}
+static void viommu_debugfs_remove(struct viommu_dev *viommu) {}
+static void viommu_debugfs_add_domain(struct viommu_domain *vdomain) {}
+static void viommu_debugfs_remove_domain(struct viommu_domain *vdomain) {}
+static void viommu_debugfs_add_endpoint(struct viommu_endpoint *vdev) {}
+static void viommu_debugfs_remove_endpoint(struct viommu_endpoint *vdev) {}
+#endif
+
 static int viommu_get_req_errno(void *buf, size_t len)
 {
 	struct virtio_iommu_req_tail *tail = buf + len - sizeof(*tail);
@@ -676,6 +972,9 @@ static struct iommu_domain *viommu_domain_alloc_paging(struct device *dev)
 
 	spin_lock_init(&vdomain->mappings_lock);
 	vdomain->mappings = RB_ROOT_CACHED;
+#ifdef CONFIG_IOMMU_DEBUGFS
+	INIT_LIST_HEAD(&vdomain->debugfs_node);
+#endif
 
 	ret = ida_alloc_range(&viommu->domain_ids, viommu->first_domain,
 			      viommu->last_domain, GFP_KERNEL);
@@ -691,6 +990,7 @@ static struct iommu_domain *viommu_domain_alloc_paging(struct device *dev)
 
 	vdomain->map_flags = viommu->map_flags;
 	vdomain->viommu = viommu;
+	viommu_debugfs_add_domain(vdomain);
 
 	return &vdomain->domain;
 }
@@ -702,8 +1002,10 @@ static void viommu_domain_free(struct iommu_domain *domain)
 	/* Free all remaining mappings */
 	viommu_del_mappings(vdomain, 0, ULLONG_MAX);
 
-	if (vdomain->viommu)
+	if (vdomain->viommu) {
+		viommu_debugfs_remove_domain(vdomain);
 		ida_free(&vdomain->viommu->domain_ids, vdomain->id);
+	}
 
 	kfree(vdomain);
 }
@@ -1035,6 +1337,9 @@ static struct iommu_device *viommu_probe_device(struct device *dev)
 	vdev->dev = dev;
 	vdev->viommu = viommu;
 	INIT_LIST_HEAD(&vdev->resv_regions);
+#ifdef CONFIG_IOMMU_DEBUGFS
+	INIT_LIST_HEAD(&vdev->debugfs_node);
+#endif
 	dev_iommu_priv_set(dev, vdev);
 
 	if (viommu->probe_size) {
@@ -1044,6 +1349,8 @@ static struct iommu_device *viommu_probe_device(struct device *dev)
 			goto err_free_dev;
 	}
 
+	viommu_debugfs_add_endpoint(vdev);
+
 	return &viommu->iommu;
 
 err_free_dev:
@@ -1057,6 +1364,7 @@ static void viommu_release_device(struct device *dev)
 {
 	struct viommu_endpoint *vdev = dev_iommu_priv_get(dev);
 
+	viommu_debugfs_remove_endpoint(vdev);
 	viommu_detach_dev(vdev);
 	iommu_put_resv_regions(dev, &vdev->resv_regions);
 	kfree(vdev);
@@ -1170,6 +1478,11 @@ static int viommu_probe(struct virtio_device *vdev)
 	viommu->dev = dev;
 	viommu->vdev = vdev;
 	INIT_LIST_HEAD(&viommu->requests);
+#ifdef CONFIG_IOMMU_DEBUGFS
+	mutex_init(&viommu->debugfs_lock);
+	INIT_LIST_HEAD(&viommu->debugfs_domains);
+	INIT_LIST_HEAD(&viommu->debugfs_endpoints);
+#endif
 
 	ret = viommu_init_vqs(viommu);
 	if (ret)
@@ -1237,6 +1550,7 @@ static int viommu_probe(struct virtio_device *vdev)
 	vdev->priv = viommu;
 
 	iommu_device_register(&viommu->iommu, &viommu_ops, parent_dev);
+	viommu_debugfs_init(viommu);
 
 	dev_info(dev, "input address: %u bits\n",
 		 order_base_2(viommu->geometry.aperture_end));
@@ -1254,6 +1568,7 @@ static void viommu_remove(struct virtio_device *vdev)
 {
 	struct viommu_dev *viommu = vdev->priv;
 
+	viommu_debugfs_remove(viommu);
 	iommu_device_sysfs_remove(&viommu->iommu);
 	iommu_device_unregister(&viommu->iommu);
 
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH] iommu/virtio: Add debugfs state dump
  2026-07-31  1:48 [PATCH] iommu/virtio: Add debugfs state dump LiMing Wu
@ 2026-08-17  3:41 ` kernel test robot
  2026-08-17  4:42 ` kernel test robot
  1 sibling, 0 replies; 3+ messages in thread
From: kernel test robot @ 2026-08-17  3:41 UTC (permalink / raw)
  To: LiMing Wu, Jean-Philippe Brucker, Joerg Roedel (AMD)
  Cc: oe-kbuild-all, Will Deacon, Robin Murphy, virtualization, iommu,
	angus.chen, Liming Wu

Hi LiMing,

kernel test robot noticed the following build warnings:

[auto build test WARNING on linus/master]
[also build test WARNING on arm-perf/for-next/perf v7.2-rc7 next-20260814]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/LiMing-Wu/iommu-virtio-Add-debugfs-state-dump/20260815-175817
base:   linus/master
patch link:    https://lore.kernel.org/r/20260731014838.31187-1-liming.wu%40jaguarmicro.com
patch subject: [PATCH] iommu/virtio: Add debugfs state dump
config: i386-randconfig-141-20260817 (https://download.01.org/0day-ci/archive/20260817/202608171132.xtGhKM9V-lkp@intel.com/config)
compiler: clang version 22.1.3 (https://github.com/llvm/llvm-project e9846648fd6183ee6d8cbdb4502213fcf902a211)
smatch: v0.5.0-9187-g5189e3fb
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260817/202608171132.xtGhKM9V-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202608171132.xtGhKM9V-lkp@intel.com/

All warnings (new ones prefixed by >>):

>> drivers/iommu/virtio-iommu.c:165:6: warning: format specifies type 'unsigned long long' but the argument has type 'dma_addr_t' (aka 'unsigned int') [-Wformat]
     164 |         seq_printf(s, "input_range: %#llx-%#llx\n",
         |                                     ~~~~~
         |                                     %#x
     165 |                    viommu->geometry.aperture_start,
         |                    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/iommu/virtio-iommu.c:166:6: warning: format specifies type 'unsigned long long' but the argument has type 'dma_addr_t' (aka 'unsigned int') [-Wformat]
     164 |         seq_printf(s, "input_range: %#llx-%#llx\n",
         |                                           ~~~~~
         |                                           %#x
     165 |                    viommu->geometry.aperture_start,
     166 |                    viommu->geometry.aperture_end);
         |                    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/iommu/virtio-iommu.c:242:62: warning: implicit conversion from 'unsigned long long' to 'unsigned long' changes value from 18446744073709551615 to 4294967295 [-Wconstant-conversion]
     242 |         for (node = interval_tree_iter_first(&vdomain->mappings, 0, ULLONG_MAX);
         |                     ~~~~~~~~~~~~~~~~~~~~~~~~                        ^~~~~~~~~~
   include/vdso/limits.h:16:21: note: expanded from macro 'ULLONG_MAX'
      16 | #define ULLONG_MAX      (~0ULL)
         |                          ^~~~~
   drivers/iommu/virtio-iommu.c:243:53: warning: implicit conversion from 'unsigned long long' to 'unsigned long' changes value from 18446744073709551615 to 4294967295 [-Wconstant-conversion]
     243 |              node; node = interval_tree_iter_next(node, 0, ULLONG_MAX))
         |                           ~~~~~~~~~~~~~~~~~~~~~~~          ^~~~~~~~~~
   include/vdso/limits.h:16:21: note: expanded from macro 'ULLONG_MAX'
      16 | #define ULLONG_MAX      (~0ULL)
         |                          ^~~~~
   drivers/iommu/virtio-iommu.c:263:6: warning: format specifies type 'unsigned long long' but the argument has type 'dma_addr_t' (aka 'unsigned int') [-Wformat]
     260 |                    "id=%u type=%s endpoints=%lu mappings=%lu aperture=%#llx-%#llx pgsize_bitmap=%#lx map_flags=%#x\n",
         |                                                                       ~~~~~
         |                                                                       %#x
     261 |                    vdomain->id, viommu_domain_type_name(vdomain->domain.type),
     262 |                    vdomain->nr_endpoints, mappings,
     263 |                    vdomain->domain.geometry.aperture_start,
         |                    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/iommu/virtio-iommu.c:264:6: warning: format specifies type 'unsigned long long' but the argument has type 'dma_addr_t' (aka 'unsigned int') [-Wformat]
     260 |                    "id=%u type=%s endpoints=%lu mappings=%lu aperture=%#llx-%#llx pgsize_bitmap=%#lx map_flags=%#x\n",
         |                                                                             ~~~~~
         |                                                                             %#x
     261 |                    vdomain->id, viommu_domain_type_name(vdomain->domain.type),
     262 |                    vdomain->nr_endpoints, mappings,
     263 |                    vdomain->domain.geometry.aperture_start,
     264 |                    vdomain->domain.geometry.aperture_end,
         |                    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/iommu/virtio-iommu.c:296:62: warning: implicit conversion from 'unsigned long long' to 'unsigned long' changes value from 18446744073709551615 to 4294967295 [-Wconstant-conversion]
     296 |         for (node = interval_tree_iter_first(&vdomain->mappings, 0, ULLONG_MAX);
         |                     ~~~~~~~~~~~~~~~~~~~~~~~~                        ^~~~~~~~~~
   include/vdso/limits.h:16:21: note: expanded from macro 'ULLONG_MAX'
      16 | #define ULLONG_MAX      (~0ULL)
         |                          ^~~~~
   drivers/iommu/virtio-iommu.c:297:53: warning: implicit conversion from 'unsigned long long' to 'unsigned long' changes value from 18446744073709551615 to 4294967295 [-Wconstant-conversion]
     297 |              node; node = interval_tree_iter_next(node, 0, ULLONG_MAX)) {
         |                           ~~~~~~~~~~~~~~~~~~~~~~~          ^~~~~~~~~~
   include/vdso/limits.h:16:21: note: expanded from macro 'ULLONG_MAX'
      16 | #define ULLONG_MAX      (~0ULL)
         |                          ^~~~~
   8 warnings generated.


vim +165 drivers/iommu/virtio-iommu.c

   158	
   159	static int viommu_debugfs_status_show(struct seq_file *s, void *unused)
   160	{
   161		struct viommu_dev *viommu = s->private;
   162	
   163		seq_printf(s, "device: %s\n", virtio_bus_name(viommu->vdev));
   164		seq_printf(s, "input_range: %#llx-%#llx\n",
 > 165			   viommu->geometry.aperture_start,
   166			   viommu->geometry.aperture_end);
   167		seq_printf(s, "page_size_mask: %#llx\n", viommu->pgsize_bitmap);
   168		seq_printf(s, "domain_range: %u-%u\n", viommu->first_domain,
   169			   viommu->last_domain);
   170		seq_printf(s, "identity_domain_id: %u\n",
   171			   viommu->identity_domain_id);
   172		seq_printf(s, "probe_size: %u\n", viommu->probe_size);
   173		seq_printf(s, "map_flags: %#x\n", viommu->map_flags);
   174		seq_puts(s, "features:\n");
   175		viommu_debugfs_feature(s, viommu, VIRTIO_IOMMU_F_MAP_UNMAP,
   176				       "map_unmap");
   177		viommu_debugfs_feature(s, viommu, VIRTIO_IOMMU_F_INPUT_RANGE,
   178				       "input_range");
   179		viommu_debugfs_feature(s, viommu, VIRTIO_IOMMU_F_DOMAIN_RANGE,
   180				       "domain_range");
   181		viommu_debugfs_feature(s, viommu, VIRTIO_IOMMU_F_PROBE, "probe");
   182		viommu_debugfs_feature(s, viommu, VIRTIO_IOMMU_F_MMIO, "mmio");
   183		viommu_debugfs_feature(s, viommu, VIRTIO_IOMMU_F_BYPASS_CONFIG,
   184				       "bypass_config");
   185	
   186		return 0;
   187	}
   188	DEFINE_SHOW_ATTRIBUTE(viommu_debugfs_status);
   189	
   190	static void viommu_debugfs_print_endpoint(struct seq_file *s,
   191						  struct viommu_endpoint *vdev)
   192	{
   193		int i;
   194		u32 domain_id = 0;
   195		const char *domain_type = "none";
   196		struct iommu_group *group;
   197		struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(vdev->dev);
   198	
   199		if (vdev->vdomain) {
   200			domain_type = viommu_domain_type_name(vdev->vdomain->domain.type);
   201			if (vdev->vdomain == &viommu_identity_domain)
   202				domain_id = vdev->viommu->identity_domain_id;
   203			else
   204				domain_id = vdev->vdomain->id;
   205		}
   206	
   207		group = iommu_group_get(vdev->dev);
   208		seq_printf(s, "endpoint=%s group_id=%d domain_type=%s",
   209			   dev_name(vdev->dev), group ? iommu_group_id(group) : -1,
   210			   domain_type);
   211		if (vdev->vdomain)
   212			seq_printf(s, " domain_id=%u", domain_id);
   213		if (fwspec) {
   214			seq_puts(s, " ids=");
   215			for (i = 0; i < fwspec->num_ids; i++)
   216				seq_printf(s, "%s%u", i ? "," : "", fwspec->ids[i]);
   217		}
   218		seq_putc(s, '\n');
   219	
   220		iommu_group_put(group);
   221	}
   222	
   223	static int viommu_debugfs_endpoints_show(struct seq_file *s, void *unused)
   224	{
   225		struct viommu_dev *viommu = s->private;
   226		struct viommu_endpoint *vdev;
   227	
   228		mutex_lock(&viommu->debugfs_lock);
   229		list_for_each_entry(vdev, &viommu->debugfs_endpoints, debugfs_node)
   230			viommu_debugfs_print_endpoint(s, vdev);
   231		mutex_unlock(&viommu->debugfs_lock);
   232	
   233		return 0;
   234	}
   235	DEFINE_SHOW_ATTRIBUTE(viommu_debugfs_endpoints);
   236	
   237	static unsigned long viommu_debugfs_count_mappings(struct viommu_domain *vdomain)
   238	{
   239		unsigned long count = 0;
   240		struct interval_tree_node *node;
   241	
 > 242		for (node = interval_tree_iter_first(&vdomain->mappings, 0, ULLONG_MAX);
   243		     node; node = interval_tree_iter_next(node, 0, ULLONG_MAX))
   244			count++;
   245	
   246		return count;
   247	}
   248	

--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] iommu/virtio: Add debugfs state dump
  2026-07-31  1:48 [PATCH] iommu/virtio: Add debugfs state dump LiMing Wu
  2026-08-17  3:41 ` kernel test robot
@ 2026-08-17  4:42 ` kernel test robot
  1 sibling, 0 replies; 3+ messages in thread
From: kernel test robot @ 2026-08-17  4:42 UTC (permalink / raw)
  To: LiMing Wu, Jean-Philippe Brucker, Joerg Roedel (AMD)
  Cc: oe-kbuild-all, Will Deacon, Robin Murphy, virtualization, iommu,
	angus.chen, Liming Wu

Hi LiMing,

kernel test robot noticed the following build warnings:

[auto build test WARNING on linus/master]
[also build test WARNING on arm-perf/for-next/perf v7.2-rc7 next-20260814]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/LiMing-Wu/iommu-virtio-Add-debugfs-state-dump/20260815-175817
base:   linus/master
patch link:    https://lore.kernel.org/r/20260731014838.31187-1-liming.wu%40jaguarmicro.com
patch subject: [PATCH] iommu/virtio: Add debugfs state dump
config: i386-buildonly-randconfig-002-20260817 (https://download.01.org/0day-ci/archive/20260817/202608171219.4vMy8i3D-lkp@intel.com/config)
compiler: gcc-14 (Debian 14.2.0-19) 14.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260817/202608171219.4vMy8i3D-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202608171219.4vMy8i3D-lkp@intel.com/

All warnings (new ones prefixed by >>):

   drivers/iommu/virtio-iommu.c: In function 'viommu_debugfs_status_show':
>> drivers/iommu/virtio-iommu.c:164:41: warning: format '%llx' expects argument of type 'long long unsigned int', but argument 3 has type 'dma_addr_t' {aka 'unsigned int'} [-Wformat=]
     164 |         seq_printf(s, "input_range: %#llx-%#llx\n",
         |                                     ~~~~^
         |                                         |
         |                                         long long unsigned int
         |                                     %#x
     165 |                    viommu->geometry.aperture_start,
         |                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
         |                                    |
         |                                    dma_addr_t {aka unsigned int}
   drivers/iommu/virtio-iommu.c:164:47: warning: format '%llx' expects argument of type 'long long unsigned int', but argument 4 has type 'dma_addr_t' {aka 'unsigned int'} [-Wformat=]
     164 |         seq_printf(s, "input_range: %#llx-%#llx\n",
         |                                           ~~~~^
         |                                               |
         |                                               long long unsigned int
         |                                           %#x
     165 |                    viommu->geometry.aperture_start,
     166 |                    viommu->geometry.aperture_end);
         |                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
         |                                    |
         |                                    dma_addr_t {aka unsigned int}
   In file included from include/linux/limits.h:7,
                    from include/linux/overflow.h:6,
                    from include/linux/bits.h:32,
                    from include/linux/bitops.h:6,
                    from include/linux/log2.h:12,
                    from arch/x86/include/asm/div64.h:8,
                    from include/linux/math.h:6,
                    from include/linux/delay.h:12,
                    from drivers/iommu/virtio-iommu.c:10:
   drivers/iommu/virtio-iommu.c: In function 'viommu_debugfs_count_mappings':
   include/vdso/limits.h:16:25: warning: conversion from 'long long unsigned int' to 'long unsigned int' changes value from '18446744073709551615' to '4294967295' [-Woverflow]
      16 | #define ULLONG_MAX      (~0ULL)
         |                         ^~~~~~~
   drivers/iommu/virtio-iommu.c:242:69: note: in expansion of macro 'ULLONG_MAX'
     242 |         for (node = interval_tree_iter_first(&vdomain->mappings, 0, ULLONG_MAX);
         |                                                                     ^~~~~~~~~~
   include/vdso/limits.h:16:25: warning: conversion from 'long long unsigned int' to 'long unsigned int' changes value from '18446744073709551615' to '4294967295' [-Woverflow]
      16 | #define ULLONG_MAX      (~0ULL)
         |                         ^~~~~~~
   drivers/iommu/virtio-iommu.c:243:60: note: in expansion of macro 'ULLONG_MAX'
     243 |              node; node = interval_tree_iter_next(node, 0, ULLONG_MAX))
         |                                                            ^~~~~~~~~~
   drivers/iommu/virtio-iommu.c: In function 'viommu_debugfs_print_domain':
   drivers/iommu/virtio-iommu.c:260:75: warning: format '%llx' expects argument of type 'long long unsigned int', but argument 7 has type 'dma_addr_t' {aka 'unsigned int'} [-Wformat=]
     260 |                    "id=%u type=%s endpoints=%lu mappings=%lu aperture=%#llx-%#llx pgsize_bitmap=%#lx map_flags=%#x\n",
         |                                                                       ~~~~^
         |                                                                           |
         |                                                                           long long unsigned int
         |                                                                       %#x
   ......
     263 |                    vdomain->domain.geometry.aperture_start,
         |                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~                 
         |                                            |
         |                                            dma_addr_t {aka unsigned int}
   drivers/iommu/virtio-iommu.c:260:81: warning: format '%llx' expects argument of type 'long long unsigned int', but argument 8 has type 'dma_addr_t' {aka 'unsigned int'} [-Wformat=]
     260 |                    "id=%u type=%s endpoints=%lu mappings=%lu aperture=%#llx-%#llx pgsize_bitmap=%#lx map_flags=%#x\n",
         |                                                                             ~~~~^
         |                                                                                 |
         |                                                                                 long long unsigned int
         |                                                                             %#x
   ......
     264 |                    vdomain->domain.geometry.aperture_end,
         |                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~                         
         |                                            |
         |                                            dma_addr_t {aka unsigned int}
   drivers/iommu/virtio-iommu.c: In function 'viommu_debugfs_print_mapping':
   include/vdso/limits.h:16:25: warning: conversion from 'long long unsigned int' to 'long unsigned int' changes value from '18446744073709551615' to '4294967295' [-Woverflow]
      16 | #define ULLONG_MAX      (~0ULL)
         |                         ^~~~~~~
   drivers/iommu/virtio-iommu.c:296:69: note: in expansion of macro 'ULLONG_MAX'
     296 |         for (node = interval_tree_iter_first(&vdomain->mappings, 0, ULLONG_MAX);
         |                                                                     ^~~~~~~~~~
   include/vdso/limits.h:16:25: warning: conversion from 'long long unsigned int' to 'long unsigned int' changes value from '18446744073709551615' to '4294967295' [-Woverflow]
      16 | #define ULLONG_MAX      (~0ULL)
         |                         ^~~~~~~
   drivers/iommu/virtio-iommu.c:297:60: note: in expansion of macro 'ULLONG_MAX'
     297 |              node; node = interval_tree_iter_next(node, 0, ULLONG_MAX)) {
         |                                                            ^~~~~~~~~~


vim +164 drivers/iommu/virtio-iommu.c

   158	
   159	static int viommu_debugfs_status_show(struct seq_file *s, void *unused)
   160	{
   161		struct viommu_dev *viommu = s->private;
   162	
   163		seq_printf(s, "device: %s\n", virtio_bus_name(viommu->vdev));
 > 164		seq_printf(s, "input_range: %#llx-%#llx\n",
   165			   viommu->geometry.aperture_start,
   166			   viommu->geometry.aperture_end);
   167		seq_printf(s, "page_size_mask: %#llx\n", viommu->pgsize_bitmap);
   168		seq_printf(s, "domain_range: %u-%u\n", viommu->first_domain,
   169			   viommu->last_domain);
   170		seq_printf(s, "identity_domain_id: %u\n",
   171			   viommu->identity_domain_id);
   172		seq_printf(s, "probe_size: %u\n", viommu->probe_size);
   173		seq_printf(s, "map_flags: %#x\n", viommu->map_flags);
   174		seq_puts(s, "features:\n");
   175		viommu_debugfs_feature(s, viommu, VIRTIO_IOMMU_F_MAP_UNMAP,
   176				       "map_unmap");
   177		viommu_debugfs_feature(s, viommu, VIRTIO_IOMMU_F_INPUT_RANGE,
   178				       "input_range");
   179		viommu_debugfs_feature(s, viommu, VIRTIO_IOMMU_F_DOMAIN_RANGE,
   180				       "domain_range");
   181		viommu_debugfs_feature(s, viommu, VIRTIO_IOMMU_F_PROBE, "probe");
   182		viommu_debugfs_feature(s, viommu, VIRTIO_IOMMU_F_MMIO, "mmio");
   183		viommu_debugfs_feature(s, viommu, VIRTIO_IOMMU_F_BYPASS_CONFIG,
   184				       "bypass_config");
   185	
   186		return 0;
   187	}
   188	DEFINE_SHOW_ATTRIBUTE(viommu_debugfs_status);
   189	

--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-08-17  4:43 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-31  1:48 [PATCH] iommu/virtio: Add debugfs state dump LiMing Wu
2026-08-17  3:41 ` kernel test robot
2026-08-17  4:42 ` kernel test robot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox