Re: [PATCH v3 2/8] iommu/riscv: Fix WSI mode IRQ number handling

Andrew Jones
2026-02-05T15:04:29Z

On Thu, Feb 05, 2026 at 11:52:57AM +0800, Lv Zheng wrote:
> On 2/5/2026 1:20 AM, Andrew Jones wrote:
> > On Wed, Feb 04, 2026 at 05:08:52PM +0800, Lv Zheng wrote:
...
> > > 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)) {
> >
> > The behavior of ICVEC does not depend on 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);
> >
> > It's certainly not correct to set iommu->icvec to anything that can't be
> > written to the IOMMU's WARL ICVEC fields and read back again.
>
> Indeed.
> It looks I can keep icvec returned for WSI and keeps the write-and-read
> check logic only for MSI.
>

You shouldn't need to touch this code at all. I don't see anything to fix
wrt the spec. As I said, if iommu->irqs_count is known to be greater than
one but you're getting zero back from ICVEC even after writing 0xffff to
it first, then ICVEC on your IOMMU is broken. Once you've confirmed that,
then the best you can do is add some workaround for your specific IOMMU
here.

Thanks,
drew