Loading drivers/iommu/iommu.c +53 −0 Original line number Diff line number Diff line Loading @@ -1538,3 +1538,56 @@ void iommu_put_dm_regions(struct device *dev, struct list_head *list) if (ops && ops->put_dm_regions) ops->put_dm_regions(dev, list); } /* Request that a device is direct mapped by the IOMMU */ int iommu_request_dm_for_dev(struct device *dev) { struct iommu_domain *dm_domain; struct iommu_group *group; int ret; /* Device must already be in a group before calling this function */ group = iommu_group_get_for_dev(dev); if (!group) return -EINVAL; mutex_lock(&group->mutex); /* Check if the default domain is already direct mapped */ ret = 0; if (group->default_domain && group->default_domain->type == IOMMU_DOMAIN_IDENTITY) goto out; /* Don't change mappings of existing devices */ ret = -EBUSY; if (iommu_group_device_count(group) != 1) goto out; /* Allocate a direct mapped domain */ ret = -ENOMEM; dm_domain = __iommu_domain_alloc(dev->bus, IOMMU_DOMAIN_IDENTITY); if (!dm_domain) goto out; /* Attach the device to the domain */ ret = __iommu_attach_group(dm_domain, group); if (ret) { iommu_domain_free(dm_domain); goto out; } /* Make the direct mapped domain the default for this group */ if (group->default_domain) iommu_domain_free(group->default_domain); group->default_domain = dm_domain; pr_info("Using direct mapping for device %s\n", dev_name(dev)); ret = 0; out: mutex_unlock(&group->mutex); iommu_group_put(group); return ret; } include/linux/iommu.h +6 −0 Original line number Diff line number Diff line Loading @@ -225,6 +225,7 @@ extern void iommu_set_fault_handler(struct iommu_domain *domain, extern void iommu_get_dm_regions(struct device *dev, struct list_head *list); extern void iommu_put_dm_regions(struct device *dev, struct list_head *list); extern int iommu_request_dm_for_dev(struct device *dev); extern int iommu_attach_group(struct iommu_domain *domain, struct iommu_group *group); Loading Loading @@ -411,6 +412,11 @@ static inline void iommu_put_dm_regions(struct device *dev, { } static inline int iommu_request_dm_for_dev(struct device *dev) { return -ENODEV; } static inline int iommu_attach_group(struct iommu_domain *domain, struct iommu_group *group) { Loading Loading
drivers/iommu/iommu.c +53 −0 Original line number Diff line number Diff line Loading @@ -1538,3 +1538,56 @@ void iommu_put_dm_regions(struct device *dev, struct list_head *list) if (ops && ops->put_dm_regions) ops->put_dm_regions(dev, list); } /* Request that a device is direct mapped by the IOMMU */ int iommu_request_dm_for_dev(struct device *dev) { struct iommu_domain *dm_domain; struct iommu_group *group; int ret; /* Device must already be in a group before calling this function */ group = iommu_group_get_for_dev(dev); if (!group) return -EINVAL; mutex_lock(&group->mutex); /* Check if the default domain is already direct mapped */ ret = 0; if (group->default_domain && group->default_domain->type == IOMMU_DOMAIN_IDENTITY) goto out; /* Don't change mappings of existing devices */ ret = -EBUSY; if (iommu_group_device_count(group) != 1) goto out; /* Allocate a direct mapped domain */ ret = -ENOMEM; dm_domain = __iommu_domain_alloc(dev->bus, IOMMU_DOMAIN_IDENTITY); if (!dm_domain) goto out; /* Attach the device to the domain */ ret = __iommu_attach_group(dm_domain, group); if (ret) { iommu_domain_free(dm_domain); goto out; } /* Make the direct mapped domain the default for this group */ if (group->default_domain) iommu_domain_free(group->default_domain); group->default_domain = dm_domain; pr_info("Using direct mapping for device %s\n", dev_name(dev)); ret = 0; out: mutex_unlock(&group->mutex); iommu_group_put(group); return ret; }
include/linux/iommu.h +6 −0 Original line number Diff line number Diff line Loading @@ -225,6 +225,7 @@ extern void iommu_set_fault_handler(struct iommu_domain *domain, extern void iommu_get_dm_regions(struct device *dev, struct list_head *list); extern void iommu_put_dm_regions(struct device *dev, struct list_head *list); extern int iommu_request_dm_for_dev(struct device *dev); extern int iommu_attach_group(struct iommu_domain *domain, struct iommu_group *group); Loading Loading @@ -411,6 +412,11 @@ static inline void iommu_put_dm_regions(struct device *dev, { } static inline int iommu_request_dm_for_dev(struct device *dev) { return -ENODEV; } static inline int iommu_attach_group(struct iommu_domain *domain, struct iommu_group *group) { Loading