|
@@ -167,22 +167,43 @@ void iommu_put_dma_cookie(struct iommu_domain *domain)
|
|
}
|
|
}
|
|
EXPORT_SYMBOL(iommu_put_dma_cookie);
|
|
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;
|
|
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) {
|
|
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)
|
|
if (resource_type(window->res) != IORESOURCE_MEM)
|
|
continue;
|
|
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,
|
|
static int cookie_init_hw_msi_region(struct iommu_dma_cookie *cookie,
|
|
phys_addr_t start, phys_addr_t end)
|
|
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);
|
|
LIST_HEAD(resv_regions);
|
|
int ret = 0;
|
|
int ret = 0;
|
|
|
|
|
|
- if (dev_is_pci(dev))
|
|
|
|
- iova_reserve_pci_windows(to_pci_dev(dev), iovad);
|
|
|
|
-
|
|
|
|
iommu_get_resv_regions(dev, &resv_regions);
|
|
iommu_get_resv_regions(dev, &resv_regions);
|
|
list_for_each_entry(region, &resv_regions, list) {
|
|
list_for_each_entry(region, &resv_regions, list) {
|
|
unsigned long lo, hi;
|
|
unsigned long lo, hi;
|