forked from luck/tmp_suning_uos_patched
iommu: Create direct mappings in default domains
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>
This commit is contained in:
parent
a1015c2b99
commit
beed2821b4
|
@ -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)
|
||||
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue
Block a user