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

Lv Zheng
2026-02-06T01:37:40Z

On 2/5/2026 11:04 PM, Andrew Jones wrote:
> 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
>

This patch is an approach trying to give PMIV a standalone wired IRQ#
which is required by pre-silicon spacemit T100 RTLs when it is
configured to report both MSI/WSI caps. However there is no such real
product on the market, I just drop it it in the next version.

Thanks,
Lv