mirror of
https://github.com/torvalds/linux.git
synced 2024-11-26 22:21:42 +00:00
iommu/dma: Make PCI window reservation generic
Now that we're applying the IOMMU API reserved regions to our IOVA domains, we shouldn't need to privately special-case PCI windows, or indeed anything else which isn't specific to our iommu-dma layer. However, since those aren't IOMMU-specific either, rather than start duplicating code into IOMMU drivers let's transform the existing function into an iommu_get_resv_regions() helper that they can share. Signed-off-by: Robin Murphy <robin.murphy@arm.com> Signed-off-by: Joerg Roedel <jroedel@suse.de>
This commit is contained in:
parent
7c1b058c8b
commit
273df96353
@ -1893,6 +1893,8 @@ static void arm_smmu_get_resv_regions(struct device *dev,
|
||||
return;
|
||||
|
||||
list_add_tail(®ion->list, head);
|
||||
|
||||
iommu_dma_get_resv_regions(dev, head);
|
||||
}
|
||||
|
||||
static void arm_smmu_put_resv_regions(struct device *dev,
|
||||
|
@ -1613,6 +1613,8 @@ static void arm_smmu_get_resv_regions(struct device *dev,
|
||||
return;
|
||||
|
||||
list_add_tail(®ion->list, head);
|
||||
|
||||
iommu_dma_get_resv_regions(dev, head);
|
||||
}
|
||||
|
||||
static void arm_smmu_put_resv_regions(struct device *dev,
|
||||
|
@ -167,22 +167,43 @@ void iommu_put_dma_cookie(struct iommu_domain *domain)
|
||||
}
|
||||
EXPORT_SYMBOL(iommu_put_dma_cookie);
|
||||
|
||||
static void iova_reserve_pci_windows(struct pci_dev *dev,
|
||||
struct iova_domain *iovad)
|
||||
/**
|
||||
* iommu_dma_get_resv_regions - Reserved region driver helper
|
||||
* @dev: Device from iommu_get_resv_regions()
|
||||
* @list: Reserved region list from iommu_get_resv_regions()
|
||||
*
|
||||
* IOMMU drivers can use this to implement their .get_resv_regions callback
|
||||
* for general non-IOMMU-specific reservations. Currently, this covers host
|
||||
* bridge windows for PCI devices.
|
||||
*/
|
||||
void iommu_dma_get_resv_regions(struct device *dev, struct list_head *list)
|
||||
{
|
||||
struct pci_host_bridge *bridge = pci_find_host_bridge(dev->bus);
|
||||
struct pci_host_bridge *bridge;
|
||||
struct resource_entry *window;
|
||||
unsigned long lo, hi;
|
||||
|
||||
if (!dev_is_pci(dev))
|
||||
return;
|
||||
|
||||
bridge = pci_find_host_bridge(to_pci_dev(dev)->bus);
|
||||
resource_list_for_each_entry(window, &bridge->windows) {
|
||||
struct iommu_resv_region *region;
|
||||
phys_addr_t start;
|
||||
size_t length;
|
||||
|
||||
if (resource_type(window->res) != IORESOURCE_MEM)
|
||||
continue;
|
||||
|
||||
lo = iova_pfn(iovad, window->res->start - window->offset);
|
||||
hi = iova_pfn(iovad, window->res->end - window->offset);
|
||||
reserve_iova(iovad, lo, hi);
|
||||
start = window->res->start - window->offset;
|
||||
length = window->res->end - window->res->start + 1;
|
||||
region = iommu_alloc_resv_region(start, length, 0,
|
||||
IOMMU_RESV_RESERVED);
|
||||
if (!region)
|
||||
return;
|
||||
|
||||
list_add_tail(®ion->list, list);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(iommu_dma_get_resv_regions);
|
||||
|
||||
static int cookie_init_hw_msi_region(struct iommu_dma_cookie *cookie,
|
||||
phys_addr_t start, phys_addr_t end)
|
||||
@ -218,9 +239,6 @@ static int iova_reserve_iommu_regions(struct device *dev,
|
||||
LIST_HEAD(resv_regions);
|
||||
int ret = 0;
|
||||
|
||||
if (dev_is_pci(dev))
|
||||
iova_reserve_pci_windows(to_pci_dev(dev), iovad);
|
||||
|
||||
iommu_get_resv_regions(dev, &resv_regions);
|
||||
list_for_each_entry(region, &resv_regions, list) {
|
||||
unsigned long lo, hi;
|
||||
|
@ -71,6 +71,7 @@ int iommu_dma_mapping_error(struct device *dev, dma_addr_t dma_addr);
|
||||
|
||||
/* The DMA API isn't _quite_ the whole story, though... */
|
||||
void iommu_dma_map_msi_msg(int irq, struct msi_msg *msg);
|
||||
void iommu_dma_get_resv_regions(struct device *dev, struct list_head *list);
|
||||
|
||||
#else
|
||||
|
||||
@ -100,6 +101,10 @@ static inline void iommu_dma_map_msi_msg(int irq, struct msi_msg *msg)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void iommu_dma_get_resv_regions(struct device *dev, struct list_head *list)
|
||||
{
|
||||
}
|
||||
|
||||
#endif /* CONFIG_IOMMU_DMA */
|
||||
#endif /* __KERNEL__ */
|
||||
#endif /* __DMA_IOMMU_H */
|
||||
|
Loading…
Reference in New Issue
Block a user