Re: [PATCH v3 3/3] arm-smmu: select suitable MSI IOVA
From: Jason Gunthorpe <jgg@ziepe.ca>
Date: 2025-08-06 23:58:50
Also in:
linux-devicetree, linux-iommu, virtualization
On Wed, Aug 06, 2025 at 02:55:39PM -0700, Shyam Saini wrote:
quoted hunk ↗ jump to hunk
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c@@ -3642,17 +3642,30 @@ static int arm_smmu_of_xlate(struct device *dev, static void arm_smmu_get_resv_regions(struct device *dev, struct list_head *head) { - struct iommu_resv_region *region; int prot = IOMMU_WRITE | IOMMU_NOEXEC | IOMMU_MMIO; - region = iommu_alloc_resv_region(MSI_IOVA_BASE, MSI_IOVA_LENGTH, - prot, IOMMU_RESV_SW_MSI, GFP_KERNEL); - if (!region) - return; - - list_add_tail(®ion->list, head); + static const u64 msi_bases[] = { MSI_IOVA_BASE, MSI_IOVA_BASE2 }; iommu_dma_get_resv_regions(dev, head); + + /* + * Use the first msi_base that does not intersect with a platform + * reserved region. The SW MSI base selection is entirely arbitrary. + */ + for (int i = 0; i != ARRAY_SIZE(msi_bases); i++) { + struct iommu_resv_region *region; + + if (resv_region_intersects(msi_bases[i], MSI_IOVA_LENGTH, head)) + continue; + + region = iommu_alloc_resv_region(msi_bases[i], MSI_IOVA_LENGTH, prot, + IOMMU_RESV_SW_MSI, GFP_KERNEL); + if (!region) + return; + + list_add_tail(®ion->list, head); + return; + } }
I think this whole series looks pretty good, but I would suggest to put this in a helper.. 'iommu_set_sw_msi()' perhaps, must be called after iommu_dma_get_resv_regions() Then maybe the constants can just be placed in the .c file inside the helper function. Jsaon