[PATCH v3 3/3] arm-smmu: select suitable MSI IOVA
Jason Gunthorpe
jgg at ziepe.ca
Wed Aug 6 16:58:48 PDT 2025
On Wed, Aug 06, 2025 at 02:55:39PM -0700, Shyam Saini wrote:
> --- 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
More information about the linux-arm-kernel
mailing list