Merge branches 'x86/amd', 'x86/vt-d', 'arm/exynos', 'arm/mediatek', 'arm/msm', 'arm...
[linux-2.6-block.git] / drivers / iommu / iommu.c
index b9df1411c8942c18b266b11e1cf572ecf9bcad15..b06d93594436984fa954982a0cb763206df268c0 100644 (file)
@@ -34,8 +34,7 @@
 #include <trace/events/iommu.h>
 
 static struct kset *iommu_group_kset;
-static struct ida iommu_group_ida;
-static struct mutex iommu_group_mutex;
+static DEFINE_IDA(iommu_group_ida);
 
 struct iommu_callback_data {
        const struct iommu_ops *ops;
@@ -144,9 +143,7 @@ static void iommu_group_release(struct kobject *kobj)
        if (group->iommu_data_release)
                group->iommu_data_release(group->iommu_data);
 
-       mutex_lock(&iommu_group_mutex);
-       ida_remove(&iommu_group_ida, group->id);
-       mutex_unlock(&iommu_group_mutex);
+       ida_simple_remove(&iommu_group_ida, group->id);
 
        if (group->default_domain)
                iommu_domain_free(group->default_domain);
@@ -186,26 +183,17 @@ struct iommu_group *iommu_group_alloc(void)
        INIT_LIST_HEAD(&group->devices);
        BLOCKING_INIT_NOTIFIER_HEAD(&group->notifier);
 
-       mutex_lock(&iommu_group_mutex);
-
-again:
-       if (unlikely(0 == ida_pre_get(&iommu_group_ida, GFP_KERNEL))) {
+       ret = ida_simple_get(&iommu_group_ida, 0, 0, GFP_KERNEL);
+       if (ret < 0) {
                kfree(group);
-               mutex_unlock(&iommu_group_mutex);
-               return ERR_PTR(-ENOMEM);
+               return ERR_PTR(ret);
        }
-
-       if (-EAGAIN == ida_get_new(&iommu_group_ida, &group->id))
-               goto again;
-
-       mutex_unlock(&iommu_group_mutex);
+       group->id = ret;
 
        ret = kobject_init_and_add(&group->kobj, &iommu_group_ktype,
                                   NULL, "%d", group->id);
        if (ret) {
-               mutex_lock(&iommu_group_mutex);
-               ida_remove(&iommu_group_ida, group->id);
-               mutex_unlock(&iommu_group_mutex);
+               ida_simple_remove(&iommu_group_ida, group->id);
                kfree(group);
                return ERR_PTR(ret);
        }
@@ -337,9 +325,9 @@ static int iommu_group_create_direct_mappings(struct iommu_group *group,
        if (!domain || domain->type != IOMMU_DOMAIN_DMA)
                return 0;
 
-       BUG_ON(!domain->ops->pgsize_bitmap);
+       BUG_ON(!domain->pgsize_bitmap);
 
-       pg_size = 1UL << __ffs(domain->ops->pgsize_bitmap);
+       pg_size = 1UL << __ffs(domain->pgsize_bitmap);
        INIT_LIST_HEAD(&mappings);
 
        iommu_get_dm_regions(dev, &mappings);
@@ -348,6 +336,9 @@ static int iommu_group_create_direct_mappings(struct iommu_group *group,
        list_for_each_entry(entry, &mappings, list) {
                dma_addr_t start, end, addr;
 
+               if (domain->ops->apply_dm_region)
+                       domain->ops->apply_dm_region(dev, domain, entry);
+
                start = ALIGN(entry->start, pg_size);
                end   = ALIGN(entry->start + entry->length, pg_size);
 
@@ -660,8 +651,8 @@ static struct iommu_group *get_pci_function_alias_group(struct pci_dev *pdev,
 }
 
 /*
- * Look for aliases to or from the given device for exisiting groups.  The
- * dma_alias_devfn only supports aliases on the same bus, therefore the search
+ * Look for aliases to or from the given device for existing groups. DMA
+ * aliases are only supported on the same bus, therefore the search
  * space is quite small (especially since we're really only looking at pcie
  * device, and therefore only expect multiple slots on the root complex or
  * downstream switch ports).  It's conceivable though that a pair of
@@ -686,11 +677,7 @@ static struct iommu_group *get_pci_alias_group(struct pci_dev *pdev,
                        continue;
 
                /* We alias them or they alias us */
-               if (((pdev->dev_flags & PCI_DEV_FLAGS_DMA_ALIAS_DEVFN) &&
-                    pdev->dma_alias_devfn == tmp->devfn) ||
-                   ((tmp->dev_flags & PCI_DEV_FLAGS_DMA_ALIAS_DEVFN) &&
-                    tmp->dma_alias_devfn == pdev->devfn)) {
-
+               if (pci_devs_are_dma_aliases(pdev, tmp)) {
                        group = get_pci_alias_group(tmp, devfns);
                        if (group) {
                                pci_dev_put(tmp);
@@ -1073,6 +1060,8 @@ static struct iommu_domain *__iommu_domain_alloc(struct bus_type *bus,
 
        domain->ops  = bus->iommu_ops;
        domain->type = type;
+       /* Assume all sizes by default; the driver may override this later */
+       domain->pgsize_bitmap  = bus->iommu_ops->pgsize_bitmap;
 
        return domain;
 }
@@ -1297,7 +1286,7 @@ static size_t iommu_pgsize(struct iommu_domain *domain,
        pgsize = (1UL << (pgsize_idx + 1)) - 1;
 
        /* throw away page sizes not supported by the hardware */
-       pgsize &= domain->ops->pgsize_bitmap;
+       pgsize &= domain->pgsize_bitmap;
 
        /* make sure we're still sane */
        BUG_ON(!pgsize);
@@ -1319,14 +1308,14 @@ int iommu_map(struct iommu_domain *domain, unsigned long iova,
        int ret = 0;
 
        if (unlikely(domain->ops->map == NULL ||
-                    domain->ops->pgsize_bitmap == 0UL))
+                    domain->pgsize_bitmap == 0UL))
                return -ENODEV;
 
        if (unlikely(!(domain->type & __IOMMU_DOMAIN_PAGING)))
                return -EINVAL;
 
        /* find out the minimum page size supported */
-       min_pagesz = 1 << __ffs(domain->ops->pgsize_bitmap);
+       min_pagesz = 1 << __ffs(domain->pgsize_bitmap);
 
        /*
         * both the virtual address and the physical one, as well as
@@ -1373,14 +1362,14 @@ size_t iommu_unmap(struct iommu_domain *domain, unsigned long iova, size_t size)
        unsigned long orig_iova = iova;
 
        if (unlikely(domain->ops->unmap == NULL ||
-                    domain->ops->pgsize_bitmap == 0UL))
+                    domain->pgsize_bitmap == 0UL))
                return -ENODEV;
 
        if (unlikely(!(domain->type & __IOMMU_DOMAIN_PAGING)))
                return -EINVAL;
 
        /* find out the minimum page size supported */
-       min_pagesz = 1 << __ffs(domain->ops->pgsize_bitmap);
+       min_pagesz = 1 << __ffs(domain->pgsize_bitmap);
 
        /*
         * The virtual address, as well as the size of the mapping, must be
@@ -1426,10 +1415,10 @@ size_t default_iommu_map_sg(struct iommu_domain *domain, unsigned long iova,
        unsigned int i, min_pagesz;
        int ret;
 
-       if (unlikely(domain->ops->pgsize_bitmap == 0UL))
+       if (unlikely(domain->pgsize_bitmap == 0UL))
                return 0;
 
-       min_pagesz = 1 << __ffs(domain->ops->pgsize_bitmap);
+       min_pagesz = 1 << __ffs(domain->pgsize_bitmap);
 
        for_each_sg(sg, s, nents, i) {
                phys_addr_t phys = page_to_phys(sg_page(s)) + s->offset;
@@ -1485,9 +1474,6 @@ static int __init iommu_init(void)
 {
        iommu_group_kset = kset_create_and_add("iommu_groups",
                                               NULL, kernel_kobj);
-       ida_init(&iommu_group_ida);
-       mutex_init(&iommu_group_mutex);
-
        BUG_ON(!iommu_group_kset);
 
        return 0;
@@ -1510,7 +1496,7 @@ int iommu_domain_get_attr(struct iommu_domain *domain,
                break;
        case DOMAIN_ATTR_PAGING:
                paging  = data;
-               *paging = (domain->ops->pgsize_bitmap != 0UL);
+               *paging = (domain->pgsize_bitmap != 0UL);
                break;
        case DOMAIN_ATTR_WINDOWS:
                count = data;