From 1386a12ee395909173468001cc66c256ca3e3602 Mon Sep 17 00:00:00 2001 From: Russell King Date: Tue, 4 Aug 2020 01:39:54 +0100 Subject: Revert "iommu: Remove functions that support private domain" This reverts commit 69cf449166987d9a041020be6422ee7bf94a7228. --- drivers/iommu/iommu.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/iommu.h | 12 ++++++++++ 2 files changed, 77 insertions(+) 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) { } -- cgit