Not all domain owners call iommu_get_dma/msi_cookie(), e.g. iommufd has its sw_msi implementation without using the domain->iova_cookie but the domain->iommufd_hwpt. To isolate the unused iova_cookie from the iommufd, iommu_domain_free() will no longer call iommu_put_dma_cookie(). Add iommu_put_msi_cookie() to pair with iommu_put_dma_cookie() for VFIO that is the only caller to explicitly put the MSI cookie. Move iommufd_get/put_msi_cookie() inside "ifdef CONFIG_IRQ_MSI_IOMMU". Note that the iommufd_get_msi_cookie now returns a 0 for NOP in case of: *) !CONFIG_IOMMU_DMA - the caller in VFIO would have returned prior to reaching to this function. *) !CONFIG_IRQ_MSI_IOMMU - in a system without an irqchip driver, vfio or iommufd shouldn't fail if an IOMMU driver still reports SW_MSI reserved regions. Suggested-by: Jason Gunthorpe <jgg@xxxxxxxxxx> Signed-off-by: Nicolin Chen <nicolinc@xxxxxxxxxx> --- include/linux/iommu.h | 10 +++++++--- drivers/iommu/dma-iommu.c | 12 ++++++++++++ 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/include/linux/iommu.h b/include/linux/iommu.h index e93d2e918599..6f66980e0c86 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -1534,12 +1534,16 @@ void iommu_debugfs_setup(void); static inline void iommu_debugfs_setup(void) {} #endif -#ifdef CONFIG_IOMMU_DMA +#if defined(CONFIG_IOMMU_DMA) && IS_ENABLED(CONFIG_IRQ_MSI_IOMMU) int iommu_get_msi_cookie(struct iommu_domain *domain, dma_addr_t base); -#else /* CONFIG_IOMMU_DMA */ +void iommu_put_msi_cookie(struct iommu_domain *domain); +#else /* CONFIG_IOMMU_DMA && CONFIG_IRQ_MSI_IOMMU */ static inline int iommu_get_msi_cookie(struct iommu_domain *domain, dma_addr_t base) { - return -ENODEV; + return 0; +} +static inline void iommu_put_msi_cookie(struct iommu_domain *domain) +{ } #endif /* CONFIG_IOMMU_DMA */ diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c index 94263ed2c564..228524c81b72 100644 --- a/drivers/iommu/dma-iommu.c +++ b/drivers/iommu/dma-iommu.c @@ -418,6 +418,7 @@ int iommu_get_dma_cookie(struct iommu_domain *domain) * number of PAGE_SIZE mappings necessary to cover every MSI doorbell address * used by the devices attached to @domain. */ +#if IS_ENABLED(CONFIG_IRQ_MSI_IOMMU) int iommu_get_msi_cookie(struct iommu_domain *domain, dma_addr_t base) { struct iommu_dma_cookie *cookie; @@ -439,6 +440,17 @@ int iommu_get_msi_cookie(struct iommu_domain *domain, dma_addr_t base) } EXPORT_SYMBOL(iommu_get_msi_cookie); +/** + * iommu_put_msi_cookie - Release a domain's MSI remapping resources + * @domain: IOMMU domain previously prepared by iommu_get_msi_cookie() + */ +void iommu_put_msi_cookie(struct iommu_domain *domain) +{ + iommu_put_dma_cookie(domain); +} +EXPORT_SYMBOL_GPL(iommu_put_msi_cookie); +#endif + /** * iommu_put_dma_cookie - Release a domain's DMA mapping resources * @domain: IOMMU domain previously prepared by iommu_get_dma_cookie() or -- 2.43.0