forked from mirrors/linux
		
	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
					
				
					 4 changed files with 37 additions and 10 deletions
				
			
		|  | @ -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 a new issue
	
	 Robin Murphy
						Robin Murphy