Skip to content

Commit

Permalink
iommu: Create direct mappings in default domains
Browse files Browse the repository at this point in the history
Use the information exported by the IOMMU drivers to create
direct mapped regions in the default domains.

Signed-off-by: Joerg Roedel <jroedel@suse.de>
  • Loading branch information
Joerg Roedel committed Jun 9, 2015
1 parent a1015c2 commit beed282
Showing 1 changed file with 48 additions and 0 deletions.
48 changes: 48 additions & 0 deletions drivers/iommu/iommu.c
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,52 @@ int iommu_group_set_name(struct iommu_group *group, const char *name)
}
EXPORT_SYMBOL_GPL(iommu_group_set_name);

static int iommu_group_create_direct_mappings(struct iommu_group *group,
struct device *dev)
{
struct iommu_domain *domain = group->default_domain;
struct iommu_dm_region *entry;
struct list_head mappings;
unsigned long pg_size;
int ret = 0;

if (!domain || domain->type != IOMMU_DOMAIN_DMA)
return 0;

BUG_ON(!domain->ops->pgsize_bitmap);

pg_size = 1UL << __ffs(domain->ops->pgsize_bitmap);
INIT_LIST_HEAD(&mappings);

iommu_get_dm_regions(dev, &mappings);

/* We need to consider overlapping regions for different devices */
list_for_each_entry(entry, &mappings, list) {
dma_addr_t start, end, addr;

start = ALIGN(entry->start, pg_size);
end = ALIGN(entry->start + entry->length, pg_size);

for (addr = start; addr < end; addr += pg_size) {
phys_addr_t phys_addr;

phys_addr = iommu_iova_to_phys(domain, addr);
if (phys_addr)
continue;

ret = iommu_map(domain, addr, addr, pg_size, entry->prot);
if (ret)
goto out;
}

}

out:
iommu_put_dm_regions(dev, &mappings);

return ret;
}

/**
* iommu_group_add_device - add a device to an iommu group
* @group: the group into which to add the device (reference should be held)
Expand Down Expand Up @@ -381,6 +427,8 @@ int iommu_group_add_device(struct iommu_group *group, struct device *dev)

dev->iommu_group = group;

iommu_group_create_direct_mappings(group, dev);

mutex_lock(&group->mutex);
list_add_tail(&device->list, &group->devices);
if (group->domain)
Expand Down

0 comments on commit beed282

Please sign in to comment.