Merge tag 'thermal-6.6-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael...
[linux-2.6-block.git] / drivers / iommu / iommu.c
index c9c370de9d3d54e9a024147064fd2f39d48c38c8..3bfc56df4f781cbb15f6cad090681f8327b8dde4 100644 (file)
@@ -41,6 +41,7 @@
 
 static struct kset *iommu_group_kset;
 static DEFINE_IDA(iommu_group_ida);
+static DEFINE_IDA(iommu_global_pasid_ida);
 
 static unsigned int iommu_def_domain_type __read_mostly;
 static bool iommu_dma_strict __read_mostly = IS_ENABLED(CONFIG_IOMMU_DEFAULT_DMA_STRICT);
@@ -129,9 +130,12 @@ static int iommu_setup_default_domain(struct iommu_group *group,
                                      int target_type);
 static int iommu_create_device_direct_mappings(struct iommu_domain *domain,
                                               struct device *dev);
-static struct iommu_group *iommu_group_get_for_dev(struct device *dev);
 static ssize_t iommu_group_store_type(struct iommu_group *group,
                                      const char *buf, size_t count);
+static struct group_device *iommu_group_alloc_device(struct iommu_group *group,
+                                                    struct device *dev);
+static void __iommu_group_free_device(struct iommu_group *group,
+                                     struct group_device *grp_dev);
 
 #define IOMMU_GROUP_ATTR(_name, _mode, _show, _store)          \
 struct iommu_group_attribute iommu_group_attr_##_name =                \
@@ -377,28 +381,18 @@ static u32 dev_iommu_get_max_pasids(struct device *dev)
        return min_t(u32, max_pasids, dev->iommu->iommu_dev->max_pasids);
 }
 
