diff options
author | Russell King <rmk+kernel@armlinux.org.uk> | 2020-08-04 01:39:54 +0100 |
---|---|---|
committer | Russell King <rmk+kernel@armlinux.org.uk> | 2020-10-12 22:41:38 +0100 |
commit | 1386a12ee395909173468001cc66c256ca3e3602 (patch) | |
tree | b367346ce4815a400149cef894599a14eec9d760 | |
parent | 1b108cfb917cf204d309087273e06bbe91f7e57f (diff) |
Revert "iommu: Remove functions that support private domain"
This reverts commit 69cf449166987d9a041020be6422ee7bf94a7228.
-rw-r--r-- | drivers/iommu/iommu.c | 65 | ||||
-rw-r--r-- | include/linux/iommu.h | 12 |
2 files changed, 77 insertions, 0 deletions
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index 609bd25bf154..f7a372f7f08c 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -2562,6 +2562,71 @@ struct iommu_resv_region *iommu_alloc_resv_region(phys_addr_t start, } EXPORT_SYMBOL_GPL(iommu_alloc_resv_region); +static int +request_default_domain_for_dev(struct device *dev, unsigned long type) +{ + struct iommu_domain *domain; + struct iommu_group *group; + int ret; + + /* Device must already be in a group before calling this function */ + group = iommu_group_get(dev); + if (!group) + return -EINVAL; + + mutex_lock(&group->mutex); + + ret = 0; + if (group->default_domain && group->default_domain->type == type) + goto out; + + /* Don't change mappings of existing devices */ + ret = -EBUSY; + if (iommu_group_device_count(group) != 1) + goto out; + + ret = -ENOMEM; + domain = __iommu_domain_alloc(dev->bus, type); + if (!domain) + goto out; + + /* Attach the device to the domain */ + ret = __iommu_attach_group(domain, group); + if (ret) { + iommu_domain_free(domain); + goto out; + } + + /* Make the domain the default for this group */ + if (group->default_domain) + iommu_domain_free(group->default_domain); + group->default_domain = domain; + + iommu_create_device_direct_mappings(group, dev); + + dev_info(dev, "Using iommu %s mapping\n", + type == IOMMU_DOMAIN_DMA ? "dma" : "direct"); + + ret = 0; +out: + mutex_unlock(&group->mutex); + iommu_group_put(group); + + return ret; +} + +/* Request that a device is direct mapped by the IOMMU */ +int iommu_request_dm_for_dev(struct device *dev) +{ + return request_default_domain_for_dev(dev, IOMMU_DOMAIN_IDENTITY); +} + +/* Request that a device can't be direct mapped by the IOMMU */ +int iommu_request_dma_domain_for_dev(struct device *dev) +{ + return request_default_domain_for_dev(dev, IOMMU_DOMAIN_DMA); +} + void iommu_set_default_passthrough(bool cmd_line) { if (cmd_line) diff --git a/include/linux/iommu.h b/include/linux/iommu.h index fee209efb756..f9c213122402 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -455,6 +455,8 @@ extern void iommu_get_resv_regions(struct device *dev, struct list_head *list); extern void iommu_put_resv_regions(struct device *dev, struct list_head *list); extern void generic_iommu_put_resv_regions(struct device *dev, struct list_head *list); +extern int iommu_request_dm_for_dev(struct device *dev); +extern int iommu_request_dma_domain_for_dev(struct device *dev); extern void iommu_set_default_passthrough(bool cmd_line); extern void iommu_set_default_translated(bool cmd_line); extern bool iommu_default_passthrough(void); @@ -772,6 +774,16 @@ static inline int iommu_get_group_resv_regions(struct iommu_group *group, return -ENODEV; } +static inline int iommu_request_dm_for_dev(struct device *dev) +{ + return -ENODEV; +} + +static inline int iommu_request_dma_domain_for_dev(struct device *dev) +{ + return -ENODEV; +} + static inline void iommu_set_default_passthrough(bool cmd_line) { } |