[PATCH v3 2/8] iommu/riscv: Fix WSI mode IRQ number handling
Lv Zheng
lv.zheng at linux.spacemit.com
Wed Feb 4 01:08:52 PST 2026
From: Jingyu Li <joey.li at spacemit.com>
In WSI mode, ICVEC doesn't exist, thus reading it returns 0, which
causes IOMMU driver to fail to find IRQ numbers from device tree
IRQ arrary. The issue is fixed by applying icvec indexes of WSI IRQs.
Signed-off-by: Jingyu Li <joey.li at spacemit.com>
Signed-off-by: Lv Zheng <lv.zheng at linux.spacemit.com>
---
drivers/iommu/riscv/iommu.c | 25 ++++++++++++++++++++-----
1 file changed, 20 insertions(+), 5 deletions(-)
diff --git a/drivers/iommu/riscv/iommu.c b/drivers/iommu/riscv/iommu.c
index d9429097a2b5..26630979473b 100644
--- a/drivers/iommu/riscv/iommu.c
+++ b/drivers/iommu/riscv/iommu.c
@@ -1593,11 +1593,26 @@ static int riscv_iommu_init_check(struct riscv_iommu_device *iommu)
FIELD_PREP(RISCV_IOMMU_ICVEC_PMIV, 3 % iommu->irqs_count);
riscv_iommu_writeq(iommu, RISCV_IOMMU_REG_ICVEC, iommu->icvec);
iommu->icvec = riscv_iommu_readq(iommu, RISCV_IOMMU_REG_ICVEC);
- if (max(max(FIELD_GET(RISCV_IOMMU_ICVEC_CIV, iommu->icvec),
- FIELD_GET(RISCV_IOMMU_ICVEC_FIV, iommu->icvec)),
- max(FIELD_GET(RISCV_IOMMU_ICVEC_PIV, iommu->icvec),
- FIELD_GET(RISCV_IOMMU_ICVEC_PMIV, iommu->icvec))) >= iommu->irqs_count)
- return -EINVAL;
+ /*
+ * In WSI mode, ICVEC may read as zero. Only validate if using MSI.
+ * Check if FCTL.WSI is set to determine interrupt mode.
+ */
+ if (!(iommu->fctl & RISCV_IOMMU_FCTL_WSI)) {
+ if (max(max(FIELD_GET(RISCV_IOMMU_ICVEC_CIV, iommu->icvec),
+ FIELD_GET(RISCV_IOMMU_ICVEC_FIV, iommu->icvec)),
+ max(FIELD_GET(RISCV_IOMMU_ICVEC_PIV, iommu->icvec),
+ FIELD_GET(RISCV_IOMMU_ICVEC_PMIV, iommu->icvec))) >= iommu->irqs_count)
+ return -EINVAL;
+ } else {
+ /*
+ * WSI mode: ICVEC is not used. Set to identity mapping for
+ * riscv_iommu_queue_vec() to work correctly.
+ */
+ iommu->icvec = FIELD_PREP(RISCV_IOMMU_ICVEC_CIV, 0) |
+ FIELD_PREP(RISCV_IOMMU_ICVEC_FIV, 1) |
+ FIELD_PREP(RISCV_IOMMU_ICVEC_PIV, 2) |
+ FIELD_PREP(RISCV_IOMMU_ICVEC_PMIV, 3);
+ }
return 0;
}
--
2.43.0
More information about the linux-riscv
mailing list