From: Sean Chang <seanwascoding@gmail.com>
To: tjeznach@rivosinc.com, joro@8bytes.org
Cc: will@kernel.org, iommu@lists.linux.dev,
linux-riscv@lists.infradead.org, linux-kernel@vger.kernel.org,
Sean Chang <seanwascoding@gmail.com>
Subject: [PATCH] iommu/riscv: Add DebugFS support for register dump
Date: Mon, 23 Mar 2026 23:58:06 +0800 [thread overview]
Message-ID: <20260323155806.97130-1-seanwascoding@gmail.com> (raw)
Add a DebugFS interface to allow users to dump the internal state of
the RISC-V IOMMU hardware. This is essential for diagnosing hardware
initialization issues and debugging driver-hardware communication
such as Command or Fault queue stalls.
The implementation exposes a "registers" file under the device's
debugfs directory. It uses the standard debugfs_regset32 structure
to dump core registers:
* Global configuration: capabilities, fctl, ddtp
* Command Queue: cqb, cqh, cqt, cqcsr
* Fault Queue: fqb, fqh, fqt, fqcsr
* Interrupts: ipsr, icvec
Signed-off-by: Sean Chang <seanwascoding@gmail.com>
---
drivers/iommu/riscv/Kconfig | 11 ++++++++
drivers/iommu/riscv/Makefile | 1 +
drivers/iommu/riscv/debugfs.c | 53 +++++++++++++++++++++++++++++++++++
drivers/iommu/riscv/iommu.c | 3 ++
drivers/iommu/riscv/iommu.h | 12 ++++++++
5 files changed, 80 insertions(+)
create mode 100644 drivers/iommu/riscv/debugfs.c
diff --git a/drivers/iommu/riscv/Kconfig b/drivers/iommu/riscv/Kconfig
index b86e5ab94183..c2ba12d97e98 100644
--- a/drivers/iommu/riscv/Kconfig
+++ b/drivers/iommu/riscv/Kconfig
@@ -22,3 +22,14 @@ config RISCV_IOMMU_PCI
def_bool y if RISCV_IOMMU && PCI_MSI
help
Support for the PCIe implementation of RISC-V IOMMU architecture.
+
+config RISCV_IOMMU_DEBUGFS
+ bool "RISC-V IOMMU Debugfs Support"
+ depends on RISCV_IOMMU
+ depends on IOMMU_DEBUGFS
+ help
+ Expose RISC-V IOMMU internals via debugfs. This includes
+ register dumps, queue status, and other hardware-specific
+ information useful for debugging.
+
+ If unsure, say N.
diff --git a/drivers/iommu/riscv/Makefile b/drivers/iommu/riscv/Makefile
index b5929f9f23e6..9658a10d8b24 100644
--- a/drivers/iommu/riscv/Makefile
+++ b/drivers/iommu/riscv/Makefile
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: GPL-2.0-only
obj-y += iommu.o iommu-platform.o
obj-$(CONFIG_RISCV_IOMMU_PCI) += iommu-pci.o
+obj-$(CONFIG_RISCV_IOMMU_DEBUGFS) += debugfs.o
diff --git a/drivers/iommu/riscv/debugfs.c b/drivers/iommu/riscv/debugfs.c
new file mode 100644
index 000000000000..52dc50a7fa20
--- /dev/null
+++ b/drivers/iommu/riscv/debugfs.c
@@ -0,0 +1,53 @@
+// SPDX-License-Identifier: GPL-2.0-only
+#include <linux/debugfs.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+
+#include "iommu.h"
+
+static const struct debugfs_reg32 riscv_iommu_regs[] = {
+ /* --- Global Configuration --- */
+ { .name = "capabilities", .offset = RISCV_IOMMU_REG_CAPABILITIES },
+ { .name = "fctl", .offset = RISCV_IOMMU_REG_FCTL },
+ { .name = "ddtp", .offset = RISCV_IOMMU_REG_DDTP },
+ /* --- Command Queue --- */
+ { .name = "cqb", .offset = RISCV_IOMMU_REG_CQB },
+ { .name = "cqh", .offset = RISCV_IOMMU_REG_CQH },
+ { .name = "cqt", .offset = RISCV_IOMMU_REG_CQT },
+ { .name = "cqcsr", .offset = RISCV_IOMMU_REG_CQCSR },
+ /* --- Fault Queue --- */
+ { .name = "fqb", .offset = RISCV_IOMMU_REG_FQB },
+ { .name = "fqh", .offset = RISCV_IOMMU_REG_FQH },
+ { .name = "fqt", .offset = RISCV_IOMMU_REG_FQT },
+ { .name = "fqcsr", .offset = RISCV_IOMMU_REG_FQCSR },
+ /* --- Interrupts --- */
+ { .name = "ipsr", .offset = RISCV_IOMMU_REG_IPSR },
+ { .name = "icvec", .offset = RISCV_IOMMU_REG_ICVEC },
+};
+
+void riscv_iommu_debugfs_init(struct riscv_iommu_device *iommu)
+{
+ struct debugfs_regset32 *regset;
+
+ if (!iommu_debugfs_dir)
+ return;
+
+ iommu->debugfs_dir = debugfs_create_dir(dev_name(iommu->dev), iommu_debugfs_dir);
+ if (IS_ERR_OR_NULL(iommu->debugfs_dir))
+ return;
+
+ regset = devm_kzalloc(iommu->dev, sizeof(*regset), GFP_KERNEL);
+ if (!regset)
+ return;
+
+ regset->regs = riscv_iommu_regs;
+ regset->nregs = ARRAY_SIZE(riscv_iommu_regs);
+ regset->base = iommu->reg;
+
+ debugfs_create_regset32("registers", 0444, iommu->debugfs_dir, regset);
+}
+
+void riscv_iommu_debugfs_remove(struct riscv_iommu_device *iommu)
+{
+ debugfs_remove_recursive(iommu->debugfs_dir);
+}
diff --git a/drivers/iommu/riscv/iommu.c b/drivers/iommu/riscv/iommu.c
index 368f3cbd2d0a..a4fa0307b32a 100644
--- a/drivers/iommu/riscv/iommu.c
+++ b/drivers/iommu/riscv/iommu.c
@@ -1466,6 +1466,7 @@ void riscv_iommu_remove(struct riscv_iommu_device *iommu)
riscv_iommu_iodir_set_mode(iommu, RISCV_IOMMU_DDTP_IOMMU_MODE_OFF);
riscv_iommu_queue_disable(&iommu->cmdq);
riscv_iommu_queue_disable(&iommu->fltq);
+ riscv_iommu_debugfs_remove(iommu);
}
int riscv_iommu_init(struct riscv_iommu_device *iommu)
@@ -1526,6 +1527,8 @@ int riscv_iommu_init(struct riscv_iommu_device *iommu)
goto err_remove_sysfs;
}
+ riscv_iommu_debugfs_init(iommu);
+
return 0;
err_remove_sysfs:
diff --git a/drivers/iommu/riscv/iommu.h b/drivers/iommu/riscv/iommu.h
index 46df79dd5495..1084e4e77455 100644
--- a/drivers/iommu/riscv/iommu.h
+++ b/drivers/iommu/riscv/iommu.h
@@ -60,6 +60,10 @@ struct riscv_iommu_device {
unsigned int ddt_mode;
dma_addr_t ddt_phys;
u64 *ddt_root;
+
+#ifdef CONFIG_RISCV_IOMMU_DEBUGFS
+ struct dentry *debugfs_dir;
+#endif
};
int riscv_iommu_init(struct riscv_iommu_device *iommu);
@@ -86,4 +90,12 @@ void riscv_iommu_disable(struct riscv_iommu_device *iommu);
readx_poll_timeout(readl_relaxed, (iommu)->reg + (addr), val, cond, \
delay_us, timeout_us)
+#ifdef CONFIG_RISCV_IOMMU_DEBUGFS
+void riscv_iommu_debugfs_init(struct riscv_iommu_device *iommu);
+void riscv_iommu_debugfs_remove(struct riscv_iommu_device *iommu);
+#else
+static inline void riscv_iommu_debugfs_init(struct riscv_iommu_device *iommu) { }
+static inline void riscv_iommu_debugfs_remove(struct riscv_iommu_device *iommu) { }
+#endif
+
#endif
--
2.34.1
WARNING: multiple messages have this Message-ID (diff)
From: Sean Chang <seanwascoding@gmail.com>
To: tjeznach@rivosinc.com, joro@8bytes.org
Cc: will@kernel.org, iommu@lists.linux.dev,
linux-riscv@lists.infradead.org, linux-kernel@vger.kernel.org,
Sean Chang <seanwascoding@gmail.com>
Subject: [PATCH] iommu/riscv: Add DebugFS support for register dump
Date: Mon, 23 Mar 2026 23:58:06 +0800 [thread overview]
Message-ID: <20260323155806.97130-1-seanwascoding@gmail.com> (raw)
Add a DebugFS interface to allow users to dump the internal state of
the RISC-V IOMMU hardware. This is essential for diagnosing hardware
initialization issues and debugging driver-hardware communication
such as Command or Fault queue stalls.
The implementation exposes a "registers" file under the device's
debugfs directory. It uses the standard debugfs_regset32 structure
to dump core registers:
* Global configuration: capabilities, fctl, ddtp
* Command Queue: cqb, cqh, cqt, cqcsr
* Fault Queue: fqb, fqh, fqt, fqcsr
* Interrupts: ipsr, icvec
Signed-off-by: Sean Chang <seanwascoding@gmail.com>
---
drivers/iommu/riscv/Kconfig | 11 ++++++++
drivers/iommu/riscv/Makefile | 1 +
drivers/iommu/riscv/debugfs.c | 53 +++++++++++++++++++++++++++++++++++
drivers/iommu/riscv/iommu.c | 3 ++
drivers/iommu/riscv/iommu.h | 12 ++++++++
5 files changed, 80 insertions(+)
create mode 100644 drivers/iommu/riscv/debugfs.c
diff --git a/drivers/iommu/riscv/Kconfig b/drivers/iommu/riscv/Kconfig
index b86e5ab94183..c2ba12d97e98 100644
--- a/drivers/iommu/riscv/Kconfig
+++ b/drivers/iommu/riscv/Kconfig
@@ -22,3 +22,14 @@ config RISCV_IOMMU_PCI
def_bool y if RISCV_IOMMU && PCI_MSI
help
Support for the PCIe implementation of RISC-V IOMMU architecture.
+
+config RISCV_IOMMU_DEBUGFS
+ bool "RISC-V IOMMU Debugfs Support"
+ depends on RISCV_IOMMU
+ depends on IOMMU_DEBUGFS
+ help
+ Expose RISC-V IOMMU internals via debugfs. This includes
+ register dumps, queue status, and other hardware-specific
+ information useful for debugging.
+
+ If unsure, say N.
diff --git a/drivers/iommu/riscv/Makefile b/drivers/iommu/riscv/Makefile
index b5929f9f23e6..9658a10d8b24 100644
--- a/drivers/iommu/riscv/Makefile
+++ b/drivers/iommu/riscv/Makefile
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: GPL-2.0-only
obj-y += iommu.o iommu-platform.o
obj-$(CONFIG_RISCV_IOMMU_PCI) += iommu-pci.o
+obj-$(CONFIG_RISCV_IOMMU_DEBUGFS) += debugfs.o
diff --git a/drivers/iommu/riscv/debugfs.c b/drivers/iommu/riscv/debugfs.c
new file mode 100644
index 000000000000..52dc50a7fa20
--- /dev/null
+++ b/drivers/iommu/riscv/debugfs.c
@@ -0,0 +1,53 @@
+// SPDX-License-Identifier: GPL-2.0-only
+#include <linux/debugfs.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+
+#include "iommu.h"
+
+static const struct debugfs_reg32 riscv_iommu_regs[] = {
+ /* --- Global Configuration --- */
+ { .name = "capabilities", .offset = RISCV_IOMMU_REG_CAPABILITIES },
+ { .name = "fctl", .offset = RISCV_IOMMU_REG_FCTL },
+ { .name = "ddtp", .offset = RISCV_IOMMU_REG_DDTP },
+ /* --- Command Queue --- */
+ { .name = "cqb", .offset = RISCV_IOMMU_REG_CQB },
+ { .name = "cqh", .offset = RISCV_IOMMU_REG_CQH },
+ { .name = "cqt", .offset = RISCV_IOMMU_REG_CQT },
+ { .name = "cqcsr", .offset = RISCV_IOMMU_REG_CQCSR },
+ /* --- Fault Queue --- */
+ { .name = "fqb", .offset = RISCV_IOMMU_REG_FQB },
+ { .name = "fqh", .offset = RISCV_IOMMU_REG_FQH },
+ { .name = "fqt", .offset = RISCV_IOMMU_REG_FQT },
+ { .name = "fqcsr", .offset = RISCV_IOMMU_REG_FQCSR },
+ /* --- Interrupts --- */
+ { .name = "ipsr", .offset = RISCV_IOMMU_REG_IPSR },
+ { .name = "icvec", .offset = RISCV_IOMMU_REG_ICVEC },
+};
+
+void riscv_iommu_debugfs_init(struct riscv_iommu_device *iommu)
+{
+ struct debugfs_regset32 *regset;
+
+ if (!iommu_debugfs_dir)
+ return;
+
+ iommu->debugfs_dir = debugfs_create_dir(dev_name(iommu->dev), iommu_debugfs_dir);
+ if (IS_ERR_OR_NULL(iommu->debugfs_dir))
+ return;
+
+ regset = devm_kzalloc(iommu->dev, sizeof(*regset), GFP_KERNEL);
+ if (!regset)
+ return;
+
+ regset->regs = riscv_iommu_regs;
+ regset->nregs = ARRAY_SIZE(riscv_iommu_regs);
+ regset->base = iommu->reg;
+
+ debugfs_create_regset32("registers", 0444, iommu->debugfs_dir, regset);
+}
+
+void riscv_iommu_debugfs_remove(struct riscv_iommu_device *iommu)
+{
+ debugfs_remove_recursive(iommu->debugfs_dir);
+}
diff --git a/drivers/iommu/riscv/iommu.c b/drivers/iommu/riscv/iommu.c
index 368f3cbd2d0a..a4fa0307b32a 100644
--- a/drivers/iommu/riscv/iommu.c
+++ b/drivers/iommu/riscv/iommu.c
@@ -1466,6 +1466,7 @@ void riscv_iommu_remove(struct riscv_iommu_device *iommu)
riscv_iommu_iodir_set_mode(iommu, RISCV_IOMMU_DDTP_IOMMU_MODE_OFF);
riscv_iommu_queue_disable(&iommu->cmdq);
riscv_iommu_queue_disable(&iommu->fltq);
+ riscv_iommu_debugfs_remove(iommu);
}
int riscv_iommu_init(struct riscv_iommu_device *iommu)
@@ -1526,6 +1527,8 @@ int riscv_iommu_init(struct riscv_iommu_device *iommu)
goto err_remove_sysfs;
}
+ riscv_iommu_debugfs_init(iommu);
+
return 0;
err_remove_sysfs:
diff --git a/drivers/iommu/riscv/iommu.h b/drivers/iommu/riscv/iommu.h
index 46df79dd5495..1084e4e77455 100644
--- a/drivers/iommu/riscv/iommu.h
+++ b/drivers/iommu/riscv/iommu.h
@@ -60,6 +60,10 @@ struct riscv_iommu_device {
unsigned int ddt_mode;
dma_addr_t ddt_phys;
u64 *ddt_root;
+
+#ifdef CONFIG_RISCV_IOMMU_DEBUGFS
+ struct dentry *debugfs_dir;
+#endif
};
int riscv_iommu_init(struct riscv_iommu_device *iommu);
@@ -86,4 +90,12 @@ void riscv_iommu_disable(struct riscv_iommu_device *iommu);
readx_poll_timeout(readl_relaxed, (iommu)->reg + (addr), val, cond, \
delay_us, timeout_us)
+#ifdef CONFIG_RISCV_IOMMU_DEBUGFS
+void riscv_iommu_debugfs_init(struct riscv_iommu_device *iommu);
+void riscv_iommu_debugfs_remove(struct riscv_iommu_device *iommu);
+#else
+static inline void riscv_iommu_debugfs_init(struct riscv_iommu_device *iommu) { }
+static inline void riscv_iommu_debugfs_remove(struct riscv_iommu_device *iommu) { }
+#endif
+
#endif
--
2.34.1
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
next reply other threads:[~2026-03-23 15:58 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-23 15:58 Sean Chang [this message]
2026-03-23 15:58 ` [PATCH] iommu/riscv: Add DebugFS support for register dump Sean Chang
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260323155806.97130-1-seanwascoding@gmail.com \
--to=seanwascoding@gmail.com \
--cc=iommu@lists.linux.dev \
--cc=joro@8bytes.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-riscv@lists.infradead.org \
--cc=tjeznach@rivosinc.com \
--cc=will@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.