Merge branch 'stable/for-linus-5.15' of git://git.kernel.org/pub/scm/linux/kernel...
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 3 Sep 2021 17:34:44 +0000 (10:34 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 3 Sep 2021 17:34:44 +0000 (10:34 -0700)
Pull swiotlb updates from Konrad Rzeszutek Wilk:
 "A new feature called restricted DMA pools. It allows SWIOTLB to
  utilize per-device (or per-platform) allocated memory pools instead of
  using the global one.

  The first big user of this is ARM Confidential Computing where the
  memory for DMA operations can be set per platform"

* 'stable/for-linus-5.15' of git://git.kernel.org/pub/scm/linux/kernel/git/konrad/swiotlb: (23 commits)
  swiotlb: use depends on for DMA_RESTRICTED_POOL
  of: restricted dma: Don't fail device probe on rmem init failure
  of: Move of_dma_set_restricted_buffer() into device.c
  powerpc/svm: Don't issue ultracalls if !mem_encrypt_active()
  s390/pv: fix the forcing of the swiotlb
  swiotlb: Free tbl memory in swiotlb_exit()
  swiotlb: Emit diagnostic in swiotlb_exit()
  swiotlb: Convert io_default_tlb_mem to static allocation
  of: Return success from of_dma_set_restricted_buffer() when !OF_ADDRESS
  swiotlb: add overflow checks to swiotlb_bounce
  swiotlb: fix implicit debugfs declarations
  of: Add plumbing for restricted DMA pool
  dt-bindings: of: Add restricted DMA pool
  swiotlb: Add restricted DMA pool initialization
  swiotlb: Add restricted DMA alloc/free support
  swiotlb: Refactor swiotlb_tbl_unmap_single
  swiotlb: Move alloc_size to swiotlb_find_slots
  swiotlb: Use is_swiotlb_force_bounce for swiotlb data bouncing
  swiotlb: Update is_swiotlb_active to add a struct device argument
  swiotlb: Update is_swiotlb_buffer to add a struct device argument
  ...

1  2 
arch/s390/mm/init.c
drivers/base/core.c
drivers/gpu/drm/i915/gem/i915_gem_internal.c
drivers/iommu/dma-iommu.c
drivers/pci/xen-pcifront.c
drivers/xen/swiotlb-xen.c
include/linux/device.h
kernel/dma/Kconfig
kernel/dma/direct.c

diff --combined arch/s390/mm/init.c
@@@ -34,7 -34,6 +34,7 @@@
  #include <asm/processor.h>
  #include <linux/uaccess.h>
  #include <asm/pgalloc.h>
 +#include <asm/kfence.h>
  #include <asm/ptdump.h>
  #include <asm/dma.h>
  #include <asm/lowcore.h>
@@@ -187,9 -186,9 +187,9 @@@ static void pv_init(void
                return;
  
        /* make sure bounce buffers are shared */
+       swiotlb_force = SWIOTLB_FORCE;
        swiotlb_init(1);
        swiotlb_update_mem_attributes();
-       swiotlb_force = SWIOTLB_FORCE;
  }
  
  void __init mem_init(void)
          high_memory = (void *) __va(max_low_pfn * PAGE_SIZE);
  
        pv_init();
 -
 +      kfence_split_mapping();
        /* Setup guest page hinting */
        cmma_init();
  
diff --combined drivers/base/core.c
@@@ -27,6 -27,7 +27,7 @@@
  #include <linux/netdevice.h>
  #include <linux/sched/signal.h>
  #include <linux/sched/mm.h>
+ #include <linux/swiotlb.h>
  #include <linux/sysfs.h>
  #include <linux/dma-map-ops.h> /* for dma_default_coherent */
  
@@@ -574,10 -575,8 +575,10 @@@ static void devlink_remove_symlinks(str
                return;
        }
  
 -      snprintf(buf, len, "supplier:%s:%s", dev_bus_name(sup), dev_name(sup));
 -      sysfs_remove_link(&con->kobj, buf);
 +      if (device_is_registered(con)) {
 +              snprintf(buf, len, "supplier:%s:%s", dev_bus_name(sup), dev_name(sup));
 +              sysfs_remove_link(&con->kobj, buf);
 +      }
        snprintf(buf, len, "consumer:%s:%s", dev_bus_name(con), dev_name(con));
        sysfs_remove_link(&sup->kobj, buf);
        kfree(buf);
@@@ -886,8 -885,6 +887,8 @@@ static void device_link_put_kref(struc
  {
        if (link->flags & DL_FLAG_STATELESS)
                kref_put(&link->kref, __device_link_del);
 +      else if (!device_is_registered(link->consumer))
 +              __device_link_del(&link->kref);
        else
                WARN(1, "Unable to drop a managed device link reference\n");
  }
@@@ -2004,24 -2001,24 +2005,24 @@@ static inline int device_is_not_partiti
  }
  #endif
  
 -static int
 -device_platform_notify(struct device *dev, enum kobject_action action)
 +static void device_platform_notify(struct device *dev)
  {
 -      int ret;
 +      acpi_device_notify(dev);
  
 -      ret = acpi_platform_notify(dev, action);
 -      if (ret)
 -              return ret;
 -
 -      ret = software_node_notify(dev, action);
 -      if (ret)
 -              return ret;
 +      software_node_notify(dev);
  
 -      if (platform_notify && action == KOBJ_ADD)
 +      if (platform_notify)
                platform_notify(dev);
 -      else if (platform_notify_remove && action == KOBJ_REMOVE)
 +}
 +
 +static void device_platform_notify_remove(struct device *dev)
 +{
 +      acpi_device_notify_remove(dev);
 +
 +      software_node_notify_remove(dev);
 +
 +      if (platform_notify_remove)
                platform_notify_remove(dev);
 -      return 0;
  }
  
  /**
@@@ -2839,7 -2836,6 +2840,7 @@@ void device_initialize(struct device *d
        device_pm_init(dev);
        set_dev_node(dev, -1);
  #ifdef CONFIG_GENERIC_MSI_IRQ
 +      raw_spin_lock_init(&dev->msi_lock);
        INIT_LIST_HEAD(&dev->msi_list);
  #endif
        INIT_LIST_HEAD(&dev->links.consumers);
      defined(CONFIG_ARCH_HAS_SYNC_DMA_FOR_CPU_ALL)
        dev->dma_coherent = dma_default_coherent;
  #endif
+ #ifdef CONFIG_SWIOTLB
+       dev->dma_io_tlb_mem = &io_tlb_default_mem;
+ #endif
  }
  EXPORT_SYMBOL_GPL(device_initialize);
  
@@@ -3294,7 -3293,9 +3298,7 @@@ int device_add(struct device *dev
        }
  
        /* notify platform of device entry */
 -      error = device_platform_notify(dev, KOBJ_ADD);
 -      if (error)
 -              goto platform_error;
 +      device_platform_notify(dev);
  
        error = device_create_file(dev, &dev_attr_uevent);
        if (error)
@@@ -3397,7 -3398,8 +3401,7 @@@ done
   SymlinkError:
        device_remove_file(dev, &dev_attr_uevent);
   attrError:
 -      device_platform_notify(dev, KOBJ_REMOVE);
 -platform_error:
 +      device_platform_notify_remove(dev);
        kobject_uevent(&dev->kobj, KOBJ_REMOVE);
        glue_dir = get_glue_dir(dev);
        kobject_del(&dev->kobj);
@@@ -3542,7 -3544,7 +3546,7 @@@ void device_del(struct device *dev
        bus_remove_device(dev);
        device_pm_remove(dev);
        driver_deferred_probe_del(dev);
 -      device_platform_notify(dev, KOBJ_REMOVE);
 +      device_platform_notify_remove(dev);
        device_remove_properties(dev);
        device_links_purge(dev);
  
@@@ -4581,8 -4583,8 +4585,8 @@@ static void __dev_printk(const char *le
                printk("%s(NULL device *): %pV", level, vaf);
  }
  
 -void dev_printk(const char *level, const struct device *dev,
 -              const char *fmt, ...)
 +void _dev_printk(const char *level, const struct device *dev,
 +               const char *fmt, ...)
  {
        struct va_format vaf;
        va_list args;
  
        va_end(args);
  }
 -EXPORT_SYMBOL(dev_printk);
 +EXPORT_SYMBOL(_dev_printk);
  
  #define define_dev_printk_level(func, kern_level)             \
  void func(const struct device *dev, const char *fmt, ...)     \
@@@ -42,7 -42,7 +42,7 @@@ static int i915_gem_object_get_pages_in
  
        max_order = MAX_ORDER;
  #ifdef CONFIG_SWIOTLB
-       if (is_swiotlb_active()) {
+       if (is_swiotlb_active(obj->base.dev->dev)) {
                unsigned int max_segment;
  
                max_segment = swiotlb_max_segment();
@@@ -177,8 -177,8 +177,8 @@@ i915_gem_object_create_internal(struct 
                return ERR_PTR(-ENOMEM);
  
        drm_gem_private_object_init(&i915->drm, &obj->base, size);
 -      i915_gem_object_init(obj, &i915_gem_object_internal_ops, &lock_class,
 -                           I915_BO_ALLOC_STRUCT_PAGE);
 +      i915_gem_object_init(obj, &i915_gem_object_internal_ops, &lock_class, 0);
 +      obj->mem_flags |= I915_BO_FLAG_STRUCT_PAGE;
  
        /*
         * Mark the object as volatile, such that the pages are marked as
@@@ -506,7 -506,7 +506,7 @@@ static void __iommu_dma_unmap_swiotlb(s
  
        __iommu_dma_unmap(dev, dma_addr, size);
  
-       if (unlikely(is_swiotlb_buffer(phys)))
+       if (unlikely(is_swiotlb_buffer(dev, phys)))
                swiotlb_tbl_unmap_single(dev, phys, size, dir, attrs);
  }
  
@@@ -577,7 -577,7 +577,7 @@@ static dma_addr_t __iommu_dma_map_swiot
        }
  
        iova = __iommu_dma_map(dev, phys, aligned_size, prot, dma_mask);
-       if (iova == DMA_MAPPING_ERROR && is_swiotlb_buffer(phys))
+       if (iova == DMA_MAPPING_ERROR && is_swiotlb_buffer(dev, phys))
                swiotlb_tbl_unmap_single(dev, phys, org_size, dir, attrs);
        return iova;
  }
@@@ -768,7 -768,6 +768,7 @@@ static void iommu_dma_free_noncontiguou
        __iommu_dma_unmap(dev, sgt->sgl->dma_address, size);
        __iommu_dma_free_pages(sh->pages, PAGE_ALIGN(size) >> PAGE_SHIFT);
        sg_free_table(&sh->sgt);
 +      kfree(sh);
  }
  #endif /* CONFIG_DMA_REMAP */
  
@@@ -784,7 -783,7 +784,7 @@@ static void iommu_dma_sync_single_for_c
        if (!dev_is_dma_coherent(dev))
                arch_sync_dma_for_cpu(phys, size, dir);
  
-       if (is_swiotlb_buffer(phys))
+       if (is_swiotlb_buffer(dev, phys))
                swiotlb_sync_single_for_cpu(dev, phys, size, dir);
  }
  
@@@ -797,7 -796,7 +797,7 @@@ static void iommu_dma_sync_single_for_d
                return;
  
        phys = iommu_iova_to_phys(iommu_get_dma_domain(dev), dma_handle);
-       if (is_swiotlb_buffer(phys))
+       if (is_swiotlb_buffer(dev, phys))
                swiotlb_sync_single_for_device(dev, phys, size, dir);
  
        if (!dev_is_dma_coherent(dev))
@@@ -818,7 -817,7 +818,7 @@@ static void iommu_dma_sync_sg_for_cpu(s
                if (!dev_is_dma_coherent(dev))
                        arch_sync_dma_for_cpu(sg_phys(sg), sg->length, dir);
  
-               if (is_swiotlb_buffer(sg_phys(sg)))
+               if (is_swiotlb_buffer(dev, sg_phys(sg)))
                        swiotlb_sync_single_for_cpu(dev, sg_phys(sg),
                                                    sg->length, dir);
        }
@@@ -835,7 -834,7 +835,7 @@@ static void iommu_dma_sync_sg_for_devic
                return;
  
        for_each_sg(sgl, sg, nelems, i) {
-               if (is_swiotlb_buffer(sg_phys(sg)))
+               if (is_swiotlb_buffer(dev, sg_phys(sg)))
                        swiotlb_sync_single_for_device(dev, sg_phys(sg),
                                                       sg->length, dir);
  
@@@ -973,7 -972,7 +973,7 @@@ static int iommu_dma_map_sg_swiotlb(str
  
  out_unmap:
        iommu_dma_unmap_sg_swiotlb(dev, sg, i, dir, attrs | DMA_ATTR_SKIP_CPU_SYNC);
 -      return 0;
 +      return -EIO;
  }
  
  /*
@@@ -994,13 -993,11 +994,13 @@@ static int iommu_dma_map_sg(struct devi
        dma_addr_t iova;
        size_t iova_len = 0;
        unsigned long mask = dma_get_seg_boundary(dev);
 +      ssize_t ret;
        int i;
  
 -      if (static_branch_unlikely(&iommu_deferred_attach_enabled) &&
 -          iommu_deferred_attach(dev, domain))
 -              return 0;
 +      if (static_branch_unlikely(&iommu_deferred_attach_enabled)) {
 +              ret = iommu_deferred_attach(dev, domain);
 +              goto out;
 +      }
  
        if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC))
                iommu_dma_sync_sg_for_device(dev, sg, nents, dir);
        }
  
        iova = iommu_dma_alloc_iova(domain, iova_len, dma_get_mask(dev), dev);
 -      if (!iova)
 +      if (!iova) {
 +              ret = -ENOMEM;
                goto out_restore_sg;
 +      }
  
        /*
         * We'll leave any physical concatenation to the IOMMU driver's
         * implementation - it knows better than we do.
         */
 -      if (iommu_map_sg_atomic(domain, iova, sg, nents, prot) < iova_len)
 +      ret = iommu_map_sg_atomic(domain, iova, sg, nents, prot);
 +      if (ret < iova_len)
                goto out_free_iova;
  
        return __finalise_sg(dev, sg, nents, iova);
@@@ -1067,10 -1061,7 +1067,10 @@@ out_free_iova
        iommu_dma_free_iova(cookie, iova, iova_len, NULL);
  out_restore_sg:
        __invalidate_sg(sg, nents);
 -      return 0;
 +out:
 +      if (ret != -ENOMEM)
 +              return -EINVAL;
 +      return ret;
  }
  
  static void iommu_dma_unmap_sg(struct device *dev, struct scatterlist *sg,
@@@ -115,7 -115,7 +115,7 @@@ static int do_pci_op(struct pcifront_de
        struct xen_pci_op *active_op = &pdev->sh_info->op;
        unsigned long irq_flags;
        evtchn_port_t port = pdev->evtchn;
 -      unsigned irq = pdev->irq;
 +      unsigned int irq = pdev->irq;
        s64 ns, ns_timeout;
  
        spin_lock_irqsave(&pdev->sh_info_lock, irq_flags);
        }
  
        /*
 -      * We might lose backend service request since we
 -      * reuse same evtchn with pci_conf backend response. So re-schedule
 -      * aer pcifront service.
 -      */
 +       * We might lose backend service request since we
 +       * reuse same evtchn with pci_conf backend response. So re-schedule
 +       * aer pcifront service.
 +       */
        if (test_bit(_XEN_PCIB_active,
                        (unsigned long *)&pdev->sh_info->flags)) {
                dev_err(&pdev->xdev->dev,
@@@ -414,8 -414,7 +414,8 @@@ static int pcifront_scan_bus(struct pci
        struct pci_dev *d;
        unsigned int devfn;
  
 -      /* Scan the bus for functions and add.
 +      /*
 +       * Scan the bus for functions and add.
         * We omit handling of PCI bridge attachment because pciback prevents
         * bridges from being exported.
         */
@@@ -493,10 -492,8 +493,10 @@@ static int pcifront_scan_root(struct pc
  
        list_add(&bus_entry->list, &pdev->root_buses);
  
 -      /* pci_scan_root_bus skips devices which do not have a
 -      * devfn==0. The pcifront_scan_bus enumerates all devfn. */
 +      /*
 +       * pci_scan_root_bus skips devices which do not have a
 +       * devfn==0. The pcifront_scan_bus enumerates all devfn.
 +       */
        err = pcifront_scan_bus(pdev, domain, bus, b);
  
        /* Claim resources before going "live" with our devices */
@@@ -654,10 -651,8 +654,10 @@@ static void pcifront_do_aer(struct work
        pci_channel_state_t state =
                (pci_channel_state_t)pdev->sh_info->aer_op.err;
  
 -      /*If a pci_conf op is in progress,
 -              we have to wait until it is done before service aer op*/
 +      /*
 +       * If a pci_conf op is in progress, we have to wait until it is done
 +       * before service aer op
 +       */
        dev_dbg(&pdev->xdev->dev,
                "pcifront service aer bus %x devfn %x\n",
                pdev->sh_info->aer_op.bus, pdev->sh_info->aer_op.devfn);
  static irqreturn_t pcifront_handler_aer(int irq, void *dev)
  {
        struct pcifront_device *pdev = dev;
 +
        schedule_pcifront_aer_op(pdev);
        return IRQ_HANDLED;
  }
@@@ -699,7 -693,7 +699,7 @@@ static int pcifront_connect_and_init_dm
  
        spin_unlock(&pcifront_dev_lock);
  
-       if (!err && !is_swiotlb_active()) {
+       if (!err && !is_swiotlb_active(&pdev->xdev->dev)) {
                err = pci_xen_swiotlb_init_late();
                if (err)
                        dev_err(&pdev->xdev->dev, "Could not setup SWIOTLB!\n");
@@@ -1033,7 -1027,6 +1033,7 @@@ static int pcifront_detach_devices(stru
        /* Find devices being detached and remove them. */
        for (i = 0; i < num_devs; i++) {
                int l, state;
 +
                l = snprintf(str, sizeof(str), "state-%d", i);
                if (unlikely(l >= (sizeof(str) - 1))) {
                        err = -ENOMEM;
@@@ -1085,7 -1078,7 +1085,7 @@@ out
        return err;
  }
  
 -static void __ref pcifront_backend_changed(struct xenbus_device *xdev,
 +static void pcifront_backend_changed(struct xenbus_device *xdev,
                                                  enum xenbus_state be_state)
  {
        struct pcifront_device *pdev = dev_get_drvdata(&xdev->dev);
@@@ -1144,7 -1137,6 +1144,7 @@@ out
  static int pcifront_xenbus_remove(struct xenbus_device *xdev)
  {
        struct pcifront_device *pdev = dev_get_drvdata(&xdev->dev);
 +
        if (pdev)
                free_pdev(pdev);
  
@@@ -100,7 -100,7 +100,7 @@@ static int is_xen_swiotlb_buffer(struc
         * in our domain. Therefore _only_ check address within our domain.
         */
        if (pfn_valid(PFN_DOWN(paddr)))
-               return is_swiotlb_buffer(paddr);
+               return is_swiotlb_buffer(dev, paddr);
        return 0;
  }
  
@@@ -164,7 -164,7 +164,7 @@@ int __ref xen_swiotlb_init(void
        int rc = -ENOMEM;
        char *start;
  
-       if (io_tlb_default_mem != NULL) {
+       if (io_tlb_default_mem.nslabs) {
                pr_warn("swiotlb buffer already initialized\n");
                return -EEXIST;
        }
@@@ -374,7 -374,7 +374,7 @@@ static dma_addr_t xen_swiotlb_map_page(
        if (dma_capable(dev, dev_addr, size, true) &&
            !range_straddles_page_boundary(phys, size) &&
                !xen_arch_need_swiotlb(dev, phys, dev_addr) &&
-               swiotlb_force != SWIOTLB_FORCE)
+               !is_swiotlb_force_bounce(dev))
                goto done;
  
        /*
@@@ -509,7 -509,7 +509,7 @@@ xen_swiotlb_map_sg(struct device *dev, 
  out_unmap:
        xen_swiotlb_unmap_sg(dev, sgl, i, dir, attrs | DMA_ATTR_SKIP_CPU_SYNC);
        sg_dma_len(sgl) = 0;
 -      return 0;
 +      return -EIO;
  }
  
  static void
@@@ -547,7 -547,7 +547,7 @@@ xen_swiotlb_sync_sg_for_device(struct d
  static int
  xen_swiotlb_dma_supported(struct device *hwdev, u64 mask)
  {
-       return xen_phys_to_dma(hwdev, io_tlb_default_mem->end - 1) <= mask;
+       return xen_phys_to_dma(hwdev, io_tlb_default_mem.end - 1) <= mask;
  }
  
  const struct dma_map_ops xen_swiotlb_dma_ops = {
diff --combined include/linux/device.h
@@@ -407,7 -407,6 +407,7 @@@ struct dev_links_info 
   * @em_pd:    device's energy model performance domain
   * @pins:     For device pin management.
   *            See Documentation/driver-api/pin-control.rst for details.
 + * @msi_lock: Lock to protect MSI mask cache and mask register
   * @msi_list: Hosts MSI descriptors
   * @msi_domain: The generic MSI domain this device is using.
   * @numa_node:        NUMA node this device is close to.
   * @dma_pools:        Dma pools (if dma'ble device).
   * @dma_mem:  Internal for coherent mem override.
   * @cma_area: Contiguous memory area for dma allocations
+  * @dma_io_tlb_mem: Pointer to the swiotlb pool used.  Not for driver use.
   * @archdata: For arch-specific additions.
   * @of_node:  Associated device tree node.
   * @fwnode:   Associated device node supplied by platform firmware.
@@@ -507,7 -507,6 +508,7 @@@ struct device 
        struct dev_pin_info     *pins;
  #endif
  #ifdef CONFIG_GENERIC_MSI_IRQ
 +      raw_spinlock_t          msi_lock;
        struct list_head        msi_list;
  #endif
  #ifdef CONFIG_DMA_OPS
  #ifdef CONFIG_DMA_CMA
        struct cma *cma_area;           /* contiguous memory area for dma
                                           allocations */
+ #endif
+ #ifdef CONFIG_SWIOTLB
+       struct io_tlb_mem *dma_io_tlb_mem;
  #endif
        /* arch specific additions */
        struct dev_archdata     archdata;
diff --combined kernel/dma/Kconfig
@@@ -80,6 -80,19 +80,19 @@@ config SWIOTL
        bool
        select NEED_DMA_MAP_STATE
  
+ config DMA_RESTRICTED_POOL
+       bool "DMA Restricted Pool"
+       depends on OF && OF_RESERVED_MEM && SWIOTLB
+       help
+         This enables support for restricted DMA pools which provide a level of
+         DMA memory protection on systems with limited hardware protection
+         capabilities, such as those lacking an IOMMU.
+         For more information see
+         <Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt>
+         and <kernel/dma/swiotlb.c>.
+         If unsure, say "n".
  #
  # Should be selected if we can mmap non-coherent mappings to userspace.
  # The only thing that is really required is a way to set an uncached bit
@@@ -93,10 -106,6 +106,10 @@@ config DMA_COHERENT_POO
        select GENERIC_ALLOCATOR
        bool
  
 +config DMA_GLOBAL_POOL
 +      select DMA_DECLARE_COHERENT
 +      bool
 +
  config DMA_REMAP
        bool
        depends on MMU
diff --combined kernel/dma/direct.c
@@@ -75,6 -75,15 +75,15 @@@ static bool dma_coherent_ok(struct devi
                min_not_zero(dev->coherent_dma_mask, dev->bus_dma_limit);
  }
  
+ static void __dma_direct_free_pages(struct device *dev, struct page *page,
+                                   size_t size)
+ {
+       if (IS_ENABLED(CONFIG_DMA_RESTRICTED_POOL) &&
+           swiotlb_free(dev, page, size))
+               return;
+       dma_free_contiguous(dev, page, size);
+ }
  static struct page *__dma_direct_alloc_pages(struct device *dev, size_t size,
                gfp_t gfp)
  {
  
        gfp |= dma_direct_optimal_gfp_mask(dev, dev->coherent_dma_mask,
                                           &phys_limit);
+       if (IS_ENABLED(CONFIG_DMA_RESTRICTED_POOL) &&
+           is_swiotlb_for_alloc(dev)) {
+               page = swiotlb_alloc(dev, size);
+               if (page && !dma_coherent_ok(dev, page_to_phys(page), size)) {
+                       __dma_direct_free_pages(dev, page, size);
+                       return NULL;
+               }
+               return page;
+       }
        page = dma_alloc_contiguous(dev, size, gfp);
        if (page && !dma_coherent_ok(dev, page_to_phys(page), size)) {
                dma_free_contiguous(dev, page, size);
@@@ -142,7 -161,7 +161,7 @@@ void *dma_direct_alloc(struct device *d
                gfp |= __GFP_NOWARN;
  
        if ((attrs & DMA_ATTR_NO_KERNEL_MAPPING) &&
-           !force_dma_unencrypted(dev)) {
+           !force_dma_unencrypted(dev) && !is_swiotlb_for_alloc(dev)) {
                page = __dma_direct_alloc_pages(dev, size, gfp & ~__GFP_ZERO);
                if (!page)
                        return NULL;
        }
  
        if (!IS_ENABLED(CONFIG_ARCH_HAS_DMA_SET_UNCACHED) &&
 -          !IS_ENABLED(CONFIG_DMA_DIRECT_REMAP) && !dev_is_dma_coherent(dev) &&
 +          !IS_ENABLED(CONFIG_DMA_DIRECT_REMAP) &&
 +          !IS_ENABLED(CONFIG_DMA_GLOBAL_POOL) &&
-           !dev_is_dma_coherent(dev))
++          !dev_is_dma_coherent(dev) &&
+           !is_swiotlb_for_alloc(dev))
                return arch_dma_alloc(dev, size, dma_handle, gfp, attrs);
  
 +      if (IS_ENABLED(CONFIG_DMA_GLOBAL_POOL) &&
 +          !dev_is_dma_coherent(dev))
 +              return dma_alloc_from_global_coherent(dev, size, dma_handle);
 +
        /*
         * Remapping or decrypting memory may block. If either is required and
         * we can't block, allocate the memory from the atomic pools.
+        * If restricted DMA (i.e., is_swiotlb_for_alloc) is required, one must
+        * set up another device coherent pool by shared-dma-pool and use
+        * dma_alloc_from_dev_coherent instead.
         */
        if (IS_ENABLED(CONFIG_DMA_COHERENT_POOL) &&
            !gfpflags_allow_blocking(gfp) &&
            (force_dma_unencrypted(dev) ||
-            (IS_ENABLED(CONFIG_DMA_DIRECT_REMAP) && !dev_is_dma_coherent(dev))))
+            (IS_ENABLED(CONFIG_DMA_DIRECT_REMAP) &&
+             !dev_is_dma_coherent(dev))) &&
+           !is_swiotlb_for_alloc(dev))
                return dma_direct_alloc_from_pool(dev, size, dma_handle, gfp);
  
        /* we always manually zero the memory once we are done */
@@@ -242,7 -261,7 +267,7 @@@ out_encrypt_pages
                        return NULL;
        }
  out_free_pages:
-       dma_free_contiguous(dev, page, size);
+       __dma_direct_free_pages(dev, page, size);
        return NULL;
  }
  
@@@ -252,27 -271,19 +277,28 @@@ void dma_direct_free(struct device *dev
        unsigned int page_order = get_order(size);
  
        if ((attrs & DMA_ATTR_NO_KERNEL_MAPPING) &&
-           !force_dma_unencrypted(dev)) {
+           !force_dma_unencrypted(dev) && !is_swiotlb_for_alloc(dev)) {
                /* cpu_addr is a struct page cookie, not a kernel address */
                dma_free_contiguous(dev, cpu_addr, size);
                return;
        }
  
        if (!IS_ENABLED(CONFIG_ARCH_HAS_DMA_SET_UNCACHED) &&
 -          !IS_ENABLED(CONFIG_DMA_DIRECT_REMAP) && !dev_is_dma_coherent(dev) &&
 +          !IS_ENABLED(CONFIG_DMA_DIRECT_REMAP) &&
 +          !IS_ENABLED(CONFIG_DMA_GLOBAL_POOL) &&
-           !dev_is_dma_coherent(dev)) {
++          !dev_is_dma_coherent(dev) &&
+           !is_swiotlb_for_alloc(dev)) {
                arch_dma_free(dev, size, cpu_addr, dma_addr, attrs);
                return;
        }
  
 +      if (IS_ENABLED(CONFIG_DMA_GLOBAL_POOL) &&
 +          !dev_is_dma_coherent(dev)) {
 +              if (!dma_release_from_global_coherent(page_order, cpu_addr))
 +                      WARN_ON_ONCE(1);
 +              return;
 +      }
 +
        /* If cpu_addr is not from an atomic pool, dma_free_from_pool() fails */
        if (IS_ENABLED(CONFIG_DMA_COHERENT_POOL) &&
            dma_free_from_pool(dev, cpu_addr, PAGE_ALIGN(size)))
        else if (IS_ENABLED(CONFIG_ARCH_HAS_DMA_CLEAR_UNCACHED))
                arch_dma_clear_uncached(cpu_addr, size);
  
-       dma_free_contiguous(dev, dma_direct_to_page(dev, dma_addr), size);
+       __dma_direct_free_pages(dev, dma_direct_to_page(dev, dma_addr), size);
  }
  
  struct page *dma_direct_alloc_pages(struct device *dev, size_t size,
        void *ret;
  
        if (IS_ENABLED(CONFIG_DMA_COHERENT_POOL) &&
-           force_dma_unencrypted(dev) && !gfpflags_allow_blocking(gfp))
+           force_dma_unencrypted(dev) && !gfpflags_allow_blocking(gfp) &&
+           !is_swiotlb_for_alloc(dev))
                return dma_direct_alloc_from_pool(dev, size, dma_handle, gfp);
  
        page = __dma_direct_alloc_pages(dev, size, gfp);
        *dma_handle = phys_to_dma_direct(dev, page_to_phys(page));
        return page;
  out_free_pages:
-       dma_free_contiguous(dev, page, size);
+       __dma_direct_free_pages(dev, page, size);
        return NULL;
  }
  
@@@ -342,7 -354,7 +369,7 @@@ void dma_direct_free_pages(struct devic
        if (force_dma_unencrypted(dev))
                set_memory_encrypted((unsigned long)vaddr, 1 << page_order);
  
-       dma_free_contiguous(dev, page, size);
+       __dma_direct_free_pages(dev, page, size);
  }
  
  #if defined(CONFIG_ARCH_HAS_SYNC_DMA_FOR_DEVICE) || \
@@@ -356,7 -368,7 +383,7 @@@ void dma_direct_sync_sg_for_device(stru
        for_each_sg(sgl, sg, nents, i) {
                phys_addr_t paddr = dma_to_phys(dev, sg_dma_address(sg));
  
-               if (unlikely(is_swiotlb_buffer(paddr)))
+               if (unlikely(is_swiotlb_buffer(dev, paddr)))
                        swiotlb_sync_single_for_device(dev, paddr, sg->length,
                                                       dir);
  
@@@ -382,7 -394,7 +409,7 @@@ void dma_direct_sync_sg_for_cpu(struct 
                if (!dev_is_dma_coherent(dev))
                        arch_sync_dma_for_cpu(paddr, sg->length, dir);
  
-               if (unlikely(is_swiotlb_buffer(paddr)))
+               if (unlikely(is_swiotlb_buffer(dev, paddr)))
                        swiotlb_sync_single_for_cpu(dev, paddr, sg->length,
                                                    dir);
  
@@@ -424,7 -436,7 +451,7 @@@ int dma_direct_map_sg(struct device *de
  
  out_unmap:
        dma_direct_unmap_sg(dev, sgl, i, dir, attrs | DMA_ATTR_SKIP_CPU_SYNC);
 -      return 0;
 +      return -EIO;
  }
  
  dma_addr_t dma_direct_map_resource(struct device *dev, phys_addr_t paddr,
@@@ -475,8 -487,6 +502,8 @@@ int dma_direct_mmap(struct device *dev
  
        if (dma_mmap_from_dev_coherent(dev, vma, cpu_addr, size, &ret))
                return ret;
 +      if (dma_mmap_from_global_coherent(vma, cpu_addr, size, &ret))
 +              return ret;
  
        if (vma->vm_pgoff >= count || user_count > count - vma->vm_pgoff)
                return -ENXIO;
@@@ -510,8 -520,8 +537,8 @@@ int dma_direct_supported(struct device 
  size_t dma_direct_max_mapping_size(struct device *dev)
  {
        /* If SWIOTLB is active, use its maximum mapping size */
-       if (is_swiotlb_active() &&
-           (dma_addressing_limited(dev) || swiotlb_force == SWIOTLB_FORCE))
+       if (is_swiotlb_active(dev) &&
+           (dma_addressing_limited(dev) || is_swiotlb_force_bounce(dev)))
                return swiotlb_max_mapping_size(dev);
        return SIZE_MAX;
  }
  bool dma_direct_need_sync(struct device *dev, dma_addr_t dma_addr)
  {
        return !dev_is_dma_coherent(dev) ||
-               is_swiotlb_buffer(dma_to_phys(dev, dma_addr));
+              is_swiotlb_buffer(dev, dma_to_phys(dev, dma_addr));
  }
  
  /**