-static int __iommu_probe_device(struct device *dev, struct list_head *group_list)
+/*
+ * Init the dev->iommu and dev->iommu_group in the struct device and get the
+ * driver probed
+ */
+static int iommu_init_device(struct device *dev, const struct iommu_ops *ops)
 {
-       const struct iommu_ops *ops = dev->bus->iommu_ops;
        struct iommu_device *iommu_dev;
        struct iommu_group *group;
-       static DEFINE_MUTEX(iommu_probe_device_lock);
        int ret;
 
-       if (!ops)
-               return -ENODEV;
-       /*
-        * Serialise to avoid races between IOMMU drivers registering in
-        * parallel and/or the "replay" calls from ACPI/OF code via client
-        * driver probe. Once the latter have been cleaned up we should
-        * probably be able to use device_lock() here to minimise the scope,
-        * but for now enforcing a simple global ordering is fine.
-        */
-       mutex_lock(&iommu_probe_device_lock);
-       if (!dev_iommu_get(dev)) {
-               ret = -ENOMEM;
-               goto err_unlock;
-       }
+       if (!dev_iommu_get(dev))
+               return -ENOMEM;
 
        if (!try_module_get(ops->owner)) {
                ret = -EINVAL;
@@ -408,124 +402,184 @@ static int __iommu_probe_device(struct device *dev, struct list_head *group_list
        iommu_dev = ops->probe_device(dev);
        if (IS_ERR(iommu_dev)) {
                ret = PTR_ERR(iommu_dev);
-               goto out_module_put;
+               goto err_module_put;
        }
 
-       dev->iommu->iommu_dev = iommu_dev;
-       dev->iommu->max_pasids = dev_iommu_get_max_pasids(dev);
-       if (ops->is_attach_deferred)
-               dev->iommu->attach_deferred = ops->is_attach_deferred(dev);
+       ret = iommu_device_link(iommu_dev, dev);
+       if (ret)
+               goto err_release;
 
-       group = iommu_group_get_for_dev(dev);
+       group = ops->device_group(dev);
+       if (WARN_ON_ONCE(group == NULL))
+               group = ERR_PTR(-EINVAL);
        if (IS_ERR(group)) {
                ret = PTR_ERR(group);
-               goto out_release;
+               goto err_unlink;
        }
+       dev->iommu_group = group;
 
-       mutex_lock(&group->mutex);
-       if (group_list && !group->default_domain && list_empty(&group->entry))
-               list_add_tail(&group->entry, group_list);
-       mutex_unlock(&group->mutex);
-       iommu_group_put(group);
-
-       mutex_unlock(&iommu_probe_device_lock);
-       iommu_device_link(iommu_dev, dev);
-
+       dev->iommu->iommu_dev = iommu_dev;
+       dev->iommu->max_pasids = dev_iommu_get_max_pasids(dev);
+       if (ops->is_attach_deferred)
+               dev->iommu->attach_deferred = ops->is_attach_deferred(dev);
        return 0;
 
-out_release:
+err_unlink:
+       iommu_device_unlink(iommu_dev, dev);
+err_release:
        if (ops->release_device)
                ops->release_device(dev);
-
-out_module_put:
+err_module_put:
        module_put(ops->owner);
-
 err_free:
        dev_iommu_free(dev);
+       return ret;
+}
 
-err_unlock:
-       mutex_unlock(&iommu_probe_device_lock);
+static void iommu_deinit_device(struct device *dev)
+{
+       struct iommu_group *group = dev->iommu_group;
+       const struct iommu_ops *ops = dev_iommu_ops(dev);
 
-       return ret;
+       lockdep_assert_held(&group->mutex);
+
+       iommu_device_unlink(dev->iommu->iommu_dev, dev);
+
+       /*
+        * release_device() must stop using any attached domain on the device.
+        * If there are still other devices in the group they are not effected
+        * by this callback.
+        *
+        * The IOMMU driver must set the device to either an identity or
+        * blocking translation and stop using any domain pointer, as it is
+        * going to be freed.
+        */
+       if (ops->release_device)
+               ops->release_device(dev);
+
+       /*
+        * If this is the last driver to use the group then we must free the
+        * domains before we do the module_put().
+        */
+       if (list_empty(&group->devices)) {
+               if (group->default_domain) {
+                       iommu_domain_free(group->default_domain);
+                       group->default_domain = NULL;
+               }
+               if (group->blocking_domain) {
+                       iommu_domain_free(group->blocking_domain);
+                       group->blocking_domain = NULL;
+               }
+               group->domain = NULL;
+       }
+
+       /* Caller must put iommu_group */
+       dev->iommu_group = NULL;
+       module_put(ops->owner);
+       dev_iommu_free(dev);
 }
 
-int iommu_probe_device(struct device *dev)
+static int __iommu_probe_device(struct device *dev, struct list_head *group_list)
 {
-       const struct iommu_ops *ops;
+       const struct iommu_ops *ops = dev->bus->iommu_ops;
        struct iommu_group *group;
+       static DEFINE_MUTEX(iommu_probe_device_lock);
+       struct group_device *gdev;
        int ret;
 
-       ret = __iommu_probe_device(dev, NULL);
-       if (ret)
-               goto err_out;
+       if (!ops)
+               return -ENODEV;
+       /*
+        * Serialise to avoid races between IOMMU drivers registering in
+        * parallel and/or the "replay" calls from ACPI/OF code via client
+        * driver probe. Once the latter have been cleaned up we should
+        * probably be able to use device_lock() here to minimise the scope,
+        * but for now enforcing a simple global ordering is fine.
+        */
+       mutex_lock(&iommu_probe_device_lock);
 
-       group = iommu_group_get(dev);
-       if (!group) {
-               ret = -ENODEV;
-               goto err_release;
+       /* Device is probed already if in a group */
+       if (dev->iommu_group) {
+               ret = 0;
+               goto out_unlock;
        }
 
+       ret = iommu_init_device(dev, ops);
+       if (ret)
+               goto out_unlock;
+
+       group = dev->iommu_group;
+       gdev = iommu_group_alloc_device(group, dev);
        mutex_lock(&group->mutex);
+       if (IS_ERR(gdev)) {
+               ret = PTR_ERR(gdev);
+               goto err_put_group;
+       }
 
+       /*
+        * The gdev must be in the list before calling
+        * iommu_setup_default_domain()
+        */
+       list_add_tail(&gdev->list, &group->devices);
+       WARN_ON(group->default_domain && !group->domain);
        if (group->default_domain)
                iommu_create_device_direct_mappings(group->default_domain, dev);
-
        if (group->domain) {
                ret = __iommu_device_set_domain(group, dev, group->domain, 0);
                if (ret)
-                       goto err_unlock;
-       } else if (!group->default_domain) {
+                       goto err_remove_gdev;
+       } else if (!group->default_domain && !group_list) {
                ret = iommu_setup_default_domain(group, 0);
                if (ret)
-                       goto err_unlock;
+                       goto err_remove_gdev;
+       } else if (!group->default_domain) {
+               /*
+                * With a group_list argument we defer the default_domain setup
+                * to the caller by providing a de-duplicated list of groups
+                * that need further setup.
+                */
+               if (list_empty(&group->entry))
+                       list_add_tail(&group->entry, group_list);
        }
-
        mutex_unlock(&group->mutex);
-       iommu_group_put(group);
+       mutex_unlock(&iommu_probe_device_lock);
 
-       ops = dev_iommu_ops(dev);
-       if (ops->probe_finalize)
-               ops->probe_finalize(dev);
+       if (dev_is_pci(dev))
+               iommu_dma_set_pci_32bit_workaround(dev);
 
        return 0;
 
-err_unlock:
+err_remove_gdev:
+       list_del(&gdev->list);
+       __iommu_group_free_device(group, gdev);
+err_put_group:
+       iommu_deinit_device(dev);
        mutex_unlock(&group->mutex);
        iommu_group_put(group);
-err_release:
-       iommu_release_device(dev);
+out_unlock:
+       mutex_unlock(&iommu_probe_device_lock);
 
-err_out:
        return ret;
-
 }
 
-/*
- * Remove a device from a group's device list and return the group device
- * if successful.
- */
-static struct group_device *
-__iommu_group_remove_device(struct iommu_group *group, struct device *dev)
+int iommu_probe_device(struct device *dev)
 {
-       struct group_device *device;
+       const struct iommu_ops *ops;
+       int ret;
 
-       lockdep_assert_held(&group->mutex);
-       for_each_group_device(group, device) {
-               if (device->dev == dev) {
-                       list_del(&device->list);
-                       return device;
-               }
-       }
+       ret = __iommu_probe_device(dev, NULL);
+       if (ret)
+               return ret;
 
-       return NULL;
+       ops = dev_iommu_ops(dev);
+       if (ops->probe_finalize)
+               ops->probe_finalize(dev);
+
+       return 0;
 }
 
-/*
- * Release a device from its group and decrements the iommu group reference
- * count.
- */
-static void __iommu_group_release_device(struct iommu_group *group,
-                                        struct group_device *grp_dev)
+static void __iommu_group_free_device(struct iommu_group *group,
+                                     struct group_device *grp_dev)
 {
        struct device *dev = grp_dev->dev;
 
@@ -534,54 +588,57 @@ static void __iommu_group_release_device(struct iommu_group *group,
 
        trace_remove_device_from_group(group->id, dev);
 
+       /*
+        * If the group has become empty then ownership must have been
+        * released, and the current domain must be set back to NULL or
+        * the default domain.
+        */
+       if (list_empty(&group->devices))
+               WARN_ON(group->owner_cnt ||
+                       group->domain != group->default_domain);
+
        kfree(grp_dev->name);
        kfree(grp_dev);
-       dev->iommu_group = NULL;
-       kobject_put(group->devices_kobj);
 }
 
-static void iommu_release_device(struct device *dev)
+/* Remove the iommu_group from the struct device. */
+static void __iommu_group_remove_device(struct device *dev)
 {
        struct iommu_group *group = dev->iommu_group;
        struct group_device *device;
-       const struct iommu_ops *ops;
-
-       if (!dev->iommu || !group)
-               return;
-
-       iommu_device_unlink(dev->iommu->iommu_dev, dev);
 
        mutex_lock(&group->mutex);
-       device = __iommu_group_remove_device(group, dev);
+       for_each_group_device(group, device) {
+               if (device->dev != dev)
+                       continue;
 
-       /*
-        * If the group has become empty then ownership must have been released,
-        * and the current domain must be set back to NULL or the default
-        * domain.
-        */
-       if (list_empty(&group->devices))
-               WARN_ON(group->owner_cnt ||
-                       group->domain != group->default_domain);
+               list_del(&device->list);
+               __iommu_group_free_device(group, device);
+               if (dev->iommu && dev->iommu->iommu_dev)
+                       iommu_deinit_device(dev);
+               else
+                       dev->iommu_group = NULL;
+               break;
+       }
+       mutex_unlock(&group->mutex);
 
        /*
-        * release_device() must stop using any attached domain on the device.
-        * If there are still other devices in the group they are not effected
-        * by this callback.
-        *
-        * The IOMMU driver must set the device to either an identity or
-        * blocking translation and stop using any domain pointer, as it is
-        * going to be freed.
+        * Pairs with the get in iommu_init_device() or
+        * iommu_group_add_device()
         */
-       ops = dev_iommu_ops(dev);
-       if (ops->release_device)
-               ops->release_device(dev);
-       mutex_unlock(&group->mutex);
+       iommu_group_put(group);
+}
 
-       if (device)
-               __iommu_group_release_device(group, device);
+static void iommu_release_device(struct device *dev)
+{
+       struct iommu_group *group = dev->iommu_group;
 
-       module_put(ops->owner);
-       dev_iommu_free(dev);
+       if (group)
+               __iommu_group_remove_device(dev);
+
+       /* Free any fwspec if no iommu_driver was ever attached */
+       if (dev->iommu)
+               dev_iommu_free(dev);
 }
 
 static int __init iommu_set_def_domain_type(char *str)
@@ -842,10 +899,9 @@ static void iommu_group_release(struct kobject *kobj)
 
        ida_free(&iommu_group_ida, group->id);
 
-       if (group->default_domain)
-               iommu_domain_free(group->default_domain);
-       if (group->blocking_domain)
-               iommu_domain_free(group->blocking_domain);
+       /* Domains are free'd by iommu_deinit_device() */
+       WARN_ON(group->default_domain);
+       WARN_ON(group->blocking_domain);
 
        kfree(group->name);
        kfree(group);
@@ -1003,14 +1059,12 @@ static int iommu_create_device_direct_mappings(struct iommu_domain *domain,
        unsigned long pg_size;
        int ret = 0;
 
-       if (!iommu_is_dma_domain(domain))
-               return 0;
-
-       BUG_ON(!domain->pgsize_bitmap);
-
-       pg_size = 1UL << __ffs(domain->pgsize_bitmap);
+       pg_size = domain->pgsize_bitmap ? 1UL << __ffs(domain->pgsize_bitmap) : 0;
        INIT_LIST_HEAD(&mappings);
 
+       if (WARN_ON_ONCE(iommu_is_dma_domain(domain) && !pg_size))
+               return -EINVAL;
+
        iommu_get_resv_regions(dev, &mappings);
 
        /* We need to consider overlapping regions for different devices */
@@ -1018,13 +1072,17 @@ static int iommu_create_device_direct_mappings(struct iommu_domain *domain,
                dma_addr_t start, end, addr;
                size_t map_size = 0;
 
-               start = ALIGN(entry->start, pg_size);
-               end   = ALIGN(entry->start + entry->length, pg_size);
+               if (entry->type == IOMMU_RESV_DIRECT)
+                       dev->iommu->require_direct = 1;
 
-               if (entry->type != IOMMU_RESV_DIRECT &&
-                   entry->type != IOMMU_RESV_DIRECT_RELAXABLE)
+               if ((entry->type != IOMMU_RESV_DIRECT &&
+                    entry->type != IOMMU_RESV_DIRECT_RELAXABLE) ||
+                   !iommu_is_dma_domain(domain))
                        continue;
 
+               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;
 
@@ -1058,22 +1116,16 @@ out:
        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)
- * @dev: the device
- *
- * This function is called by an iommu driver to add a device into a
- * group.  Adding a device increments the group reference count.
- */
-int iommu_group_add_device(struct iommu_group *group, struct device *dev)
+/* This is undone by __iommu_group_free_device() */
+static struct group_device *iommu_group_alloc_device(struct iommu_group *group,
+                                                    struct device *dev)
 {
        int ret, i = 0;
        struct group_device *device;
 
        device = kzalloc(sizeof(*device), GFP_KERNEL);
        if (!device)
-               return -ENOMEM;
+               return ERR_PTR(-ENOMEM);
 
        device->dev = dev;
 
@@ -1104,18 +1156,11 @@ rename:
                goto err_free_name;
        }
 
-       kobject_get(group->devices_kobj);
-
-       dev->iommu_group = group;
-
-       mutex_lock(&group->mutex);
-       list_add_tail(&device->list, &group->devices);
-       mutex_unlock(&group->mutex);
        trace_add_device_to_group(group->id, dev);
 
        dev_info(dev, "Adding to iommu group %d\n", group->id);
 
-       return 0;
+       return device;
 
 err_free_name:
        kfree(device->name);
@@ -1124,7 +1169,32 @@ err_remove_link:
 err_free_device:
        kfree(device);
        dev_err(dev, "Failed to add to iommu group %d: %d\n", group->id, ret);
-       return ret;
+       return ERR_PTR(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)
+ * @dev: the device
+ *
+ * This function is called by an iommu driver to add a device into a
+ * group.  Adding a device increments the group reference count.
+ */
+int iommu_group_add_device(struct iommu_group *group, struct device *dev)
+{
+       struct group_device *gdev;
+
+       gdev = iommu_group_alloc_device(group, dev);
+       if (IS_ERR(gdev))
+               return PTR_ERR(gdev);
+
+       iommu_group_ref_get(group);
+       dev->iommu_group = group;
+
+       mutex_lock(&group->mutex);
+       list_add_tail(&gdev->list, &group->devices);
+       mutex_unlock(&group->mutex);
+       return 0;
 }
 EXPORT_SYMBOL_GPL(iommu_group_add_device);
 
@@ -1138,19 +1208,13 @@ EXPORT_SYMBOL_GPL(iommu_group_add_device);
 void iommu_group_remove_device(struct device *dev)
 {
        struct iommu_group *group = dev->iommu_group;
-       struct group_device *device;
 
        if (!group)
                return;
 
        dev_info(dev, "Removing from iommu group %d\n", group->id);
 
-       mutex_lock(&group->mutex);
-       device = __iommu_group_remove_device(group, dev);
-       mutex_unlock(&group->mutex);
-
-       if (device)
-               __iommu_group_release_device(group, device);
+       __iommu_group_remove_device(dev);
 }
 EXPORT_SYMBOL_GPL(iommu_group_remove_device);
 
@@ -1708,45 +1772,6 @@ iommu_group_alloc_default_domain(struct iommu_group *group, int req_type)
        return dom;
 }
 
-/**
- * iommu_group_get_for_dev - Find or create the IOMMU group for a device
- * @dev: target device
- *
- * This function is intended to be called by IOMMU drivers and extended to
- * support common, bus-defined algorithms when determining or creating the
- * IOMMU group for a device.  On success, the caller will hold a reference
- * to the returned IOMMU group, which will already include the provided
- * device.  The reference should be released with iommu_group_put().
- */
-static struct iommu_group *iommu_group_get_for_dev(struct device *dev)
-{
-       const struct iommu_ops *ops = dev_iommu_ops(dev);
-       struct iommu_group *group;
-       int ret;
-
-       group = iommu_group_get(dev);
-       if (group)
-               return group;
-
-       group = ops->device_group(dev);
-       if (WARN_ON_ONCE(group == NULL))
-               return ERR_PTR(-EINVAL);
-
-       if (IS_ERR(group))
-               return group;
-
-       ret = iommu_group_add_device(group, dev);
-       if (ret)
-               goto out_put_group;
-
-       return group;
-
-out_put_group:
-       iommu_group_put(group);
-
-       return ERR_PTR(ret);
-}
-
 struct iommu_domain *iommu_group_default_domain(struct iommu_group *group)
 {
        return group->default_domain;
@@ -1755,16 +1780,8 @@ struct iommu_domain *iommu_group_default_domain(struct iommu_group *group)
 static int probe_iommu_group(struct device *dev, void *data)
 {
        struct list_head *group_list = data;
-       struct iommu_group *group;
        int ret;
 
-       /* Device is probed already if in a group */
-       group = iommu_group_get(dev);
-       if (group) {
-               iommu_group_put(group);
-               return 0;
-       }
-
        ret = __iommu_probe_device(dev, group_list);
        if (ret == -ENODEV)
                ret = 0;
@@ -1840,11 +1857,6 @@ int bus_iommu_probe(const struct bus_type *bus)
        LIST_HEAD(group_list);
        int ret;
 
-       /*
-        * This code-path does not allocate the default domain when
-        * creating the iommu group, so do it after the groups are
-        * created.
-        */
        ret = bus_for_each_dev(bus, NULL, &group_list, probe_iommu_group);
        if (ret)
                return ret;
@@ -1857,6 +1869,11 @@ int bus_iommu_probe(const struct bus_type *bus)
                /* Remove item from the list */
                list_del_init(&group->entry);
 
+               /*
+                * We go to the trouble of deferred default domain creation so
+                * that the cross-group default domain type and the setup of the
+                * IOMMU_RESV_DIRECT will work correctly in non-hotpug scenarios.
+                */
                ret = iommu_setup_default_domain(group, 0);
                if (ret) {
                        mutex_unlock(&group->mutex);
@@ -2191,6 +2208,21 @@ static int __iommu_device_set_domain(struct iommu_group *group,
 {
        int ret;
 
+       /*
+        * If the device requires IOMMU_RESV_DIRECT then we cannot allow
+        * the blocking domain to be attached as it does not contain the
+        * required 1:1 mapping. This test effectively excludes the device
+        * being used with iommu_group_claim_dma_owner() which will block
+        * vfio and iommufd as well.
+        */
+       if (dev->iommu->require_direct &&
+           (new_domain->type == IOMMU_DOMAIN_BLOCKED ||
+            new_domain == group->blocking_domain)) {
+               dev_warn(dev,
+                        "Firmware has requested this device have a 1:1 IOMMU mapping, rejecting configuring the device without a 1:1 mapping. Contact your platform vendor.\n");
+               return -EINVAL;
+       }
+
        if (dev->iommu->attach_deferred) {
                if (new_domain == group->default_domain)
                        return 0;
@@ -3282,7 +3314,7 @@ static void __iommu_release_dma_ownership(struct iommu_group *group)
 
 /**
  * iommu_group_release_dma_owner() - Release DMA ownership of a group
- * @dev: The device
+ * @group: The group
  *
  * Release the DMA ownership claimed by iommu_group_claim_dma_owner().
  */
@@ -3296,7 +3328,7 @@ EXPORT_SYMBOL_GPL(iommu_group_release_dma_owner);
 
 /**
  * iommu_device_release_dma_owner() - Release DMA ownership of a device
- * @group: The device.
+ * @dev: The device.
  *
  * Release the DMA ownership claimed by iommu_device_claim_dma_owner().
  */
@@ -3479,3 +3511,30 @@ struct iommu_domain *iommu_sva_domain_alloc(struct device *dev,
 
        return domain;
 }
+
+ioasid_t iommu_alloc_global_pasid(struct device *dev)
+{
+       int ret;
+
+       /* max_pasids == 0 means that the device does not support PASID */
+       if (!dev->iommu->max_pasids)
+               return IOMMU_PASID_INVALID;
+
+       /*
+        * max_pasids is set up by vendor driver based on number of PASID bits
+        * supported but the IDA allocation is inclusive.
+        */
+       ret = ida_alloc_range(&iommu_global_pasid_ida, IOMMU_FIRST_GLOBAL_PASID,
+                             dev->iommu->max_pasids - 1, GFP_KERNEL);
+       return ret < 0 ? IOMMU_PASID_INVALID : ret;
+}
+EXPORT_SYMBOL_GPL(iommu_alloc_global_pasid);
+
+void iommu_free_global_pasid(ioasid_t pasid)
+{
+       if (WARN_ON(pasid == IOMMU_PASID_INVALID))
+               return;
+
+       ida_free(&iommu_global_pasid_ida, pasid);
+}
+EXPORT_SYMBOL_GPL(iommu_free_global_pasid);