FROMLIST: iommu/dma: Allow drivers to reserve an iova range

Some devices have a memory map which contains gaps or holes.
In order for the device to have as much IOVA space as possible,
allow its driver to inform the DMA-IOMMU layer that it should
not allocate addresses from these holes.

Bug: 149544395
Link: https://lore.kernel.org/lkml/20200220185728.GA32137@pratikp-lnx/
Change-Id: I15bd1d313d889c2572d0eb2adecf6bebde3267f7
Signed-off-by: Isaac J. Manjarres <isaacm@codeaurora.org>
This commit is contained in:
Liam Mark 2020-02-26 13:52:06 -08:00 • committed by Todd Kjos
commit 741f92f5cb
2 changed files with 37 additions and 0 deletions

View file

@ -352,6 +352,34 @@ static int iommu_dma_init_domain(struct iommu_domain *domain, dma_addr_t base,
return iova_reserve_iommu_regions(dev, domain);
}
/*
* Should be called prior to using dma-apis
*/
int iommu_dma_reserve_iova(struct device *dev, dma_addr_t base,
u64 size)
{
struct iommu_domain *domain;
struct iommu_dma_cookie *cookie;
struct iova_domain *iovad;
unsigned long pfn_lo, pfn_hi;
domain = iommu_get_domain_for_dev(dev);
if (!domain || !domain->iova_cookie)
return -EINVAL;
cookie = domain->iova_cookie;
iovad = &cookie->iovad;
/* iova will be freed automatically by put_iova_domain() */
pfn_lo = iova_pfn(iovad, base);
pfn_hi = iova_pfn(iovad, base + size - 1);
if (!reserve_iova(iovad, pfn_lo, pfn_hi))
return -EINVAL;
return 0;
}
EXPORT_SYMBOL(iommu_dma_reserve_iova);
/**
* dma_info_to_prot - Translate DMA API directions and attributes to IOMMU API
* page flags.

View file

@ -37,6 +37,9 @@ void iommu_dma_compose_msi_msg(struct msi_desc *desc,
void iommu_dma_get_resv_regions(struct device *dev, struct list_head *list);
int iommu_dma_reserve_iova(struct device *dev, dma_addr_t base,
u64 size);
#else /* CONFIG_IOMMU_DMA */
struct iommu_domain;
@ -78,5 +81,11 @@ static inline void iommu_dma_get_resv_regions(struct device *dev, struct list_he
{
}
static inline int iommu_dma_reserve_iova(struct device *dev, dma_addr_t base,
u64 size)
{
return -ENODEV;
}
#endif /* CONFIG_IOMMU_DMA */
#endif /* __DMA_IOMMU_H */