Linux RDMA and InfiniBand development
 help / color / mirror / Atom feed
* [PATCH 00/26] DMA-buf mapping types
@ 2026-10-26  5:35 Alistair Popple
  2026-10-26  5:35 ` [PATCH 01/26] dma-buf: Introduce " Alistair Popple
                   ` (25 more replies)
  0 siblings, 26 replies; 71+ messages in thread
From: Alistair Popple @ 2026-10-26  5:35 UTC (permalink / raw)
  To: dri-devel, christian.koenig, sumit.semwal, jgg
  Cc: Alistair Popple, Thomas Hellström, Simona Vetter,
	Matthew Brost, Vivek Kasireddy, Dongwon Kim, Leon Romanovsky,
	Kevin Tian, Xu Yilun, Karl Mehltretter, Baolu Lu, Felix Kuehling,
	Alex Deucher, intel-xe, amd-gfx, linux-media, linaro-mm-sig,
	linux-rdma, iommu, Alexey Kardashevskiy, zhipingz, treding,
	jhubbard

This is the next version of Jason's DMA-buf mapping types series [1]. It keeps
the framework and the SGT conversions from the RFC but defers the final mapping
type selection until the first pin/map of the buffer.

At pin/map the exporter chooses one of the types matched, taking the other
attachments and the buffer's placement into account. That choice is held by the
core until the exporter explicitly invalidates the attachment. This ensures
unmap/remap cannot cause buffer movement and ping/pong.

Future work will build on top of this series to add an iommufd importer type
per the plan in [2], separate out PCIe P2P as its own mapping type and convert
XGMI to an exclusive mapping type.

Why mapping types
-----------------

Since its introduction, DMA-buf has only supported using scatterlist for
the exporter and importer to exchange address information.  This is not
sufficient for all use cases as dma_addr_t is a very specific and limited
type that should not be abused for things unrelated to the DMA API.

There are several motivations for addressing this now:
 1) VFIO to IOMMUFD and KVM requires a physical address, not a dma_addr_t
    scatterlist, it cannot be represented in the scatterlist structure
 2) xe vGPU requires the host driver to accept a DMABUF from VFIO of its
    own VF and convert it into an internal VRAM address on the PF
 3) We are starting to look at replacement datastructures for
    scatterlist
 4) Ideas around UALink/etc are suggesting not using the DMA API
 5) Private interconnects, such as XGMI, are forced to work around this using
    driver-specific hacks.

None of these can be achieved using scatterlist. This series introduces a
"mapping type" mechanism allowing dma-buf to negotiate compatibility between
different types and support alternate mapping options. See the description of
patch 1 for more details.

Selecting mapping type
----------------------

Importers and exporters list possible mapping types with the exporter
responsible for selecting the final type at pin/map time under the dma_resv
lock. A matching phase at attachment time eliminates types which statically
cannot be supported for a given exporter/importer.

This was done in response to review comments on the RFC. Karl found that the
RFC's match callback ran on an uninitialised attachment [3]. Christian noted
that the final decision has to be made under the dma_resv lock before a
mapping is created, not at attach [4], and Thomas proposed the three steps
followed here: agree the possible types at attach, select at map, hold the
selection until invalidate_mappings() [5]. Christian also noted that remaps
must not change type or placement as that makes buffers ping/pong [6].

The dma-buf core enforces that last point by calling select_mapping() only on
the first pin/map after attach or after an invalidate. The pin/map type can
therefore only change once the exporter has explicitly invalidated the mapping.

Jason noted that some hardware, mlx5 for example, cannot change path once it
has mapped [7]. A pinned importer is covered, since its type is fixed at pin.
An unpinned importer has no way yet to narrow its own set after an invalidate.
This could be resolved if required by introducing a pin operation done under the
dma_resv lock for the mapping selection after attach.

Future work
-----------

This series stops at the SGT type so that the framework and the
attach/pin/map contract can be reviewed on their own. I already have
proof-of-concept conversions of both PCIe P2P (building on Thomas's work [8])
and XGMI to separate mapping types. If those would be helpful for reviewing
this series let me know and I will post them.

Alternatively this series could be split up with patches 1-8 & 25-26 adding the
general framework and the rest adding the conversions later.

Further work, per [2], is an iommufd importer type to replace the private
vfio/iommufd interface and allow other DMA-bufs to be imported into iommufd.

Testing
-------

- KUnit dma-buf-mapping suite (patches 25 and 26).
- Compile-tested with a config enabling all converted drivers.

Changes since RFC v1 [1]
------------------------

- Dropped the PAL type and its vfio/iommufd users (RFC 21-25).
- Rebased onto v7.3-rc5: move_notify is now invalidate_mappings,
  CONFIG_DMABUF_MOVE_NOTIFY is gone, new amdxdna/panfrost/panthor
  exporters converted, kzalloc_obj().
- Patch 1 records the whole match set in a fixed-size array in the
  attachment; patch 3 initialises the attachment before match_mapping()
  (Karl); patch 15 holds a pci_dev reference instead of asserting the resv
  lock (Baolu).
- New patches 5, 6 and 7: exporter selection at pin/map with core-enforced
  stickiness, match set queries, and dma_buf_mapping_map()/unmap().
- xe and amdgpu conversions written against the final API; amdgpu's XGMI
  override rewrites the recorded match set entry.
- New patch 26 with KUnit tests for the selection contract.

[1] https://lore.kernel.org/all/0-v1-b5cab63049c0+191af-dmabuf_map_type_jgg@nvidia.com/
[2] https://lore.kernel.org/all/20260422150000.GK3199414@nvidia.com/
[3] https://lore.kernel.org/all/20261016202653.97339-1-kmehltretter@gmail.com/
[4] https://lore.kernel.org/all/d08a26ed-ded7-4447-bf7b-88597ee7df0e@amd.com/
[5] https://lore.kernel.org/all/8d4cb20b70ac4c3f36d8d631769757158af2ac8e.camel@linux.intel.com/
[6] https://lore.kernel.org/all/7b4dc988-5dbd-40e4-b17a-47b6eaf4bf81@amd.com/
[7] https://lore.kernel.org/all/20261022115239.GY3008132@nvidia.com/
[8] https://gitlab.freedesktop.org/thomash/xe-vibe/-/commit/7452df0fc858a7dc5ccac0e2037852cb7ab64d61

Cc: Jason Gunthorpe <jgg@nvidia.com>
Cc: Christian König <christian.koenig@amd.com>
Cc: Sumit Semwal <sumit.semwal@linaro.org>
Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com>
Cc: Simona Vetter <simona.vetter@ffwll.ch>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: Vivek Kasireddy <vivek.kasireddy@intel.com>
Cc: Dongwon Kim <dongwon.kim@intel.com>
Cc: Leon Romanovsky <leonro@nvidia.com>
Cc: Kevin Tian <kevin.tian@intel.com>
Cc: Xu Yilun <yilun.xu@linux.intel.com>
Cc: Karl Mehltretter <kmehltretter@gmail.com>
Cc: Baolu Lu <baolu.lu@linux.intel.com>
Cc: Felix Kuehling <felix.kuehling@amd.com>
Cc: Alex Deucher <alexander.deucher@amd.com>
Cc: dri-devel@lists.freedesktop.org
Cc: intel-xe@lists.freedesktop.org
Cc: amd-gfx@lists.freedesktop.org
Cc: linux-media@vger.kernel.org
Cc: linaro-mm-sig@lists.linaro.org
Cc: linux-rdma@vger.kernel.org
Cc: iommu@lists.linux.dev
Cc: Alexey Kardashevskiy <aik@amd.com>
Cc: zhipingz@meta.com
Cc: treding@nvidia.com
Cc: jhubbard@nvidia.com

Alistair Popple (4):
  dma-buf: Let the exporter select mapping type at pin/map
  dma-buf: Add match set queries for exporter placement decisions
  dma-buf: Add dma_buf_mapping_map() returning a type-tagged mapping
  dma-buf: Add kunit tests for mapping type selection

Jason Gunthorpe (22):
  dma-buf: Introduce DMA-buf mapping types
  dma-buf: Add the SGT DMA mapping type
  dma-buf: Add dma_buf_mapping_attach()
  dma-buf: Route SGT related actions through attach->map_type
  dma-buf: Allow single exporter drivers to avoid the match_mapping
    function
  drm: Check the SGT ops for drm_gem_map_dma_buf()
  dma-buf: Convert all the simple exporters to use SGT mapping type
  drm/vmwgfx: Use match_mapping instead of dummy calls
  accel/habanalabs: Use the SGT_P2P mapping type
  drm/xe/dma-buf: Use the SGT mapping type
  drm/amdgpu: Use the SGT mapping type
  vfio/pci: Change the DMA-buf exporter to use mapping_type
  RDMA/uverbs: Use the SGT_P2P mapping type
  dma-buf: Update dma_buf_phys_vec_to_sgt() to use the SGT mapping type
  iio: buffer: convert to use the SGT mapping type
  functionfs: convert to use the SGT mapping type
  dma-buf: Remove unused SGT stuff from the common structures
  treewide: Rename dma_buf_map_attachment(_unlocked) to dma_buf_sgt_
  treewide: Rename dma_buf_unmap_attachment(_unlocked) to dma_buf_sgt_*
  treewide: Rename dma_buf_attach() to dma_buf_sgt_attach()
  treewide: Rename dma_buf_dynamic_attach() to
    dma_buf_sgt_dynamic_attach()
  dma-buf: Add kunit tests for mapping type

 Documentation/gpu/todo.rst                    |   2 +-
 drivers/accel/amdxdna/amdxdna_cbuf.c          |   8 +-
 drivers/accel/amdxdna/amdxdna_gem.c           |  14 +-
 drivers/accel/amdxdna/amdxdna_ubuf.c          |   8 +-
 drivers/accel/habanalabs/common/memory.c      |  54 +-
 drivers/accel/ivpu/ivpu_gem.c                 |  10 +-
 drivers/accel/ivpu/ivpu_gem_userptr.c         |  11 +-
 drivers/accel/qaic/qaic_data.c                |   8 +-
 drivers/dma-buf/Makefile                      |   1 +
 drivers/dma-buf/dma-buf-mapping.c             | 259 ++++++-
 drivers/dma-buf/dma-buf.c                     | 317 ++++++---
 drivers/dma-buf/heaps/cma_heap.c              |  12 +-
 drivers/dma-buf/heaps/system_heap.c           |  13 +-
 drivers/dma-buf/st-dma-mapping.c              | 662 ++++++++++++++++++
 drivers/dma-buf/udmabuf.c                     |   8 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c   | 141 ++--
 drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c       |   6 +-
 drivers/gpu/drm/armada/armada_gem.c           |  33 +-
 drivers/gpu/drm/drm_gem_shmem_helper.c        |   2 +-
 drivers/gpu/drm/drm_prime.c                   |  31 +-
 drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c    |  18 +-
 drivers/gpu/drm/i915/gem/i915_gem_object.c    |   2 +-
 .../drm/i915/gem/selftests/i915_gem_dmabuf.c  |   8 +-
 .../gpu/drm/i915/gem/selftests/mock_dmabuf.c  |   8 +-
 drivers/gpu/drm/msm/msm_gem_prime.c           |   7 +-
 drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c     |  11 +-
 drivers/gpu/drm/panfrost/panfrost_gem.c       |  13 +-
 drivers/gpu/drm/panthor/panthor_gem.c         |  11 +-
 drivers/gpu/drm/tegra/gem.c                   |  33 +-
 drivers/gpu/drm/virtio/virtgpu_prime.c        |  23 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_prime.c         |  32 +-
 drivers/gpu/drm/xe/xe_bo.c                    |  18 +-
 drivers/gpu/drm/xe/xe_dma_buf.c               |  64 +-
 drivers/iio/industrialio-buffer.c             |  15 +-
 drivers/infiniband/core/umem_dmabuf.c         |  15 +-
 .../infiniband/core/uverbs_std_types_dmabuf.c |  30 +-
 drivers/iommu/iommufd/pages.c                 |   5 +-
 drivers/iommu/iommufd/selftest.c              |  18 +-
 .../media/common/videobuf2/videobuf2-core.c   |   2 +-
 .../common/videobuf2/videobuf2-dma-contig.c   |  26 +-
 .../media/common/videobuf2/videobuf2-dma-sg.c |  21 +-
 .../common/videobuf2/videobuf2-vmalloc.c      |  13 +-
 .../platform/nvidia/tegra-vde/dmabuf-cache.c  |   9 +-
 drivers/misc/fastrpc.c                        |  21 +-
 drivers/tee/tee_heap.c                        |  13 +-
 drivers/usb/gadget/function/f_fs.c            |  11 +-
 drivers/vfio/pci/vfio_pci_dmabuf.c            |  25 +-
 drivers/xen/gntdev-dmabuf.c                   |  29 +-
 include/linux/dma-buf-mapping.h               | 370 ++++++++++
 include/linux/dma-buf.h                       | 227 +++---
 include/trace/events/dma_buf.h                |   2 +-
 io_uring/zcrx.c                               |   9 +-
 net/core/devmem.c                             |  14 +-
 samples/vfio-mdev/mbochs.c                    |  10 +-
 sound/soc/fsl/fsl_asrc_m2m.c                  |  12 +-
 55 files changed, 2163 insertions(+), 582 deletions(-)
 create mode 100644 drivers/dma-buf/st-dma-mapping.c


base-commit: 72d3fcf802c45d00b300f25b848a93c3a2bd7c7e
-- 
2.54.0


^ permalink raw reply	[flat|nested] 71+ messages in thread

* [PATCH 01/26] dma-buf: Introduce DMA-buf mapping types
  2026-10-26  5:35 [PATCH 00/26] DMA-buf mapping types Alistair Popple
@ 2026-10-26  5:35 ` Alistair Popple
  2026-10-26  7:00   ` sashiko-bot
  2026-10-26  5:35 ` [PATCH 02/26] dma-buf: Add the SGT DMA mapping type Alistair Popple
                   ` (24 subsequent siblings)
  25 siblings, 1 reply; 71+ messages in thread
From: Alistair Popple @ 2026-10-26  5:35 UTC (permalink / raw)
  To: dri-devel, christian.koenig, sumit.semwal, jgg
  Cc: Alistair Popple, Thomas Hellström, Simona Vetter,
	Matthew Brost, Vivek Kasireddy, Dongwon Kim, Leon Romanovsky,
	Kevin Tian, Xu Yilun, Karl Mehltretter, Baolu Lu, Felix Kuehling,
	Alex Deucher, intel-xe, amd-gfx, linux-media, linaro-mm-sig,
	linux-rdma, iommu, Alexey Kardashevskiy, zhipingz, treding,
	jhubbard

From: Jason Gunthorpe <jgg@nvidia.com>

DMA-buf mapping types allow the importer and exporter to negotiate the
format of the map/unmap to be used during the attachment.

Currently DMA-buf only supports struct scatterlist as the attachment map
operation.  This is not sufficient for all use cases as dma_addr_t is a
very specific and limited type.

With mapping types the importing driver can declare what it supports. For
example:

	struct dma_buf_mapping_match imp_match[] = {
		DMA_BUF_IMAPPING_MY_DRIVER(dev, ...),
		DMA_BUF_IMAPPING_SGT(dev, false),
	};
	attach = dma_buf_mapping_attach(dmabuf, imp_match, ...)

And the exporting driver can declare what it supports:

int exporter_match_mapping(struct dma_buf_match_args *args)
{
	struct dma_buf_mapping_match exp_match[] = {
		DMA_BUF_EMAPPING_MY_DRIVER(my_ops, dev, ...),
		DMA_BUF_EMAPPING_SGT(sgt_ops, dev, false),
		DMA_BUF_EMAPPING_PAL(PAL_ops),
	};
	return dma_buf_match_mapping(args, exp_match, ...);
}

During dma_buf_mapping_attach() the core code records every mutually
acceptable (exporter entry, importer entry) pair in attach->matches, a
small fixed-size array in the attachment, in the exporter's order of
preference. The first entry is the default and is what attach->map_type
holds; later patches let the exporter choose a different entry of the set
at pin or map time, when the buffer's placement and the other attachments
are known. Importers and exporters that list a single type see exactly one
entry.

Add the basic types:

struct dma_buf_mapping_type
   Type tag and ops for each mapping type.

struct dma_buf_mapping_match
   Entry in a list of importer or exporter match specifications.
   The match specification can be extended by the mapping type with
   unique data.

dma_buf_match_mapping() / struct dma_buf_match_args
   Helper to do the matching. Called by the exporting driver
   via a dma_buf_ops callback.

struct dma_buf_mapping_exp_ops
   Base type for the per-mapping type exporter provided functions. This
   would be the map/unmap callbacks. Each mapping type can provide its own
   functions for map/unmap type operations with optimal type signatures.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
[ dma_buf_match_mapping() records the whole match set in
  attach->matches instead of stopping at the first match, so that the
  exporter can choose among the mutually acceptable types later, at pin or
  map time, rather than the core fixing one type at attach. - apopple ]
Co-developed-by: Alistair Popple <apopple@nvidia.com>
Signed-off-by: Alistair Popple <apopple@nvidia.com>
---
 drivers/dma-buf/dma-buf-mapping.c | 62 +++++++++++++++++++++++++
 include/linux/dma-buf-mapping.h   | 76 +++++++++++++++++++++++++++++++
 include/linux/dma-buf.h           | 31 +++++++++++++
 3 files changed, 169 insertions(+)

diff --git a/drivers/dma-buf/dma-buf-mapping.c b/drivers/dma-buf/dma-buf-mapping.c
index 833be519e1e6..616ab057fb28 100644
--- a/drivers/dma-buf/dma-buf-mapping.c
+++ b/drivers/dma-buf/dma-buf-mapping.c
@@ -5,6 +5,7 @@
  */
 #include <linux/dma-buf-mapping.h>
 #include <linux/dma-resv.h>
+#include <linux/dma-buf.h>
 #include <linux/overflow.h>
 #include <linux/align.h>
 
@@ -257,3 +258,64 @@ void dma_buf_free_sgt(struct dma_buf_attachment *attach, struct sg_table *sgt,
 
 }
 EXPORT_SYMBOL_NS_GPL(dma_buf_free_sgt, "DMA_BUF");
+
+/**
+ * dma_buf_match_mapping - Record the mapping types agreed upon by exporter
+ *                         and importer
+ * @args: Match arguments from attach
+ * @exp: Array of mapping types supported by the exporter, in priority order
+ * @exp_len: Number of entries in @exp
+ *
+ * Walk the exporter's list in order and, for each entry, find the first
+ * importer entry of the same type that the type's match() callback accepts.
+ * Every such pair is recorded in @args->attach->matches, so the match set
+ * preserves the exporter's priority. The first entry becomes the default in
+ * @args->attach->map_type.
+ *
+ * Because the exporter list is walked in order, the exporter controls the
+ * priority of mapping types.
+ *
+ * Returns: 0 if at least one type matched, -EINVAL if none did, -E2BIG if
+ * more than DMA_BUF_MAX_MATCHES types matched, or the error a match() callback
+ * aborted the search with.
+ */
+int dma_buf_match_mapping(struct dma_buf_match_args *args,
+			  const struct dma_buf_mapping_match *exp,
+			  size_t exp_len)
+{
+	const struct dma_buf_mapping_match *exp_end = exp + exp_len;
+	const struct dma_buf_mapping_match *imp_end =
+		args->imp_matches + args->imp_len;
+	struct dma_buf_attachment *attach = args->attach;
+	unsigned int nr = 0;
+	int ret;
+
+	for (; exp != exp_end; exp++) {
+		const struct dma_buf_mapping_match *imp = args->imp_matches;
+
+		for (; imp != imp_end; imp++) {
+			if (exp->type != imp->type)
+				continue;
+			if (exp->type->match) {
+				ret = exp->type->match(args->dmabuf, exp, imp);
+				if (ret == -EOPNOTSUPP)
+					continue;
+				if (ret != 0)
+					return ret;
+			}
+			if (nr == ARRAY_SIZE(attach->matches))
+				return -E2BIG;
+			exp->type->finish_match(args, exp, imp);
+			attach->matches[nr++] = attach->map_type;
+			break;
+		}
+	}
+
+	if (!nr)
+		return -EINVAL;
+
+	attach->nr_matches = nr;
+	attach->map_type = attach->matches[0];
+	return 0;
+}
+EXPORT_SYMBOL_NS_GPL(dma_buf_match_mapping, "DMA_BUF");
diff --git a/include/linux/dma-buf-mapping.h b/include/linux/dma-buf-mapping.h
index 09bde3f748e4..03a03624166b 100644
--- a/include/linux/dma-buf-mapping.h
+++ b/include/linux/dma-buf-mapping.h
@@ -7,6 +7,77 @@
 #define __DMA_BUF_MAPPING_H__
 #include <linux/dma-buf.h>
 
+struct device;
+struct dma_buf;
+struct dma_buf_attachment;
+struct dma_buf_mapping_exp_ops;
+
+/* Type tag for all mapping operations */
+struct dma_buf_mapping_exp_ops {};
+
+/*
+ * Internal struct to pass arguments from the attach function to the matching
+ * function
+ */
+struct dma_buf_match_args {
+	struct dma_buf *dmabuf;
+	struct dma_buf_attachment *attach;
+	const struct dma_buf_mapping_match *imp_matches;
+	size_t imp_len;
+};
+
+/**
+ * struct dma_buf_mapping_type - Operations for a DMA-buf mapping type
+ *
+ * Each mapping type provides a singleton instance of this struct to describe
+ * the mapping type and its operations.
+ */
+struct dma_buf_mapping_type {
+	/**
+	 * @name: Human-readable name for this mapping type, used in debugfs
+	 *        output
+	 */
+	const char *name;
+
+	/**
+	 * @match:
+	 *
+	 * Called during attach from dma_buf_match_mapping(). &exp and &imp are
+	 * single items from the importer and exporter mapping match lists.
+	 * Both will have the same instance of this struct as their type member.
+	 *
+	 * It determines if the exporter/importer are compatible.
+	 *
+	 * Returns: 0 on success
+	 *   -EOPNOTSUPP means ignore the failure and continue
+	 *   Everything else aborts the search and returns the -errno
+	 */
+	int (*match)(struct dma_buf *dmabuf,
+		     const struct dma_buf_mapping_match *exp,
+		     const struct dma_buf_mapping_match *imp);
+
+	/**
+	 * @finish_match:
+	 *
+	 * Called by dma_buf_match_mapping() after a successful match to store
+	 * the negotiated result in @args->attach. The matched @exp and @imp
+	 * entries are provided so the callback can copy type-specific data into
+	 * the attachment.
+	 */
+	void (*finish_match)(struct dma_buf_match_args *args,
+			     const struct dma_buf_mapping_match *exp,
+			     const struct dma_buf_mapping_match *imp);
+
+	/**
+	 * @debugfs_dump:
+	 *
+	 * Optional callback to write mapping-type-specific diagnostic
+	 * information about @attach to the debugfs seq_file @s.
+	 */
+	void (*debugfs_dump)(struct seq_file *s,
+			     struct dma_buf_attachment *attach);
+};
+
 struct sg_table *dma_buf_phys_vec_to_sgt(struct dma_buf_attachment *attach,
 					 struct p2pdma_provider *provider,
 					 struct phys_vec *phys_vec,
@@ -14,4 +85,9 @@ struct sg_table *dma_buf_phys_vec_to_sgt(struct dma_buf_attachment *attach,
 					 enum dma_data_direction dir);
 void dma_buf_free_sgt(struct dma_buf_attachment *attach, struct sg_table *sgt,
 		      enum dma_data_direction dir);
+
+int dma_buf_match_mapping(struct dma_buf_match_args *args,
+			  const struct dma_buf_mapping_match *exp_mappings,
+			  size_t exp_len);
+
 #endif
diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h
index d15b2b31d3c9..a749562c1728 100644
--- a/include/linux/dma-buf.h
+++ b/include/linux/dma-buf.h
@@ -27,6 +27,28 @@
 struct device;
 struct dma_buf;
 struct dma_buf_attachment;
+struct dma_buf_mapping_type;
+struct dma_buf_mapping_exp_ops;
+
+/*
+ * Upper bound on the number of mapping types an attachment can record as
+ * mutually acceptable. An exporter offering more compatible types than this
+ * to one importer fails the attach with -E2BIG.
+ */
+#define DMA_BUF_MAX_MATCHES 4
+
+/*
+ * Match items are generated by the importer using the DMA_BUF_IMAPPING_*() and
+ * the exporter using the DMA_BUF_EMAPPING_*() functions. Each mapping type
+ * defines its own signature with its own data to make the match and attachment.
+ */
+struct dma_buf_mapping_match {
+	const struct dma_buf_mapping_type *type;
+	const struct dma_buf_mapping_exp_ops *exp_ops;
+	union {
+		/* Each mapping_type has unique match parameters here */
+	};
+};
 
 /**
  * struct dma_buf_ops - operations possible on struct dma_buf
@@ -472,6 +494,12 @@ struct dma_buf_attach_ops {
  * @importer_ops: importer operations for this attachment, if provided
  * dma_buf_map/unmap_attachment() must be called with the dma_resv lock held.
  * @importer_priv: importer specific attachment data.
+ * @map_type: The match this attachment is mapped with. Until the exporter
+ *            selects otherwise it holds the exporter's default, the first
+ *            entry of @matches.
+ * @matches: The match set negotiated at attach time: every mapping type both
+ *           sides accept, in the exporter's order of preference.
+ * @nr_matches: Number of valid entries in @matches.
  *
  * This structure holds the attachment information between the dma_buf buffer
  * and its user device(s). The list contains one attachment struct per device
@@ -490,6 +518,9 @@ struct dma_buf_attachment {
 	const struct dma_buf_attach_ops *importer_ops;
 	void *importer_priv;
 	void *priv;
+	struct dma_buf_mapping_match map_type;
+	struct dma_buf_mapping_match matches[DMA_BUF_MAX_MATCHES];
+	unsigned int nr_matches;
 };
 
 /**
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 71+ messages in thread

* [PATCH 02/26] dma-buf: Add the SGT DMA mapping type
  2026-10-26  5:35 [PATCH 00/26] DMA-buf mapping types Alistair Popple
  2026-10-26  5:35 ` [PATCH 01/26] dma-buf: Introduce " Alistair Popple
@ 2026-10-26  5:35 ` Alistair Popple
  2026-10-26  7:04   ` sashiko-bot
  2026-10-26  5:35 ` [PATCH 03/26] dma-buf: Add dma_buf_mapping_attach() Alistair Popple
                   ` (23 subsequent siblings)
  25 siblings, 1 reply; 71+ messages in thread
From: Alistair Popple @ 2026-10-26  5:35 UTC (permalink / raw)
  To: dri-devel, christian.koenig, sumit.semwal, jgg
  Cc: Alistair Popple, Thomas Hellström, Simona Vetter,
	Matthew Brost, Vivek Kasireddy, Dongwon Kim, Leon Romanovsky,
	Kevin Tian, Xu Yilun, Karl Mehltretter, Baolu Lu, Felix Kuehling,
	Alex Deucher, intel-xe, amd-gfx, linux-media, linaro-mm-sig,
	linux-rdma, iommu, Alexey Kardashevskiy, zhipingz, treding,
	jhubbard

From: Jason Gunthorpe <jgg@nvidia.com>

The SGT (Scatter Gather Table) DMA mapping type represents the existing
sg_table/scatterlist based DMA mapping. It provides a sg_table based
map/unmap interface that exactly matches how things work today.

dma_buf_sgt_exp_compat_match will be used in the next patch to
transparently wrap an unaware exporter with a mapping type.

The SGT type handles the allow_peer2peer flag directly through matching
logic. The importer indicates if it is willing to accept peer2peer and the
exporter indicates if it requires peer2peer. A required peer2peer exporter
will not match to an importer that does not accept peer2peer.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/dma-buf/dma-buf-mapping.c |  95 ++++++++++++++++++++++++++++
 include/linux/dma-buf-mapping.h   | 101 ++++++++++++++++++++++++++++++
 include/linux/dma-buf.h           |  18 +++++-
 3 files changed, 213 insertions(+), 1 deletion(-)

diff --git a/drivers/dma-buf/dma-buf-mapping.c b/drivers/dma-buf/dma-buf-mapping.c
index 616ab057fb28..d30c0e9ef038 100644
--- a/drivers/dma-buf/dma-buf-mapping.c
+++ b/drivers/dma-buf/dma-buf-mapping.c
@@ -6,6 +6,7 @@
 #include <linux/dma-buf-mapping.h>
 #include <linux/dma-resv.h>
 #include <linux/dma-buf.h>
+#include <linux/seq_file.h>
 #include <linux/overflow.h>
 #include <linux/align.h>
 
@@ -319,3 +320,97 @@ int dma_buf_match_mapping(struct dma_buf_match_args *args,
 	return 0;
 }
 EXPORT_SYMBOL_NS_GPL(dma_buf_match_mapping, "DMA_BUF");
+
+static int dma_buf_sgt_match(struct dma_buf *dmabuf,
+			     const struct dma_buf_mapping_match *exp,
+			     const struct dma_buf_mapping_match *imp)
+{
+	switch (exp->sgt_data.exporter_requires_p2p) {
+	case DMA_SGT_NO_P2P:
+		return 0;
+	case DMA_SGT_EXPORTER_REQUIRES_P2P_DISTANCE:
+		if (WARN_ON(!exp->sgt_data.exporting_p2p_device) ||
+		    imp->sgt_data.importer_accepts_p2p !=
+			    DMA_SGT_IMPORTER_ACCEPTS_P2P)
+			return -EOPNOTSUPP;
+		if (pci_p2pdma_distance(exp->sgt_data.exporting_p2p_device,
+					imp->sgt_data.importing_dma_device,
+					true) < 0)
+			return -EOPNOTSUPP;
+		return 0;
+	}
+	return 0;
+}
+
+static inline void
+dma_buf_sgt_finish_match(struct dma_buf_match_args *args,
+			 const struct dma_buf_mapping_match *exp,
+			 const struct dma_buf_mapping_match *imp)
+{
+	struct dma_buf_attachment *attach = args->attach;
+
+	attach->map_type = (struct dma_buf_mapping_match) {
+		.type = &dma_buf_mapping_sgt_type,
+		.exp_ops = exp->exp_ops,
+		.sgt_data = {
+			.importing_dma_device = imp->sgt_data.importing_dma_device,
+			/* exporting_p2p_device is left opaque */
+			.importer_accepts_p2p = imp->sgt_data.importer_accepts_p2p,
+			.exporter_requires_p2p = exp->sgt_data.exporter_requires_p2p,
+		},
+	};
+
+	/*
+	 * Setup the SGT type variables stored in attach because importers and
+	 * exporters that do not natively use mappings expect them to be there.
+	 * When converting to use mappings users should use the match versions
+	 * of these instead.
+	 */
+	attach->dev = imp->sgt_data.importing_dma_device;
+	attach->peer2peer = attach->map_type.sgt_data.importer_accepts_p2p ==
+			    DMA_SGT_IMPORTER_ACCEPTS_P2P;
+}
+
+static void dma_buf_sgt_debugfs_dump(struct seq_file *s,
+				     struct dma_buf_attachment *attach)
+{
+	seq_printf(s, " %s", dev_name(dma_buf_sgt_dma_device(attach)));
+}
+
+struct dma_buf_mapping_type dma_buf_mapping_sgt_type = {
+	.name = "DMA Mapped Scatter Gather Table",
+	.match = dma_buf_sgt_match,
+	.finish_match = dma_buf_sgt_finish_match,
+	.debugfs_dump = dma_buf_sgt_debugfs_dump,
+};
+EXPORT_SYMBOL_NS_GPL(dma_buf_mapping_sgt_type, "DMA_BUF");
+
+static struct sg_table *
+dma_buf_sgt_compat_map_dma_buf(struct dma_buf_attachment *attach,
+			       enum dma_data_direction dir)
+{
+	return attach->dmabuf->ops->map_dma_buf(attach, dir);
+}
+
+static void dma_buf_sgt_compat_unmap_dma_buf(struct dma_buf_attachment *attach,
+					     struct sg_table *sgt,
+					     enum dma_data_direction dir)
+{
+	attach->dmabuf->ops->unmap_dma_buf(attach, sgt, dir);
+}
+
+/* Route the classic map/unmap ops through the exp ops for old importers */
+static const struct dma_buf_mapping_sgt_exp_ops dma_buf_sgt_compat_exp_ops = {
+	.map_dma_buf = dma_buf_sgt_compat_map_dma_buf,
+	.unmap_dma_buf = dma_buf_sgt_compat_unmap_dma_buf,
+};
+
+/*
+ * This mapping type is used for unaware exporters that do not support
+ * match_mapping(). It wraps the dma_buf ops for SGT mappings into a mapping
+ * type so aware importers can transparently work with unaware exporters. This
+ * does not require p2p because old exporters will check it through the
+ * attach->peer2peer mechanism.
+ */
+const struct dma_buf_mapping_match dma_buf_sgt_exp_compat_match =
+	DMA_BUF_EMAPPING_SGT(&dma_buf_sgt_compat_exp_ops);
diff --git a/include/linux/dma-buf-mapping.h b/include/linux/dma-buf-mapping.h
index 03a03624166b..f9b749af362b 100644
--- a/include/linux/dma-buf-mapping.h
+++ b/include/linux/dma-buf-mapping.h
@@ -12,6 +12,12 @@ struct dma_buf;
 struct dma_buf_attachment;
 struct dma_buf_mapping_exp_ops;
 
+enum dma_sgt_requires_p2p {
+	DMA_SGT_NO_P2P = 0,
+	DMA_SGT_EXPORTER_REQUIRES_P2P_DISTANCE,
+	DMA_SGT_IMPORTER_ACCEPTS_P2P,
+};
+
 /* Type tag for all mapping operations */
 struct dma_buf_mapping_exp_ops {};
 
@@ -90,4 +96,99 @@ int dma_buf_match_mapping(struct dma_buf_match_args *args,
 			  const struct dma_buf_mapping_match *exp_mappings,
 			  size_t exp_len);
 
+/*
+ * DMA Mapped Scatterlist Type
+ *
+ * When this type is matched the map/unmap functions are:
+ *
+ *  dma_buf_map_attachment()
+ *  dma_buf_unmap_attachment()
+ *
+ * The struct sg_table returned by those functions has only the DMA portions
+ * available. The caller must not try to use the struct page * information.
+ *
+ * importing_dma_device is passed to the DMA API to provide the dma_addr_t's.
+ */
+extern struct dma_buf_mapping_type dma_buf_mapping_sgt_type;
+
+struct dma_buf_mapping_sgt_exp_ops {
+	struct dma_buf_mapping_exp_ops ops;
+	struct sg_table *(*map_dma_buf)(struct dma_buf_attachment *attach,
+					enum dma_data_direction dir);
+	void (*unmap_dma_buf)(struct dma_buf_attachment *attach,
+			      struct sg_table *sgt,
+			      enum dma_data_direction dir);
+};
+
+/**
+ * dma_buf_sgt_dma_device - Return the device to use for DMA mapping
+ * @attach: sgt mapping type attachment
+ *
+ * Called by the exporter to get the struct device to pass to the DMA API
+ * during map and unmap callbacks.
+ */
+static inline struct device *
+dma_buf_sgt_dma_device(struct dma_buf_attachment *attach)
+{
+	if (attach->map_type.type != &dma_buf_mapping_sgt_type)
+		return NULL;
+	return attach->map_type.sgt_data.importing_dma_device;
+}
+
+/**
+ * dma_buf_sgt_p2p_allowed - True if MMIO memory can be used peer to peer
+ * @attach: sgt mapping type attachment
+ *
+ * Should be called by exporters, returns true if the exporter's
+ * DMA_SGT_EXPORTER_REQUIRES_P2P_DISTANCE was matched.
+ */
+static inline bool dma_buf_sgt_p2p_allowed(struct dma_buf_attachment *attach)
+{
+	if (attach->map_type.type != &dma_buf_mapping_sgt_type)
+		return false;
+	return attach->map_type.sgt_data.exporter_requires_p2p ==
+	       DMA_SGT_EXPORTER_REQUIRES_P2P_DISTANCE;
+}
+
+static inline const struct dma_buf_mapping_sgt_exp_ops *
+dma_buf_get_sgt_ops(struct dma_buf_attachment *attach)
+{
+	if (attach->map_type.type != &dma_buf_mapping_sgt_type)
+		return NULL;
+	return container_of(attach->map_type.exp_ops,
+			    struct dma_buf_mapping_sgt_exp_ops, ops);
+}
+
+static inline struct dma_buf_mapping_match
+DMA_BUF_IMAPPING_SGT(struct device *importing_dma_device,
+		     enum dma_sgt_requires_p2p importer_accepts_p2p)
+{
+	return (struct dma_buf_mapping_match){
+		.type = &dma_buf_mapping_sgt_type,
+		.sgt_data = { .importing_dma_device = importing_dma_device,
+			      .importer_accepts_p2p = importer_accepts_p2p },
+	};
+}
+#define DMA_BUF_EMAPPING_SGT(_exp_ops)                                      \
+	((struct dma_buf_mapping_match){ .type = &dma_buf_mapping_sgt_type, \
+					 .exp_ops = &((_exp_ops)->ops) })
+
+/*
+ * Only matches if the importing device is P2P capable and the P2P subsystem
+ * says P2P is possible from p2p_device.
+ */
+static inline struct dma_buf_mapping_match
+DMA_BUF_EMAPPING_SGT_P2P(const struct dma_buf_mapping_sgt_exp_ops *exp_ops,
+			 struct pci_dev *p2p_device)
+{
+	struct dma_buf_mapping_match match = DMA_BUF_EMAPPING_SGT(exp_ops);
+
+	match.sgt_data.exporter_requires_p2p =
+		DMA_SGT_EXPORTER_REQUIRES_P2P_DISTANCE;
+	match.sgt_data.exporting_p2p_device = p2p_device;
+	return match;
+}
+
+extern const struct dma_buf_mapping_match dma_buf_sgt_exp_compat_match;
+
 #endif
diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h
index a749562c1728..3e82ec59d5ce 100644
--- a/include/linux/dma-buf.h
+++ b/include/linux/dma-buf.h
@@ -30,6 +30,7 @@ struct dma_buf_attachment;
 struct dma_buf_mapping_type;
 struct dma_buf_mapping_exp_ops;
 
+
 /*
  * Upper bound on the number of mapping types an attachment can record as
  * mutually acceptable. An exporter offering more compatible types than this
@@ -46,7 +47,22 @@ struct dma_buf_mapping_match {
 	const struct dma_buf_mapping_type *type;
 	const struct dma_buf_mapping_exp_ops *exp_ops;
 	union {
-		/* Each mapping_type has unique match parameters here */
+		/* For dma_buf_mapping_sgt_type */
+		struct {
+			struct device *importing_dma_device;
+			/* Only used if DMA_SGT_EXPORTER_REQUIRES_P2P_DISTANCE */
+			struct pci_dev *exporting_p2p_device;
+			/*
+			 * These p2p flags are used to support the hard coded
+			 * mechanism for p2p. If an exporting device knows it
+			 * will put MMIO into the sgt then it should set
+			 * exporter_requires_p2p. Importers should set
+			 * importer_accepts_p2p unless it is known that the
+			 * importing HW never supports P2P because of HW issues.
+			 */
+			u8 importer_accepts_p2p;
+			u8 exporter_requires_p2p;
+		} sgt_data;
 	};
 };
 
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 71+ messages in thread

* [PATCH 03/26] dma-buf: Add dma_buf_mapping_attach()
  2026-10-26  5:35 [PATCH 00/26] DMA-buf mapping types Alistair Popple
  2026-10-26  5:35 ` [PATCH 01/26] dma-buf: Introduce " Alistair Popple
  2026-10-26  5:35 ` [PATCH 02/26] dma-buf: Add the SGT DMA mapping type Alistair Popple
@ 2026-10-26  5:35 ` Alistair Popple
  2026-10-26  7:20   ` sashiko-bot
  2026-10-26  5:35 ` [PATCH 04/26] dma-buf: Route SGT related actions through attach->map_type Alistair Popple
                   ` (22 subsequent siblings)
  25 siblings, 1 reply; 71+ messages in thread
From: Alistair Popple @ 2026-10-26  5:35 UTC (permalink / raw)
  To: dri-devel, christian.koenig, sumit.semwal, jgg
  Cc: Alistair Popple, Thomas Hellström, Simona Vetter,
	Matthew Brost, Vivek Kasireddy, Dongwon Kim, Leon Romanovsky,
	Kevin Tian, Xu Yilun, Karl Mehltretter, Baolu Lu, Felix Kuehling,
	Alex Deucher, intel-xe, amd-gfx, linux-media, linaro-mm-sig,
	linux-rdma, iommu, Alexey Kardashevskiy, zhipingz, treding,
	jhubbard

From: Jason Gunthorpe <jgg@nvidia.com>

Introduce a new attach function that accepts the list of importer
supported mapping types from the caller. Turn dma_buf_dynamic_attach() and
dma_buf_attach() into simple wrappers calling this new function with a
compatibility mapping type list that only includes sgt.

dma_buf_mapping_attach() checks if the exporter is mapping aware and calls
its ops->match_mapping() function to pick up the exporter match list and
call dma_buf_match_mapping().

If unaware it will use dma_buf_sgt_exp_compat_match as a compatibility
matchlist that uses the unaware exporter's dma_buf_ops callbacks.

The resulting match set is stored in attach->matches with the first entry,
the exporter's preferred type, in attach->map_type.

In effect attach->map_type is always available and always makes sense
regardless of what combination of aware/unaware importer/exporter is used.

The attachment's importer side (dmabuf, importer_ops, importer_priv) is
initialised before match_mapping() runs so that exporters can consult it,
for example to recognise an importer driven by the same driver. The
dma_resv lock is not held at this point, so match_mapping() may only look
at properties that cannot change for the lifetime of the attachment.

For compatibility with unaware drivers copy the sgt matching data into the
attach->dev and peer2peer.

If the exporter sets exporter_requires_p2p then only the following are
allowed:
 - dma_buf_dynamic_attach() with importer_ops->allow_peer2peer = true
 - dma_buf_mapping_attach() with a
    DMA_BUF_IMAPPING_SGT(xx, exporter_requires_p2p=true)

Other combinations are blocked.

Exporters that want to behave differently based on the importer's
capability can declare exporter_requires_p2p=false and check
attach->map_type.sgt_data.importer_accepts_p2p. Or they can declare two
SGT exporters with different map/unmap functions.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
[ rebase context change due to upstream removing a WARN_ON - apopple ]
[ rebase context change due to upstream switching to kzalloc_obj() - apopple ]
[ use dma_buf_sgt_dma_device(attach) for trace points - apopple ]
[ initialise the attachment before calling match_mapping(), reported by Karl Mehltretter - apopple ]
[ kdoc updates - apopple ]
Signed-off-by: Alistair Popple <apopple@nvidia.com>
---
 drivers/dma-buf/dma-buf.c      | 103 +++++++++++++++++++++++++++------
 include/linux/dma-buf.h        |  27 +++++++++
 include/trace/events/dma_buf.h |   2 +-
 3 files changed, 112 insertions(+), 20 deletions(-)

diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c
index 4c9add51f9ef..16a7fbb8aaab 100644
--- a/drivers/dma-buf/dma-buf.c
+++ b/drivers/dma-buf/dma-buf.c
@@ -14,6 +14,7 @@
 #include <linux/fs.h>
 #include <linux/slab.h>
 #include <linux/dma-buf.h>
+#include <linux/dma-buf-mapping.h>
 #include <linux/dma-fence.h>
 #include <linux/dma-fence-unwrap.h>
 #include <linux/anon_inodes.h>
@@ -714,11 +715,19 @@ struct dma_buf *dma_buf_export(const struct dma_buf_export_info *exp_info)
 	int ret;
 
 	if (WARN_ON(!exp_info->priv || !exp_info->ops
-		    || !exp_info->ops->map_dma_buf
-		    || !exp_info->ops->unmap_dma_buf
 		    || !exp_info->ops->release))
 		return ERR_PTR(-EINVAL);
 
+	if (exp_info->ops->match_mapping) {
+		if (WARN_ON(exp_info->ops->map_dma_buf ||
+			    exp_info->ops->unmap_dma_buf))
+			return ERR_PTR(-EINVAL);
+	} else {
+		if (WARN_ON(!exp_info->ops->map_dma_buf ||
+			    !exp_info->ops->unmap_dma_buf))
+			return ERR_PTR(-EINVAL);
+	}
+
 	if (WARN_ON(!exp_info->ops->pin != !exp_info->ops->unpin))
 		return ERR_PTR(-EINVAL);
 
@@ -1007,9 +1016,10 @@ dma_buf_pin_on_map(struct dma_buf_attachment *attach)
  */
 
 /**
- * dma_buf_dynamic_attach - Add the device to dma_buf's attachments list
+ * dma_buf_mapping_attach - Add the device to dma_buf's attachments list
  * @dmabuf:		[in]	buffer to attach device to.
- * @dev:		[in]	device to be attached.
+ * @importer_matches:	[in]	mapping types supported by the importer
+ * @match_len:		[in]	length of @importer_matches
  * @importer_ops:	[in]	importer operations for the attachment
  * @importer_priv:	[in]	importer private pointer for the attachment
  *
@@ -1025,31 +1035,55 @@ dma_buf_pin_on_map(struct dma_buf_attachment *attach)
  * error code wrapped into a pointer on failure.
  *
  * Note that this can fail if the backing storage of @dmabuf is in a place not
- * accessible to @dev, and cannot be moved to a more suitable place. This is
- * indicated with the error code -EBUSY.
+ * accessible to any importers, and cannot be moved to a more suitable place.
+ * This is indicated with the error code -EBUSY.
+ *
+ * This records the attachment's match set, i.e. the intersection of types
+ * supported by both importer and exporter, in &dma_buf_attachment.matches.
+ * Later attachments by other importers never change the set but may affect
+ * what type the exporter selects when the attachment is first mapped or
+ * pinned.
  */
-struct dma_buf_attachment *
-dma_buf_dynamic_attach(struct dma_buf *dmabuf, struct device *dev,
-		       const struct dma_buf_attach_ops *importer_ops,
-		       void *importer_priv)
+struct dma_buf_attachment *dma_buf_mapping_attach(
+	struct dma_buf *dmabuf, struct dma_buf_mapping_match *importer_matches,
+	size_t match_len, const struct dma_buf_attach_ops *importer_ops,
+	void *importer_priv)
 {
+	struct dma_buf_match_args match_args = {
+		.dmabuf = dmabuf,
+		.imp_matches = importer_matches,
+		.imp_len = match_len,
+	};
 	struct dma_buf_attachment *attach;
 	int ret;
 
-	if (WARN_ON(!dmabuf || !dev))
+	if (WARN_ON(!dmabuf))
 		return ERR_PTR(-EINVAL);
 
 	attach = kzalloc_obj(*attach);
 	if (!attach)
 		return ERR_PTR(-ENOMEM);
 
-	attach->dev = dev;
 	attach->dmabuf = dmabuf;
-	if (importer_ops)
-		attach->peer2peer = importer_ops->allow_peer2peer;
 	attach->importer_ops = importer_ops;
 	attach->importer_priv = importer_priv;
 
+	/*
+	 * The exporter's match_mapping() may look at the importer side of the
+	 * attachment, so initialise it before the match.
+	 */
+	match_args.attach = attach;
+	if (dmabuf->ops->match_mapping) {
+		ret = dmabuf->ops->match_mapping(&match_args);
+		if (ret)
+			goto err_attach;
+	} else {
+		ret = dma_buf_match_mapping(&match_args,
+					    &dma_buf_sgt_exp_compat_match, 1);
+		if (ret)
+			goto err_attach;
+	}
+
 	if (dmabuf->ops->attach) {
 		ret = dmabuf->ops->attach(dmabuf, attach);
 		if (ret)
@@ -1060,7 +1094,8 @@ dma_buf_dynamic_attach(struct dma_buf *dmabuf, struct device *dev,
 	dma_resv_unlock(dmabuf->resv);
 
 	DMA_BUF_TRACE(trace_dma_buf_dynamic_attach, dmabuf, attach,
-		dma_buf_attachment_is_dynamic(attach), dev);
+		dma_buf_attachment_is_dynamic(attach),
+		dma_buf_sgt_dma_device(attach));
 
 	return attach;
 
@@ -1068,23 +1103,53 @@ dma_buf_dynamic_attach(struct dma_buf *dmabuf, struct device *dev,
 	kfree(attach);
 	return ERR_PTR(ret);
 }
-EXPORT_SYMBOL_NS_GPL(dma_buf_dynamic_attach, "DMA_BUF");
+EXPORT_SYMBOL_NS_GPL(dma_buf_mapping_attach, "DMA_BUF");
 
 /**
- * dma_buf_attach - Wrapper for dma_buf_dynamic_attach
+ * dma_buf_attach - Wrapper for dma_buf_mapping_attach
  * @dmabuf:	[in]	buffer to attach device to.
  * @dev:	[in]	device to be attached.
  *
- * Wrapper to call dma_buf_dynamic_attach() for drivers which still use a static
+ * Wrapper to call dma_buf_mapping_attach() for drivers which still use a static
  * mapping.
  */
 struct dma_buf_attachment *dma_buf_attach(struct dma_buf *dmabuf,
 					  struct device *dev)
 {
-	return dma_buf_dynamic_attach(dmabuf, dev, NULL, NULL);
+	struct dma_buf_mapping_match sgt_match[] = {
+		DMA_BUF_IMAPPING_SGT(dev, DMA_SGT_NO_P2P),
+	};
+
+	return dma_buf_mapping_attach(dmabuf, sgt_match, ARRAY_SIZE(sgt_match),
+				      NULL, NULL);
 }
 EXPORT_SYMBOL_NS_GPL(dma_buf_attach, "DMA_BUF");
 
+/**
+ * dma_buf_dynamic_attach - Add the device to dma_buf's attachments list
+ * @dmabuf:		[in]	buffer to attach device to.
+ * @dev:		[in]	device to be attached.
+ * @importer_ops:	[in]	importer operations for the attachment
+ * @importer_priv:	[in]	importer private pointer for the attachment
+ *
+ * Wrapper to call dma_buf_mapping_attach() for drivers which only support SGT.
+ */
+struct dma_buf_attachment *
+dma_buf_dynamic_attach(struct dma_buf *dmabuf, struct device *dev,
+		       const struct dma_buf_attach_ops *importer_ops,
+		       void *importer_priv)
+{
+	struct dma_buf_mapping_match sgt_match[] = {
+		DMA_BUF_IMAPPING_SGT(dev, importer_ops->allow_peer2peer ?
+						  DMA_SGT_IMPORTER_ACCEPTS_P2P :
+						  DMA_SGT_NO_P2P),
+	};
+
+	return dma_buf_mapping_attach(dmabuf, sgt_match, ARRAY_SIZE(sgt_match),
+				      importer_ops, importer_priv);
+}
+EXPORT_SYMBOL_NS_GPL(dma_buf_dynamic_attach, "DMA_BUF");
+
 /**
  * dma_buf_detach - Remove the given attachment from dmabuf's attachments list
  * @dmabuf:	[in]	buffer to detach from.
diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h
index 3e82ec59d5ce..83ab2902a23b 100644
--- a/include/linux/dma-buf.h
+++ b/include/linux/dma-buf.h
@@ -29,6 +29,7 @@ struct dma_buf;
 struct dma_buf_attachment;
 struct dma_buf_mapping_type;
 struct dma_buf_mapping_exp_ops;
+struct dma_buf_match_args;
 
 
 /*
@@ -315,6 +316,27 @@ struct dma_buf_ops {
 
 	int (*vmap)(struct dma_buf *dmabuf, struct iosys_map *map);
 	void (*vunmap)(struct dma_buf *dmabuf, struct iosys_map *map);
+
+	/**
+	 * @match_mapping:
+	 *
+	 * Called during attach, without the dma_resv lock held. Allows the
+	 * exporter to build its own exporter struct dma_buf_mapping_match[]
+	 * and call dma_buf_match_mapping() to record every mutually
+	 * acceptable type in &dma_buf_attachment.matches in the exporter's
+	 * order of preference.
+	 *
+	 * The match set is fixed for the lifetime of the attachment, so every
+	 * input to the decision must hold for that long: either static for the
+	 * dma_buf (the importer's list, PCI P2P topology, buffer creation
+	 * flags) or runtime state the exporter pins until @detach, for example
+	 * a runtime PM reference.
+	 *
+	 * It must not depend on the set of attachments or on current buffer
+	 * placement as matches are static and buffer placement can change at
+	 * any time until the final location is resolved during map/pin.
+	 */
+	int (*match_mapping)(struct dma_buf_match_args *args);
 };
 
 /**
@@ -606,6 +628,11 @@ struct dma_buf_attachment *
 dma_buf_dynamic_attach(struct dma_buf *dmabuf, struct device *dev,
 		       const struct dma_buf_attach_ops *importer_ops,
 		       void *importer_priv);
+struct dma_buf_attachment *dma_buf_mapping_attach(
+	struct dma_buf *dmabuf, struct dma_buf_mapping_match *importer_matches,
+	size_t match_len, const struct dma_buf_attach_ops *importer_ops,
+	void *importer_priv);
+
 void dma_buf_detach(struct dma_buf *dmabuf,
 		    struct dma_buf_attachment *attach);
 int dma_buf_pin(struct dma_buf_attachment *attach);
diff --git a/include/trace/events/dma_buf.h b/include/trace/events/dma_buf.h
index 3bb88d05bcc8..13d3a82856b6 100644
--- a/include/trace/events/dma_buf.h
+++ b/include/trace/events/dma_buf.h
@@ -40,7 +40,7 @@ DECLARE_EVENT_CLASS(dma_buf_attach_dev,
 	TP_ARGS(dmabuf, attach, is_dynamic, dev),
 
 	TP_STRUCT__entry(
-		__string(	dev_name,			dev_name(dev))
+		__string(	dev_name,			dev ? dev_name(dev) : "none")
 		__string(	exp_name,			dmabuf->exp_name)
 		__field(	size_t,				size)
 		__field(	ino_t,				ino)
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 71+ messages in thread

* [PATCH 04/26] dma-buf: Route SGT related actions through attach->map_type
  2026-10-26  5:35 [PATCH 00/26] DMA-buf mapping types Alistair Popple
                   ` (2 preceding siblings ...)
  2026-10-26  5:35 ` [PATCH 03/26] dma-buf: Add dma_buf_mapping_attach() Alistair Popple
@ 2026-10-26  5:35 ` Alistair Popple
  2026-10-26  7:29   ` sashiko-bot
  2026-10-26  5:35 ` [PATCH 05/26] dma-buf: Let the exporter select mapping type at pin/map Alistair Popple
                   ` (21 subsequent siblings)
  25 siblings, 1 reply; 71+ messages in thread
From: Alistair Popple @ 2026-10-26  5:35 UTC (permalink / raw)
  To: dri-devel, christian.koenig, sumit.semwal, jgg
  Cc: Alistair Popple, Thomas Hellström, Simona Vetter,
	Matthew Brost, Vivek Kasireddy, Dongwon Kim, Leon Romanovsky,
	Kevin Tian, Xu Yilun, Karl Mehltretter, Baolu Lu, Felix Kuehling,
	Alex Deucher, intel-xe, amd-gfx, linux-media, linaro-mm-sig,
	linux-rdma, iommu, Alexey Kardashevskiy, zhipingz, treding,
	jhubbard

From: Jason Gunthorpe <jgg@nvidia.com>

Now that dma_buf_mapping_attach() ensures a mapping_type exists, even for
exporters and importers that don't provide it, route operations through the
map_type.

For map/unmap this will go through dma_buf_sgt_compat_map_dma_buf() which
calls the same attach->dmabuf->ops->map_dma_buf().

Move the debugfs processing unique to SGT into a callback too.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
[ minor context change rebasing as dma_buf_unwrap_sg_table() replaced mangle_sg_table() in 51db5336e16d - apopple ]
Signed-off-by: Alistair Popple <apopple@nvidia.com>
---
 drivers/dma-buf/dma-buf.c | 21 +++++++++++++++------
 1 file changed, 15 insertions(+), 6 deletions(-)

diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c
index 16a7fbb8aaab..348b47f266b4 100644
--- a/drivers/dma-buf/dma-buf.c
+++ b/drivers/dma-buf/dma-buf.c
@@ -1253,12 +1253,14 @@ EXPORT_SYMBOL_NS_GPL(dma_buf_unpin, "DMA_BUF");
 struct sg_table *dma_buf_map_attachment(struct dma_buf_attachment *attach,
 					enum dma_data_direction direction)
 {
+	const struct dma_buf_mapping_sgt_exp_ops *sgt_exp_ops =
+		dma_buf_get_sgt_ops(attach);
 	struct sg_table *sg_table;
 	signed long ret;
 
 	might_sleep();
 
-	if (WARN_ON(!attach || !attach->dmabuf))
+	if (WARN_ON(!attach || !attach->dmabuf || !sgt_exp_ops))
 		return ERR_PTR(-EINVAL);
 
 	dma_resv_assert_held(attach->dmabuf->resv);
@@ -1274,7 +1276,7 @@ struct sg_table *dma_buf_map_attachment(struct dma_buf_attachment *attach,
 			return ERR_PTR(ret);
 	}
 
-	sg_table = attach->dmabuf->ops->map_dma_buf(attach, direction);
+	sg_table = sgt_exp_ops->map_dma_buf(attach, direction);
 	if (!sg_table)
 		sg_table = ERR_PTR(-ENOMEM);
 	if (IS_ERR(sg_table))
@@ -1313,7 +1315,7 @@ struct sg_table *dma_buf_map_attachment(struct dma_buf_attachment *attach,
 	return sg_table;
 
 error_unmap:
-	attach->dmabuf->ops->unmap_dma_buf(attach, sg_table, direction);
+	sgt_exp_ops->unmap_dma_buf(attach, sg_table, direction);
 	sg_table = ERR_PTR(ret);
 
 error_unpin:
@@ -1366,15 +1368,18 @@ void dma_buf_unmap_attachment(struct dma_buf_attachment *attach,
 				struct sg_table *sg_table,
 				enum dma_data_direction direction)
 {
+	const struct dma_buf_mapping_sgt_exp_ops *sgt_exp_ops =
+		dma_buf_get_sgt_ops(attach);
+
 	might_sleep();
 
-	if (WARN_ON(!attach || !attach->dmabuf || !sg_table))
+	if (WARN_ON(!attach || !attach->dmabuf || !sg_table || !sgt_exp_ops))
 		return;
 
 	dma_resv_assert_held(attach->dmabuf->resv);
 
 	dma_buf_unwrap_sg_table(&sg_table);
-	attach->dmabuf->ops->unmap_dma_buf(attach, sg_table, direction);
+	sgt_exp_ops->unmap_dma_buf(attach, sg_table, direction);
 
 	if (dma_buf_pin_on_map(attach))
 		attach->dmabuf->ops->unpin(attach);
@@ -1855,7 +1860,11 @@ static int dma_buf_debug_show(struct seq_file *s, void *unused)
 		attach_count = 0;
 
 		list_for_each_entry(attach_obj, &buf_obj->attachments, node) {
-			seq_printf(s, "\t%s\n", dev_name(attach_obj->dev));
+			seq_printf(s, "\t%s:", attach_obj->map_type.type->name);
+			if (attach_obj->map_type.type->debugfs_dump)
+				attach_obj->map_type.type->debugfs_dump(
+					s, attach_obj);
+			seq_putc(s, '\n');
 			attach_count++;
 		}
 		dma_resv_unlock(buf_obj->resv);
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 71+ messages in thread

* [PATCH 05/26] dma-buf: Let the exporter select mapping type at pin/map
  2026-10-26  5:35 [PATCH 00/26] DMA-buf mapping types Alistair Popple
                   ` (3 preceding siblings ...)
  2026-10-26  5:35 ` [PATCH 04/26] dma-buf: Route SGT related actions through attach->map_type Alistair Popple
@ 2026-10-26  5:35 ` Alistair Popple
  2026-10-26  7:39   ` sashiko-bot
  2026-10-26  8:03   ` Karl Mehltretter
  2026-10-26  5:35 ` [PATCH 06/26] dma-buf: Add match set queries for exporter placement decisions Alistair Popple
                   ` (20 subsequent siblings)
  25 siblings, 2 replies; 71+ messages in thread
From: Alistair Popple @ 2026-10-26  5:35 UTC (permalink / raw)
  To: dri-devel, christian.koenig, sumit.semwal, jgg
  Cc: Alistair Popple, Thomas Hellström, Simona Vetter,
	Matthew Brost, Vivek Kasireddy, Dongwon Kim, Leon Romanovsky,
	Kevin Tian, Xu Yilun, Karl Mehltretter, Baolu Lu, Felix Kuehling,
	Alex Deucher, intel-xe, amd-gfx, linux-media, linaro-mm-sig,
	linux-rdma, iommu, Alexey Kardashevskiy, zhipingz, treding,
	jhubbard

The match set negotiated at attach determines which types an attachment
could possibly be served with. Which one should actually be served
depends on where the buffer is and other attachments when an importer
first pins or maps. So far the first entry was used unconditionally,
even if it cannot be served to some importers.

Add dma_buf_ops.select_mapping() under dma_resv from both pin and map
paths before the type's map callback to let the exporter choose which to
serve based on the current placement and list of attachments.

The choice is recorded in attach->selected and does not call
select_mapping again across any number of unmaps and remaps, until
dma_buf_invalidate_mappings() has been delivered to the attachment.

This prevents importer remap from bouncing a buffer between placements
- the type cannot change without the exporter explicitly invalidating
first. In other words attachments that are never invalidated keep the
initially selected type for the life of the attachment.

A failed select or map establishes nothing and leaves the choice open.

Importers never select. The importer's list order is a preference the
exporter may weigh or ignore, and an importer must accept any type it
listed.

Assisted-by: LLM
Signed-off-by: Alistair Popple <apopple@nvidia.com>
---
 drivers/dma-buf/dma-buf-mapping.c | 49 ++++++++++++++-
 drivers/dma-buf/dma-buf.c         | 99 +++++++++++++++++++++----------
 include/linux/dma-buf-mapping.h   |  6 ++
 include/linux/dma-buf.h           | 39 +++++++++++-
 4 files changed, 156 insertions(+), 37 deletions(-)

diff --git a/drivers/dma-buf/dma-buf-mapping.c b/drivers/dma-buf/dma-buf-mapping.c
index d30c0e9ef038..dbcd83b6dcff 100644
--- a/drivers/dma-buf/dma-buf-mapping.c
+++ b/drivers/dma-buf/dma-buf-mapping.c
@@ -270,8 +270,9 @@ EXPORT_SYMBOL_NS_GPL(dma_buf_free_sgt, "DMA_BUF");
  * Walk the exporter's list in order and, for each entry, find the first
  * importer entry of the same type that the type's match() callback accepts.
  * Every such pair is recorded in @args->attach->matches, so the match set
- * preserves the exporter's priority. The first entry becomes the default in
- * @args->attach->map_type.
+ * preserves the exporter's priority. The first entry becomes the default
+ * selection in @args->attach->map_type until &dma_buf_ops.select_mapping
+ * chooses otherwise at pin or map time.
  *
  * Because the exporter list is walked in order, the exporter controls the
  * priority of mapping types.
@@ -321,6 +322,50 @@ int dma_buf_match_mapping(struct dma_buf_match_args *args,
 }
 EXPORT_SYMBOL_NS_GPL(dma_buf_match_mapping, "DMA_BUF");
 
+/**
+ * dma_buf_mapping_select - Let the exporter choose the type to map with
+ * @attach: Attachment about to be pinned or mapped
+ *
+ * Called with the dma_resv lock held by dma_buf_pin() and the map functions.
+ * The first call after attach, and after each dma_buf_invalidate_mappings(),
+ * asks &dma_buf_ops.select_mapping to pick an entry of the match set given
+ * the buffer's placement and the other live mappings; exporters without the
+ * callback get the first entry. Every other call returns the previous choice
+ * unchanged, so the mapping type cannot change between unmap and remap without
+ * the exporter having explicitly invalidated.
+ *
+ * Returns: 0 on success or the exporter's error, typically -EBUSY when the
+ * attachment cannot be served without disturbing a mapping that cannot be
+ * invalidated.
+ */
+int dma_buf_mapping_select(struct dma_buf_attachment *attach)
+{
+	const struct dma_buf_mapping_match *match;
+
+	dma_resv_assert_held(attach->dmabuf->resv);
+
+	if (attach->selected)
+		return 0;
+
+	if (WARN_ON(!attach->nr_matches))
+		return -EINVAL;
+
+	if (attach->dmabuf->ops->select_mapping) {
+		match = attach->dmabuf->ops->select_mapping(attach);
+		if (IS_ERR(match))
+			return PTR_ERR(match);
+		if (WARN_ON(match < attach->matches ||
+			    match >= attach->matches + attach->nr_matches))
+			return -EINVAL;
+	} else {
+		match = &attach->matches[0];
+	}
+
+	attach->map_type = *match;
+	attach->selected = true;
+	return 0;
+}
+
 static int dma_buf_sgt_match(struct dma_buf *dmabuf,
 			     const struct dma_buf_mapping_match *exp,
 			     const struct dma_buf_mapping_match *imp)
diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c
index 348b47f266b4..03f06c4b957c 100644
--- a/drivers/dma-buf/dma-buf.c
+++ b/drivers/dma-buf/dma-buf.c
@@ -1201,6 +1201,10 @@ int dma_buf_pin(struct dma_buf_attachment *attach)
 
 	dma_resv_assert_held(dmabuf->resv);
 
+	ret = dma_buf_mapping_select(attach);
+	if (ret)
+		return ret;
+
 	if (dmabuf->ops->pin)
 		ret = dmabuf->ops->pin(attach);
 
@@ -1229,42 +1233,19 @@ void dma_buf_unpin(struct dma_buf_attachment *attach)
 }
 EXPORT_SYMBOL_NS_GPL(dma_buf_unpin, "DMA_BUF");
 
-/**
- * dma_buf_map_attachment - Returns the scatterlist table of the attachment;
- * mapped into _device_ address space. Is a wrapper for map_dma_buf() of the
- * dma_buf_ops.
- * @attach:	[in]	attachment whose scatterlist is to be returned
- * @direction:	[in]	direction of DMA transfer
- *
- * Returns sg_table containing the scatterlist to be returned; returns ERR_PTR
- * on error. May return -EINTR if it is interrupted by a signal.
- *
- * On success, the DMA addresses and lengths in the returned scatterlist are
- * PAGE_SIZE aligned.
- *
- * A mapping must be unmapped by using dma_buf_unmap_attachment(). Note that
- * the underlying backing storage is pinned for as long as a mapping exists,
- * therefore users/importers should not hold onto a mapping for undue amounts of
- * time.
- *
- * Important: Dynamic importers must wait for the exclusive fence of the struct
- * dma_resv attached to the DMA-BUF first.
- */
-struct sg_table *dma_buf_map_attachment(struct dma_buf_attachment *attach,
-					enum dma_data_direction direction)
+/* The SGT type must have been selected into attach->map_type already */
+static struct sg_table *
+__dma_buf_sgt_map_attachment(struct dma_buf_attachment *attach,
+			     enum dma_data_direction direction)
 {
 	const struct dma_buf_mapping_sgt_exp_ops *sgt_exp_ops =
 		dma_buf_get_sgt_ops(attach);
 	struct sg_table *sg_table;
 	signed long ret;
 
-	might_sleep();
-
-	if (WARN_ON(!attach || !attach->dmabuf || !sgt_exp_ops))
+	if (WARN_ON(!sgt_exp_ops))
 		return ERR_PTR(-EINVAL);
 
-	dma_resv_assert_held(attach->dmabuf->resv);
-
 	if (dma_buf_pin_on_map(attach)) {
 		ret = attach->dmabuf->ops->pin(attach);
 		/*
@@ -1324,6 +1305,52 @@ struct sg_table *dma_buf_map_attachment(struct dma_buf_attachment *attach,
 
 	return sg_table;
 }
+
+/**
+ * dma_buf_map_attachment - Returns the scatterlist table of the attachment;
+ * mapped into _device_ address space. Is a wrapper for map_dma_buf() of the
+ * dma_buf_ops.
+ * @attach:	[in]	attachment whose scatterlist is to be returned
+ * @direction:	[in]	direction of DMA transfer
+ *
+ * Returns sg_table containing the scatterlist to be returned; returns ERR_PTR
+ * on error. May return -EINTR if it is interrupted by a signal.
+ *
+ * On success, the DMA addresses and lengths in the returned scatterlist are
+ * PAGE_SIZE aligned.
+ *
+ * A mapping must be unmapped by using dma_buf_unmap_attachment(). Note that
+ * the underlying backing storage is pinned for as long as a mapping exists,
+ * therefore users/importers should not hold onto a mapping for undue amounts of
+ * time.
+ *
+ * Important: Dynamic importers must wait for the exclusive fence of the struct
+ * dma_resv attached to the DMA-BUF first.
+ */
+struct sg_table *dma_buf_map_attachment(struct dma_buf_attachment *attach,
+					enum dma_data_direction direction)
+{
+	struct sg_table *sg_table;
+	int ret;
+
+	might_sleep();
+
+	if (WARN_ON(!attach || !attach->dmabuf))
+		return ERR_PTR(-EINVAL);
+
+	dma_resv_assert_held(attach->dmabuf->resv);
+
+	ret = dma_buf_mapping_select(attach);
+	if (ret)
+		return ERR_PTR(ret);
+
+	sg_table = __dma_buf_sgt_map_attachment(attach, direction);
+	if (IS_ERR(sg_table))
+		/* Nothing was established, so the choice may be made afresh */
+		attach->selected = false;
+
+	return sg_table;
+}
 EXPORT_SYMBOL_NS_GPL(dma_buf_map_attachment, "DMA_BUF");
 
 /**
@@ -1465,6 +1492,10 @@ EXPORT_SYMBOL_NS_GPL(dma_buf_attach_revocable, "DMA_BUF");
  *
  * Importers are free to request a new mapping in parallel as this function
  * returns.
+ *
+ * This is also the only point at which an attachment's mapping type
+ * may change after a pin/map: the core keeps the type chosen by
+ * &dma_buf_ops.select_mapping until the attachment has been invalidated here.
  */
 void dma_buf_invalidate_mappings(struct dma_buf *dmabuf)
 {
@@ -1472,10 +1503,14 @@ void dma_buf_invalidate_mappings(struct dma_buf *dmabuf)
 
 	dma_resv_assert_held(dmabuf->resv);
 
-	list_for_each_entry(attach, &dmabuf->attachments, node)
-		if (attach->importer_ops &&
-		    attach->importer_ops->invalidate_mappings)
-			attach->importer_ops->invalidate_mappings(attach);
+	list_for_each_entry(attach, &dmabuf->attachments, node) {
+		if (!attach->importer_ops ||
+		    !attach->importer_ops->invalidate_mappings)
+			continue;
+
+		attach->selected = false;
+		attach->importer_ops->invalidate_mappings(attach);
+	}
 }
 EXPORT_SYMBOL_NS_GPL(dma_buf_invalidate_mappings, "DMA_BUF");
 
diff --git a/include/linux/dma-buf-mapping.h b/include/linux/dma-buf-mapping.h
index f9b749af362b..c04fac71726a 100644
--- a/include/linux/dma-buf-mapping.h
+++ b/include/linux/dma-buf-mapping.h
@@ -96,6 +96,12 @@ int dma_buf_match_mapping(struct dma_buf_match_args *args,
 			  const struct dma_buf_mapping_match *exp_mappings,
 			  size_t exp_len);
 
+/*
+ * Internal: Selection is made by exporters through &dma_buf_ops.select_mapping
+ * in dma_buf_pin() or map paths. Importers never call this.
+ */
+int dma_buf_mapping_select(struct dma_buf_attachment *attach);
+
 /*
  * DMA Mapped Scatterlist Type
  *
diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h
index 83ab2902a23b..8bd5026eb642 100644
--- a/include/linux/dma-buf.h
+++ b/include/linux/dma-buf.h
@@ -337,6 +337,34 @@ struct dma_buf_ops {
 	 * any time until the final location is resolved during map/pin.
 	 */
 	int (*match_mapping)(struct dma_buf_match_args *args);
+
+	/**
+	 * @select_mapping:
+	 *
+	 * Called with the dma_resv lock held from dma_buf_pin() and from the
+	 * map functions, before the type's map callback, to choose which
+	 * entry of &dma_buf_attachment.matches this attachment is mapped
+	 * with. The exporter settles the buffer's placement here, taking all
+	 * live mappings and pinned attachments into account, and returns the
+	 * entry that placement can serve.
+	 *
+	 * The core records the choice and does not ask again, across any
+	 * number of unmaps and remaps, until the exporter has delivered
+	 * &dma_buf_attach_ops.invalidate_mappings to this attachment. The
+	 * exporter must therefore keep the recorded type servable: moving the
+	 * buffer somewhere that type cannot be produced from requires
+	 * invalidating first. Attachments that cannot be invalidated keep
+	 * their first choice for life.
+	 *
+	 * Optional. Without it the first entry of the match set, the
+	 * exporter's most preferred, is used.
+	 *
+	 * Returns: a pointer into &dma_buf_attachment.matches, or an ERR_PTR.
+	 * -EBUSY means the attachment cannot be served without disturbing a
+	 * mapping that cannot be invalidated.
+	 */
+	const struct dma_buf_mapping_match *(*select_mapping)(
+		struct dma_buf_attachment *attach);
 };
 
 /**
@@ -532,12 +560,16 @@ struct dma_buf_attach_ops {
  * @importer_ops: importer operations for this attachment, if provided
  * dma_buf_map/unmap_attachment() must be called with the dma_resv lock held.
  * @importer_priv: importer specific attachment data.
- * @map_type: The match this attachment is mapped with. Until the exporter
- *            selects otherwise it holds the exporter's default, the first
- *            entry of @matches.
+ * @map_type: The match this attachment is mapped with. Chosen by
+ *            &dma_buf_ops.select_mapping at the first pin or map and kept,
+ *            enforced by the core, until &dma_buf_attach_ops.invalidate_mappings
+ *            is delivered to this attachment. Before the first selection it
+ *            holds the exporter's default, the first entry of @matches.
  * @matches: The match set negotiated at attach time: every mapping type both
  *           sides accept, in the exporter's order of preference.
  * @nr_matches: Number of valid entries in @matches.
+ * @selected: True once @map_type has been chosen by the exporter; cleared
+ *            only by dma_buf_invalidate_mappings().
  *
  * This structure holds the attachment information between the dma_buf buffer
  * and its user device(s). The list contains one attachment struct per device
@@ -559,6 +591,7 @@ struct dma_buf_attachment {
 	struct dma_buf_mapping_match map_type;
 	struct dma_buf_mapping_match matches[DMA_BUF_MAX_MATCHES];
 	unsigned int nr_matches;
+	bool selected;
 };
 
 /**
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 71+ messages in thread

* [PATCH 06/26] dma-buf: Add match set queries for exporter placement decisions
  2026-10-26  5:35 [PATCH 00/26] DMA-buf mapping types Alistair Popple
                   ` (4 preceding siblings ...)
  2026-10-26  5:35 ` [PATCH 05/26] dma-buf: Let the exporter select mapping type at pin/map Alistair Popple
@ 2026-10-26  5:35 ` Alistair Popple
  2026-10-26  7:42   ` sashiko-bot
  2026-10-26  5:35 ` [PATCH 07/26] dma-buf: Add dma_buf_mapping_map() returning a type-tagged mapping Alistair Popple
                   ` (19 subsequent siblings)
  25 siblings, 1 reply; 71+ messages in thread
From: Alistair Popple @ 2026-10-26  5:35 UTC (permalink / raw)
  To: dri-devel, christian.koenig, sumit.semwal, jgg
  Cc: Alistair Popple, Thomas Hellström, Simona Vetter,
	Matthew Brost, Vivek Kasireddy, Dongwon Kim, Leon Romanovsky,
	Kevin Tian, Xu Yilun, Karl Mehltretter, Baolu Lu, Felix Kuehling,
	Alex Deucher, intel-xe, amd-gfx, linux-media, linaro-mm-sig,
	linux-rdma, iommu, Alexey Kardashevskiy, zhipingz, treding,
	jhubbard

Exporters deciding placement in their pin path walk every attachment
to determine whether it can take P2P. With selection deferred to pin or
map an unmapped attachment only holds the exporter's default. Therefore
determining what is possible requires walking attachments.

Add dma_buf_attach_accepts() and dma_buf_attach_accepts_sgt_p2p() to
walk the match set and determine if an attachment is possible with P2P.
A future series will convert P2P into a distinct match type.

Assisted-by: LLM
Signed-off-by: Alistair Popple <apopple@nvidia.com>
---
 include/linux/dma-buf-mapping.h | 46 +++++++++++++++++++++++++++++++++
 1 file changed, 46 insertions(+)

diff --git a/include/linux/dma-buf-mapping.h b/include/linux/dma-buf-mapping.h
index c04fac71726a..494bc29910f4 100644
--- a/include/linux/dma-buf-mapping.h
+++ b/include/linux/dma-buf-mapping.h
@@ -102,6 +102,26 @@ int dma_buf_match_mapping(struct dma_buf_match_args *args,
  */
 int dma_buf_mapping_select(struct dma_buf_attachment *attach);
 
+/**
+ * dma_buf_attach_accepts - Is @type in the attachment's match set
+ * @attach: the attachment
+ * @type: a mapping type
+ *
+ * Called by exporters deciding placement in pin or select_mapping to determine
+ * whether the importer could be served with @type.
+ */
+static inline bool
+dma_buf_attach_accepts(const struct dma_buf_attachment *attach,
+		       const struct dma_buf_mapping_type *type)
+{
+	unsigned int i;
+
+	for (i = 0; i < attach->nr_matches; i++)
+		if (attach->matches[i].type == type)
+			return true;
+	return false;
+}
+
 /*
  * DMA Mapped Scatterlist Type
  *
@@ -147,6 +167,10 @@ dma_buf_sgt_dma_device(struct dma_buf_attachment *attach)
  *
  * Should be called by exporters, returns true if the exporter's
  * DMA_SGT_EXPORTER_REQUIRES_P2P_DISTANCE was matched.
+ *
+ * Reflects the current selection, so is only meaningful inside the
+ * exporter's pin and map callbacks. For attachments which may be unmapped use
+ * dma_buf_attach_accepts_sgt_p2p().
  */
 static inline bool dma_buf_sgt_p2p_allowed(struct dma_buf_attachment *attach)
 {
@@ -156,6 +180,28 @@ static inline bool dma_buf_sgt_p2p_allowed(struct dma_buf_attachment *attach)
 	       DMA_SGT_EXPORTER_REQUIRES_P2P_DISTANCE;
 }
 
+/**
+ * dma_buf_attach_accepts_sgt_p2p - Could this attachment take a P2P SGT?
+ * @attach: any attachment
+ *
+ * Like dma_buf_sgt_p2p_allowed() but valid for attachments that are not mapped.
+ * Instead determines if p2p is part of the current possible match set rather
+ * than the current selection. Called by exporters walking all attachments in
+ * their pin path.
+ */
+static inline bool
+dma_buf_attach_accepts_sgt_p2p(const struct dma_buf_attachment *attach)
+{
+	unsigned int i;
+
+	for (i = 0; i < attach->nr_matches; i++)
+		if (attach->matches[i].type == &dma_buf_mapping_sgt_type &&
+		    attach->matches[i].sgt_data.exporter_requires_p2p ==
+			    DMA_SGT_EXPORTER_REQUIRES_P2P_DISTANCE)
+			return true;
+	return false;
+}
+
 static inline const struct dma_buf_mapping_sgt_exp_ops *
 dma_buf_get_sgt_ops(struct dma_buf_attachment *attach)
 {
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 71+ messages in thread

* [PATCH 07/26] dma-buf: Add dma_buf_mapping_map() returning a type-tagged mapping
  2026-10-26  5:35 [PATCH 00/26] DMA-buf mapping types Alistair Popple
                   ` (5 preceding siblings ...)
  2026-10-26  5:35 ` [PATCH 06/26] dma-buf: Add match set queries for exporter placement decisions Alistair Popple
@ 2026-10-26  5:35 ` Alistair Popple
  2026-10-26  7:56   ` sashiko-bot
  2026-10-26  5:35 ` [PATCH 08/26] dma-buf: Allow single exporter drivers to avoid the match_mapping function Alistair Popple
                   ` (18 subsequent siblings)
  25 siblings, 1 reply; 71+ messages in thread
From: Alistair Popple @ 2026-10-26  5:35 UTC (permalink / raw)
  To: dri-devel, christian.koenig, sumit.semwal, jgg
  Cc: Alistair Popple, Thomas Hellström, Simona Vetter,
	Matthew Brost, Vivek Kasireddy, Dongwon Kim, Leon Romanovsky,
	Kevin Tian, Xu Yilun, Karl Mehltretter, Baolu Lu, Felix Kuehling,
	Alex Deucher, intel-xe, amd-gfx, linux-media, linaro-mm-sig,
	linux-rdma, iommu, Alexey Kardashevskiy, zhipingz, treding,
	jhubbard

An importer that lists more than one mapping type cannot know which
type-specific map function to call, because the exporter selects the
type at map time. Create a generic entry point to determine the correct
type.

dma_buf_mapping_map() selects via dma_buf_mapping_select() and dispatches
to a map op on struct dma_buf_mapping_type. That returns a struct
dma_buf_mapping carrying the type, embedded in the type's own
result struct. dma_buf_mapping_unmap() hands it back through the type's
unmap op.

To support existing SGT importers the SGT type implements both. Its
result is struct dma_buf_sgt_mapping with the sg_table reachable through
dma_buf_sgt_mapping_table(). The sgt map body is shared with the SGT
type's map function which remains the entry point for importers listing
only SGT.

Assisted-by: LLM
Signed-off-by: Alistair Popple <apopple@nvidia.com>
---
 drivers/dma-buf/dma-buf-mapping.c | 75 +++++++++++++++++++++++++++++++
 drivers/dma-buf/dma-buf.c         | 33 ++++++++++++++
 include/linux/dma-buf-mapping.h   | 63 ++++++++++++++++++++++++++
 3 files changed, 171 insertions(+)

diff --git a/drivers/dma-buf/dma-buf-mapping.c b/drivers/dma-buf/dma-buf-mapping.c
index dbcd83b6dcff..7a5a379a372e 100644
--- a/drivers/dma-buf/dma-buf-mapping.c
+++ b/drivers/dma-buf/dma-buf-mapping.c
@@ -366,6 +366,79 @@ int dma_buf_mapping_select(struct dma_buf_attachment *attach)
 	return 0;
 }
 
+/**
+ * dma_buf_mapping_map - Map an attachment with whichever type the exporter
+ *                       selects
+ * @attach: the attachment
+ * @dir: DMA direction
+ *
+ * For importers that listed more than one mapping type. The exporter picks the
+ * type from the possible matches and the result's &dma_buf_mapping.type records
+ * which was used. Must be called with the dma_resv lock held, and the lock must
+ * be held until the result has been acted on. Importers that listed a single
+ * type keep using that type's map function.
+ *
+ * Returns: a &struct dma_buf_mapping to pass to dma_buf_mapping_unmap(), or
+ * an ERR_PTR.
+ */
+struct dma_buf_mapping *dma_buf_mapping_map(struct dma_buf_attachment *attach,
+					    enum dma_data_direction dir)
+{
+	struct dma_buf_mapping *mapping;
+	int ret;
+
+	might_sleep();
+
+	if (WARN_ON(!attach || !attach->dmabuf))
+		return ERR_PTR(-EINVAL);
+
+	dma_resv_assert_held(attach->dmabuf->resv);
+
+	ret = dma_buf_mapping_select(attach);
+	if (ret)
+		return ERR_PTR(ret);
+
+	if (!attach->map_type.type->map) {
+		ret = -EOPNOTSUPP;
+		goto err_release;
+	}
+
+	mapping = attach->map_type.type->map(attach, dir);
+	if (IS_ERR(mapping)) {
+		ret = PTR_ERR(mapping);
+		goto err_release;
+	}
+
+	return mapping;
+
+err_release:
+	/* Nothing was established, so the choice may be made afresh */
+	attach->selected = false;
+	return ERR_PTR(ret);
+}
+EXPORT_SYMBOL_NS_GPL(dma_buf_mapping_map, "DMA_BUF");
+
+/**
+ * dma_buf_mapping_unmap - Release a mapping from dma_buf_mapping_map()
+ * @attach: the attachment
+ * @mapping: what dma_buf_mapping_map() returned
+ * @dir: DMA direction used for the map
+ */
+void dma_buf_mapping_unmap(struct dma_buf_attachment *attach,
+			   struct dma_buf_mapping *mapping,
+			   enum dma_data_direction dir)
+{
+	might_sleep();
+
+	if (WARN_ON(!attach || !attach->dmabuf || !mapping))
+		return;
+
+	dma_resv_assert_held(attach->dmabuf->resv);
+
+	mapping->type->unmap(attach, mapping, dir);
+}
+EXPORT_SYMBOL_NS_GPL(dma_buf_mapping_unmap, "DMA_BUF");
+
 static int dma_buf_sgt_match(struct dma_buf *dmabuf,
 			     const struct dma_buf_mapping_match *exp,
 			     const struct dma_buf_mapping_match *imp)
@@ -427,6 +500,8 @@ struct dma_buf_mapping_type dma_buf_mapping_sgt_type = {
 	.match = dma_buf_sgt_match,
 	.finish_match = dma_buf_sgt_finish_match,
 	.debugfs_dump = dma_buf_sgt_debugfs_dump,
+	.map = dma_buf_sgt_type_map,
+	.unmap = dma_buf_sgt_type_unmap,
 };
 EXPORT_SYMBOL_NS_GPL(dma_buf_mapping_sgt_type, "DMA_BUF");
 
diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c
index 03f06c4b957c..90699e85e4c8 100644
--- a/drivers/dma-buf/dma-buf.c
+++ b/drivers/dma-buf/dma-buf.c
@@ -1353,6 +1353,39 @@ struct sg_table *dma_buf_map_attachment(struct dma_buf_attachment *attach,
 }
 EXPORT_SYMBOL_NS_GPL(dma_buf_map_attachment, "DMA_BUF");
 
+/* &dma_buf_mapping_type.map / .unmap for the SGT type */
+struct dma_buf_mapping *dma_buf_sgt_type_map(struct dma_buf_attachment *attach,
+					     enum dma_data_direction dir)
+{
+	struct dma_buf_sgt_mapping *mapping;
+	int ret;
+
+	mapping = kzalloc_obj(*mapping);
+	if (!mapping)
+		return ERR_PTR(-ENOMEM);
+
+	mapping->base.type = &dma_buf_mapping_sgt_type;
+	mapping->sgt = __dma_buf_sgt_map_attachment(attach, dir);
+	if (IS_ERR(mapping->sgt)) {
+		ret = PTR_ERR(mapping->sgt);
+		kfree(mapping);
+		return ERR_PTR(ret);
+	}
+
+	return &mapping->base;
+}
+
+void dma_buf_sgt_type_unmap(struct dma_buf_attachment *attach,
+			    struct dma_buf_mapping *base,
+			    enum dma_data_direction dir)
+{
+	struct dma_buf_sgt_mapping *mapping =
+		container_of(base, struct dma_buf_sgt_mapping, base);
+
+	dma_buf_unmap_attachment(attach, mapping->sgt, dir);
+	kfree(mapping);
+}
+
 /**
  * dma_buf_map_attachment_unlocked - Returns the scatterlist table of the attachment;
  * mapped into _device_ address space. Is a wrapper for map_dma_buf() of the
diff --git a/include/linux/dma-buf-mapping.h b/include/linux/dma-buf-mapping.h
index 494bc29910f4..885e0e54b5eb 100644
--- a/include/linux/dma-buf-mapping.h
+++ b/include/linux/dma-buf-mapping.h
@@ -21,6 +21,16 @@ enum dma_sgt_requires_p2p {
 /* Type tag for all mapping operations */
 struct dma_buf_mapping_exp_ops {};
 
+/**
+ * struct dma_buf_mapping - header of a mapping made with dma_buf_mapping_map()
+ * @type: The mapping type the exporter selected. Importers that listed more
+ *        than one type switch on this and use the type's accessor to get at
+ *        the type-specific result embedding this header.
+ */
+struct dma_buf_mapping {
+	const struct dma_buf_mapping_type *type;
+};
+
 /*
  * Internal struct to pass arguments from the attach function to the matching
  * function
@@ -82,8 +92,35 @@ struct dma_buf_mapping_type {
 	 */
 	void (*debugfs_dump)(struct seq_file *s,
 			     struct dma_buf_attachment *attach);
+
+	/**
+	 * @map:
+	 *
+	 * Produce a mapping of this type for @attach, which has already been
+	 * selected into @attach->map_type. Called by dma_buf_mapping_map()
+	 * with the dma_resv lock held. Responsible for pin-on-map of static
+	 * importers if the type supports them. Optional; a type without it
+	 * can only be used through its own map functions.
+	 */
+	struct dma_buf_mapping *(*map)(struct dma_buf_attachment *attach,
+				       enum dma_data_direction dir);
+
+	/**
+	 * @unmap:
+	 *
+	 * Release a mapping returned by @map.
+	 */
+	void (*unmap)(struct dma_buf_attachment *attach,
+		      struct dma_buf_mapping *mapping,
+		      enum dma_data_direction dir);
 };
 
+struct dma_buf_mapping *dma_buf_mapping_map(struct dma_buf_attachment *attach,
+					    enum dma_data_direction dir);
+void dma_buf_mapping_unmap(struct dma_buf_attachment *attach,
+			   struct dma_buf_mapping *mapping,
+			   enum dma_data_direction dir);
+
 struct sg_table *dma_buf_phys_vec_to_sgt(struct dma_buf_attachment *attach,
 					 struct p2pdma_provider *provider,
 					 struct phys_vec *phys_vec,
@@ -122,6 +159,13 @@ dma_buf_attach_accepts(const struct dma_buf_attachment *attach,
 	return false;
 }
 
+/* Internal: &dma_buf_mapping_sgt_type.map / .unmap, implemented in dma-buf.c */
+struct dma_buf_mapping *dma_buf_sgt_type_map(struct dma_buf_attachment *attach,
+					     enum dma_data_direction dir);
+void dma_buf_sgt_type_unmap(struct dma_buf_attachment *attach,
+			    struct dma_buf_mapping *mapping,
+			    enum dma_data_direction dir);
+
 /*
  * DMA Mapped Scatterlist Type
  *
@@ -137,6 +181,25 @@ dma_buf_attach_accepts(const struct dma_buf_attachment *attach,
  */
 extern struct dma_buf_mapping_type dma_buf_mapping_sgt_type;
 
+/**
+ * struct dma_buf_sgt_mapping - dma_buf_mapping_map() result for the SGT type
+ * @base: common header, @base.type == &dma_buf_mapping_sgt_type
+ * @sgt: the DMA mapped scatterlist, as the SGT type's own map function
+ *       returns it
+ */
+struct dma_buf_sgt_mapping {
+	struct dma_buf_mapping base;
+	struct sg_table *sgt;
+};
+
+static inline struct sg_table *
+dma_buf_sgt_mapping_table(struct dma_buf_mapping *mapping)
+{
+	if (WARN_ON(mapping->type != &dma_buf_mapping_sgt_type))
+		return NULL;
+	return container_of(mapping, struct dma_buf_sgt_mapping, base)->sgt;
+}
+
 struct dma_buf_mapping_sgt_exp_ops {
 	struct dma_buf_mapping_exp_ops ops;
 	struct sg_table *(*map_dma_buf)(struct dma_buf_attachment *attach,
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 71+ messages in thread

* [PATCH 08/26] dma-buf: Allow single exporter drivers to avoid the match_mapping function
  2026-10-26  5:35 [PATCH 00/26] DMA-buf mapping types Alistair Popple
                   ` (6 preceding siblings ...)
  2026-10-26  5:35 ` [PATCH 07/26] dma-buf: Add dma_buf_mapping_map() returning a type-tagged mapping Alistair Popple
@ 2026-10-26  5:35 ` Alistair Popple
  2026-10-26  7:58   ` sashiko-bot
  2026-10-26  5:36 ` [PATCH 09/26] drm: Check the SGT ops for drm_gem_map_dma_buf() Alistair Popple
                   ` (17 subsequent siblings)
  25 siblings, 1 reply; 71+ messages in thread
From: Alistair Popple @ 2026-10-26  5:35 UTC (permalink / raw)
  To: dri-devel, christian.koenig, sumit.semwal, jgg
  Cc: Alistair Popple, Thomas Hellström, Simona Vetter,
	Matthew Brost, Vivek Kasireddy, Dongwon Kim, Leon Romanovsky,
	Kevin Tian, Xu Yilun, Karl Mehltretter, Baolu Lu, Felix Kuehling,
	Alex Deucher, intel-xe, amd-gfx, linux-media, linaro-mm-sig,
	linux-rdma, iommu, Alexey Kardashevskiy, zhipingz, treding,
	jhubbard

From: Jason Gunthorpe <jgg@nvidia.com>

Introduce single_exporter_match into the dma_buf_ops so that single
exporter drivers can simply set it using a static initializer to use the
mapping type APIs. Provide a helper macro DMA_BUF_SIMPLE_SGT_EXP_MATCH()
that generates the initializer for simple drivers that don't use P2P.

More complex exporters, especially those with P2P, need to implement the
match_mapping call back to extract things like their DMA struct device
from the dma_buf in order to do the P2P calculations.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/dma-buf/dma-buf.c       | 14 +++++++++++---
 include/linux/dma-buf-mapping.h | 15 +++++++++++++++
 include/linux/dma-buf.h         |  9 +++++++++
 3 files changed, 35 insertions(+), 3 deletions(-)

diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c
index 90699e85e4c8..6c9ab8bc09ac 100644
--- a/drivers/dma-buf/dma-buf.c
+++ b/drivers/dma-buf/dma-buf.c
@@ -718,10 +718,14 @@ struct dma_buf *dma_buf_export(const struct dma_buf_export_info *exp_info)
 		    || !exp_info->ops->release))
 		return ERR_PTR(-EINVAL);
 
-	if (exp_info->ops->match_mapping) {
+	if (exp_info->ops->match_mapping ||
+	    exp_info->ops->single_exporter_match) {
 		if (WARN_ON(exp_info->ops->map_dma_buf ||
 			    exp_info->ops->unmap_dma_buf))
 			return ERR_PTR(-EINVAL);
+		if (WARN_ON(exp_info->ops->match_mapping &&
+			    exp_info->ops->single_exporter_match))
+			return ERR_PTR(-EINVAL);
 	} else {
 		if (WARN_ON(!exp_info->ops->map_dma_buf ||
 			    !exp_info->ops->unmap_dma_buf))
@@ -1078,8 +1082,12 @@ struct dma_buf_attachment *dma_buf_mapping_attach(
 		if (ret)
 			goto err_attach;
 	} else {
-		ret = dma_buf_match_mapping(&match_args,
-					    &dma_buf_sgt_exp_compat_match, 1);
+		const struct dma_buf_mapping_match *exp_match =
+			dmabuf->ops->single_exporter_match;
+
+		if (!exp_match)
+			exp_match = &dma_buf_sgt_exp_compat_match;
+		ret = dma_buf_match_mapping(&match_args, exp_match, 1);
 		if (ret)
 			goto err_attach;
 	}
diff --git a/include/linux/dma-buf-mapping.h b/include/linux/dma-buf-mapping.h
index 885e0e54b5eb..4aaddad8c7be 100644
--- a/include/linux/dma-buf-mapping.h
+++ b/include/linux/dma-buf-mapping.h
@@ -306,4 +306,19 @@ DMA_BUF_EMAPPING_SGT_P2P(const struct dma_buf_mapping_sgt_exp_ops *exp_ops,
 
 extern const struct dma_buf_mapping_match dma_buf_sgt_exp_compat_match;
 
+/*
+ * dma_buf_ops initializer helper for simple drivers that use a single
+ * SGT map/unmap operation without P2P.
+ */
+#define DMA_BUF_SIMPLE_SGT_EXP_MATCH(_map, _unmap)                       \
+	.single_exporter_match = &((const struct dma_buf_mapping_match){ \
+		.type = &dma_buf_mapping_sgt_type,                       \
+		.exp_ops = &((const struct dma_buf_mapping_sgt_exp_ops){ \
+			.map_dma_buf = _map,                             \
+			.unmap_dma_buf = _unmap,                         \
+		}.ops),                                                  \
+		.sgt_data = {                                            \
+			.exporter_requires_p2p = DMA_SGT_NO_P2P,         \
+		} })
+
 #endif
diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h
index 8bd5026eb642..d78eec3476f3 100644
--- a/include/linux/dma-buf.h
+++ b/include/linux/dma-buf.h
@@ -365,6 +365,15 @@ struct dma_buf_ops {
 	 */
 	const struct dma_buf_mapping_match *(*select_mapping)(
 		struct dma_buf_attachment *attach);
+
+	/**
+	 * @single_exporter_match:
+	 *
+	 * Should only be set by the DMA_BUF_SIMPLE_*_EXP_MATCH() helper macros.
+	 * Exactly one of @match_mapping or @single_exporter_match must be
+	 * provided.
+	 */
+	const struct dma_buf_mapping_match *single_exporter_match;
 };
 
 /**
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 71+ messages in thread

* [PATCH 09/26] drm: Check the SGT ops for drm_gem_map_dma_buf()
  2026-10-26  5:35 [PATCH 00/26] DMA-buf mapping types Alistair Popple
                   ` (7 preceding siblings ...)
  2026-10-26  5:35 ` [PATCH 08/26] dma-buf: Allow single exporter drivers to avoid the match_mapping function Alistair Popple
@ 2026-10-26  5:36 ` Alistair Popple
  2026-10-26  8:02   ` sashiko-bot
  2026-10-26  5:36 ` [PATCH 10/26] dma-buf: Convert all the simple exporters to use SGT mapping type Alistair Popple
                   ` (16 subsequent siblings)
  25 siblings, 1 reply; 71+ messages in thread
From: Alistair Popple @ 2026-10-26  5:36 UTC (permalink / raw)
  To: dri-devel, christian.koenig, sumit.semwal, jgg
  Cc: Alistair Popple, Thomas Hellström, Simona Vetter,
	Matthew Brost, Vivek Kasireddy, Dongwon Kim, Leon Romanovsky,
	Kevin Tian, Xu Yilun, Karl Mehltretter, Baolu Lu, Felix Kuehling,
	Alex Deucher, intel-xe, amd-gfx, linux-media, linaro-mm-sig,
	linux-rdma, iommu, Alexey Kardashevskiy, zhipingz, treding,
	jhubbard

From: Jason Gunthorpe <jgg@nvidia.com>

When the next patch converts exporters to use SGT natively, the
dma_buf->ops->map_dma_buf will become NULL. Additionally check
sgt_exp_ops to see the new location.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/gpu/drm/drm_prime.c | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c
index fe3436d1235d..cf53b8cab4da 100644
--- a/drivers/gpu/drm/drm_prime.c
+++ b/drivers/gpu/drm/drm_prime.c
@@ -28,6 +28,7 @@
 
 #include <linux/export.h>
 #include <linux/dma-buf.h>
+#include <linux/dma-buf-mapping.h>
 #include <linux/rbtree.h>
 #include <linux/module.h>
 
@@ -587,6 +588,18 @@ int drm_prime_handle_to_fd_ioctl(struct drm_device *dev, void *data,
  * option for sharing lots of buffers for rendering.
  */
 
+static bool is_gem_map_dma_buf(struct dma_buf_attachment *attach)
+{
+	const struct dma_buf_mapping_sgt_exp_ops *sgt_exp_ops =
+		dma_buf_get_sgt_ops(attach);
+
+	if (attach->dmabuf->ops->map_dma_buf == drm_gem_map_dma_buf)
+		return true;
+	if (sgt_exp_ops && sgt_exp_ops->map_dma_buf == drm_gem_map_dma_buf)
+		return true;
+	return false;
+}
+
 /**
  * drm_gem_map_attach - dma_buf attach implementation for GEM
  * @dma_buf: buffer to attach device to
@@ -608,7 +621,7 @@ int drm_gem_map_attach(struct dma_buf *dma_buf,
 	 * drm_gem_map_dma_buf() requires obj->get_sg_table(), but drivers
 	 * that implement their own ->map_dma_buf() do not.
 	 */
-	if (dma_buf->ops->map_dma_buf == drm_gem_map_dma_buf &&
+	if (is_gem_map_dma_buf(attach) &&
 	    !obj->funcs->get_sg_table)
 		return -ENOSYS;
 
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 71+ messages in thread

* [PATCH 10/26] dma-buf: Convert all the simple exporters to use SGT mapping type
  2026-10-26  5:35 [PATCH 00/26] DMA-buf mapping types Alistair Popple
                   ` (8 preceding siblings ...)
  2026-10-26  5:36 ` [PATCH 09/26] drm: Check the SGT ops for drm_gem_map_dma_buf() Alistair Popple
@ 2026-10-26  5:36 ` Alistair Popple
  2026-10-26  8:12   ` sashiko-bot
  2026-10-26  5:36 ` [PATCH 11/26] drm/vmwgfx: Use match_mapping instead of dummy calls Alistair Popple
                   ` (15 subsequent siblings)
  25 siblings, 1 reply; 71+ messages in thread
From: Alistair Popple @ 2026-10-26  5:36 UTC (permalink / raw)
  To: dri-devel, christian.koenig, sumit.semwal, jgg
  Cc: Alistair Popple, Thomas Hellström, Simona Vetter,
	Matthew Brost, Vivek Kasireddy, Dongwon Kim, Leon Romanovsky,
	Kevin Tian, Xu Yilun, Karl Mehltretter, Baolu Lu, Felix Kuehling,
	Alex Deucher, intel-xe, amd-gfx, linux-media, linaro-mm-sig,
	linux-rdma, iommu, Alexey Kardashevskiy, zhipingz, treding,
	jhubbard

From: Jason Gunthorpe <jgg@nvidia.com>

Update the exporters to use a SGT mapping type and the new style mapping
type API. None of these exporters do anything with attach->peer2peer or
importer_ops->allow_peer2peer and they all follow the same pattern.

Change all the places that need to get the SGT's DMA device for DMA API
use to use dma_buf_sgt_dma_device().

This is all a mechanical change of moving the map_dma_buf/unmap_dma_buf
into DMA_BUF_SIMPLE_SGT_EXP_MATCH() arguments and switching
attach->dev to dma_buf_sgt_dma_device(attach).

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
[ added converters for newly added amdxdna, panfrost and panthor exporters - apopple ]
Signed-off-by: Alistair Popple <apopple@nvidia.com>
---
 drivers/accel/amdxdna/amdxdna_cbuf.c          |  8 ++++----
 drivers/accel/amdxdna/amdxdna_gem.c           |  5 +++--
 drivers/accel/amdxdna/amdxdna_ubuf.c          |  8 ++++----
 drivers/accel/ivpu/ivpu_gem_userptr.c         | 11 +++++++----
 drivers/dma-buf/heaps/cma_heap.c              | 12 +++++++-----
 drivers/dma-buf/heaps/system_heap.c           | 13 ++++++++-----
 drivers/dma-buf/udmabuf.c                     |  8 ++++----
 drivers/gpu/drm/armada/armada_gem.c           | 12 +++++++-----
 drivers/gpu/drm/drm_prime.c                   |  9 +++++----
 drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c    |  8 +++++---
 .../gpu/drm/i915/gem/selftests/mock_dmabuf.c  |  8 ++++----
 drivers/gpu/drm/msm/msm_gem_prime.c           |  7 +++++--
 drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c     |  5 +++--
 drivers/gpu/drm/panfrost/panfrost_gem.c       | 13 +++++++++----
 drivers/gpu/drm/panthor/panthor_gem.c         | 11 +++++++----
 drivers/gpu/drm/tegra/gem.c                   | 12 +++++++-----
 drivers/gpu/drm/virtio/virtgpu_prime.c        | 11 +++++++----
 drivers/iommu/iommufd/selftest.c              | 18 +++---------------
 .../common/videobuf2/videobuf2-dma-contig.c   | 15 ++++++++-------
 .../media/common/videobuf2/videobuf2-dma-sg.c | 14 +++++++++-----
 .../common/videobuf2/videobuf2-vmalloc.c      | 13 ++++++++-----
 drivers/misc/fastrpc.c                        | 12 +++++++-----
 drivers/tee/tee_heap.c                        | 13 +++++++------
 drivers/xen/gntdev-dmabuf.c                   | 19 +++++++++++--------
 samples/vfio-mdev/mbochs.c                    | 10 +++++-----
 sound/soc/fsl/fsl_asrc_m2m.c                  | 12 +++++++-----
 26 files changed, 161 insertions(+), 126 deletions(-)

diff --git a/drivers/accel/amdxdna/amdxdna_cbuf.c b/drivers/accel/amdxdna/amdxdna_cbuf.c
index a504560aae98..2070a371903d 100644
--- a/drivers/accel/amdxdna/amdxdna_cbuf.c
+++ b/drivers/accel/amdxdna/amdxdna_cbuf.c
@@ -5,6 +5,7 @@
 
 #include <drm/drm_mm.h>
 #include <drm/drm_prime.h>
+#include <linux/dma-buf-mapping.h>
 
 #include "amdxdna_cbuf.h"
 #include "amdxdna_pci_drv.h"
@@ -85,7 +86,7 @@ static struct sg_table *amdxdna_cbuf_map(struct dma_buf_attachment *attach,
 					 enum dma_data_direction direction)
 {
 	struct amdxdna_cbuf_priv *cbuf = attach->dmabuf->priv;
-	struct device *dev = attach->dev;
+	struct device *dev = dma_buf_sgt_dma_device(attach);
 	struct scatterlist *sgl, *sg;
 	int ret, n_entries, i;
 	struct sg_table *sgt;
@@ -140,7 +141,7 @@ static void amdxdna_cbuf_unmap(struct dma_buf_attachment *attach,
 			       struct sg_table *sgt,
 			       enum dma_data_direction direction)
 {
-	dma_unmap_resource(attach->dev, sg_dma_address(sgt->sgl),
+	dma_unmap_resource(dma_buf_sgt_dma_device(attach), sg_dma_address(sgt->sgl),
 			   drm_prime_get_contiguous_size(sgt), direction,
 			   DMA_ATTR_SKIP_CPU_SYNC);
 	sg_free_table(sgt);
@@ -210,12 +211,11 @@ static void amdxdna_cbuf_vunmap(struct dma_buf *dbuf, struct iosys_map *map)
 }
 
 static const struct dma_buf_ops amdxdna_cbuf_dmabuf_ops = {
-	.map_dma_buf = amdxdna_cbuf_map,
-	.unmap_dma_buf = amdxdna_cbuf_unmap,
 	.release = amdxdna_cbuf_release,
 	.mmap = amdxdna_cbuf_mmap,
 	.vmap = amdxdna_cbuf_vmap,
 	.vunmap = amdxdna_cbuf_vunmap,
+	DMA_BUF_SIMPLE_SGT_EXP_MATCH(amdxdna_cbuf_map, amdxdna_cbuf_unmap),
 };
 
 static int amdxdna_cbuf_clear(struct dma_buf *dbuf)
diff --git a/drivers/accel/amdxdna/amdxdna_gem.c b/drivers/accel/amdxdna/amdxdna_gem.c
index 4b0d58d0329b..6253a720cc22 100644
--- a/drivers/accel/amdxdna/amdxdna_gem.c
+++ b/drivers/accel/amdxdna/amdxdna_gem.c
@@ -11,6 +11,7 @@
 #include <drm/drm_print.h>
 #include <drm/gpu_scheduler.h>
 #include <linux/dma-buf.h>
+#include <linux/dma-buf-mapping.h>
 #include <linux/dma-direct.h>
 #include <linux/iosys-map.h>
 #include <linux/pagemap.h>
@@ -559,12 +560,12 @@ static int amdxdna_gem_dmabuf_mmap(struct dma_buf *dma_buf, struct vm_area_struc
 static const struct dma_buf_ops amdxdna_dmabuf_ops = {
 	.attach = drm_gem_map_attach,
 	.detach = drm_gem_map_detach,
-	.map_dma_buf = drm_gem_map_dma_buf,
-	.unmap_dma_buf = drm_gem_unmap_dma_buf,
 	.release = drm_gem_dmabuf_release,
 	.mmap = amdxdna_gem_dmabuf_mmap,
 	.vmap = drm_gem_dmabuf_vmap,
 	.vunmap = drm_gem_dmabuf_vunmap,
+	DMA_BUF_SIMPLE_SGT_EXP_MATCH(drm_gem_map_dma_buf,
+				     drm_gem_unmap_dma_buf),
 };
 
 static struct dma_buf *amdxdna_gem_prime_export(struct drm_gem_object *gobj, int flags)
diff --git a/drivers/accel/amdxdna/amdxdna_ubuf.c b/drivers/accel/amdxdna/amdxdna_ubuf.c
index 0e0cd69cd1fb..b81f947712e8 100644
--- a/drivers/accel/amdxdna/amdxdna_ubuf.c
+++ b/drivers/accel/amdxdna/amdxdna_ubuf.c
@@ -7,6 +7,7 @@
 #include <drm/drm_device.h>
 #include <drm/drm_print.h>
 #include <linux/dma-buf.h>
+#include <linux/dma-buf-mapping.h>
 #include <linux/overflow.h>
 #include <linux/pagemap.h>
 #include <linux/vmalloc.h>
@@ -36,7 +37,7 @@ static struct sg_table *amdxdna_ubuf_map(struct dma_buf_attachment *attach,
 	if (ret)
 		goto err_free_sg;
 
-	ret = dma_map_sgtable(attach->dev, sg, direction, 0);
+	ret = dma_map_sgtable(dma_buf_sgt_dma_device(attach), sg, direction, 0);
 	if (ret)
 		goto err_free_table;
 
@@ -53,7 +54,7 @@ static void amdxdna_ubuf_unmap(struct dma_buf_attachment *attach,
 			       struct sg_table *sg,
 			       enum dma_data_direction direction)
 {
-	dma_unmap_sgtable(attach->dev, sg, direction, 0);
+	dma_unmap_sgtable(dma_buf_sgt_dma_device(attach), sg, direction, 0);
 	sg_free_table(sg);
 	kfree(sg);
 }
@@ -70,9 +71,8 @@ static void amdxdna_ubuf_release(struct dma_buf *dbuf)
 }
 
 static const struct dma_buf_ops amdxdna_ubuf_dmabuf_ops = {
-	.map_dma_buf = amdxdna_ubuf_map,
-	.unmap_dma_buf = amdxdna_ubuf_unmap,
 	.release = amdxdna_ubuf_release,
+	DMA_BUF_SIMPLE_SGT_EXP_MATCH(amdxdna_ubuf_map, amdxdna_ubuf_unmap),
 };
 
 struct dma_buf *amdxdna_get_ubuf(struct drm_device *dev,
diff --git a/drivers/accel/ivpu/ivpu_gem_userptr.c b/drivers/accel/ivpu/ivpu_gem_userptr.c
index 7cbf3a4cdc73..7ca9d8d4f5a8 100644
--- a/drivers/accel/ivpu/ivpu_gem_userptr.c
+++ b/drivers/accel/ivpu/ivpu_gem_userptr.c
@@ -4,6 +4,7 @@
  */
 
 #include <linux/dma-buf.h>
+#include <linux/dma-buf-mapping.h>
 #include <linux/err.h>
 #include <linux/highmem.h>
 #include <linux/mm.h>
@@ -26,7 +27,8 @@ ivpu_gem_userptr_dmabuf_map(struct dma_buf_attachment *attachment,
 	struct sg_table *sgt = attachment->dmabuf->priv;
 	int ret;
 
-	ret = dma_map_sgtable(attachment->dev, sgt, direction, DMA_ATTR_SKIP_CPU_SYNC);
+	ret = dma_map_sgtable(dma_buf_sgt_dma_device(attachment), sgt,
+			      direction, DMA_ATTR_SKIP_CPU_SYNC);
 	if (ret)
 		return ERR_PTR(ret);
 
@@ -37,7 +39,8 @@ static void ivpu_gem_userptr_dmabuf_unmap(struct dma_buf_attachment *attachment,
 					  struct sg_table *sgt,
 					  enum dma_data_direction direction)
 {
-	dma_unmap_sgtable(attachment->dev, sgt, direction, DMA_ATTR_SKIP_CPU_SYNC);
+	dma_unmap_sgtable(dma_buf_sgt_dma_device(attachment), sgt, direction,
+			  DMA_ATTR_SKIP_CPU_SYNC);
 }
 
 static void ivpu_gem_userptr_dmabuf_release(struct dma_buf *dma_buf)
@@ -56,9 +59,9 @@ static void ivpu_gem_userptr_dmabuf_release(struct dma_buf *dma_buf)
 }
 
 static const struct dma_buf_ops ivpu_gem_userptr_dmabuf_ops = {
-	.map_dma_buf = ivpu_gem_userptr_dmabuf_map,
-	.unmap_dma_buf = ivpu_gem_userptr_dmabuf_unmap,
 	.release = ivpu_gem_userptr_dmabuf_release,
+	DMA_BUF_SIMPLE_SGT_EXP_MATCH(ivpu_gem_userptr_dmabuf_map,
+				     ivpu_gem_userptr_dmabuf_unmap),
 };
 
 static struct dma_buf *
diff --git a/drivers/dma-buf/heaps/cma_heap.c b/drivers/dma-buf/heaps/cma_heap.c
index 3fb4b946c91a..fa05c242f238 100644
--- a/drivers/dma-buf/heaps/cma_heap.c
+++ b/drivers/dma-buf/heaps/cma_heap.c
@@ -14,6 +14,7 @@
 
 #include <linux/cma.h>
 #include <linux/dma-buf.h>
+#include <linux/dma-buf-mapping.h>
 #include <linux/dma-heap.h>
 #include <linux/dma-map-ops.h>
 #include <linux/err.h>
@@ -73,7 +74,7 @@ static int cma_heap_attach(struct dma_buf *dmabuf,
 		return ret;
 	}
 
-	a->dev = attachment->dev;
+	a->dev = dma_buf_sgt_dma_device(attachment);
 	INIT_LIST_HEAD(&a->list);
 	a->mapped = false;
 
@@ -107,7 +108,8 @@ static struct sg_table *cma_heap_map_dma_buf(struct dma_buf_attachment *attachme
 	struct sg_table *table = &a->table;
 	int ret;
 
-	ret = dma_map_sgtable(attachment->dev, table, direction, 0);
+	ret = dma_map_sgtable(dma_buf_sgt_dma_device(attachment), table,
+			      direction, 0);
 	if (ret)
 		return ERR_PTR(-ENOMEM);
 	a->mapped = true;
@@ -121,7 +123,8 @@ static void cma_heap_unmap_dma_buf(struct dma_buf_attachment *attachment,
 	struct dma_heap_attachment *a = attachment->priv;
 
 	a->mapped = false;
-	dma_unmap_sgtable(attachment->dev, table, direction, 0);
+	dma_unmap_sgtable(dma_buf_sgt_dma_device(attachment), table, direction,
+			  0);
 }
 
 static int cma_heap_dma_buf_begin_cpu_access(struct dma_buf *dmabuf,
@@ -268,14 +271,13 @@ static void cma_heap_dma_buf_release(struct dma_buf *dmabuf)
 static const struct dma_buf_ops cma_heap_buf_ops = {
 	.attach = cma_heap_attach,
 	.detach = cma_heap_detach,
-	.map_dma_buf = cma_heap_map_dma_buf,
-	.unmap_dma_buf = cma_heap_unmap_dma_buf,
 	.begin_cpu_access = cma_heap_dma_buf_begin_cpu_access,
 	.end_cpu_access = cma_heap_dma_buf_end_cpu_access,
 	.mmap = cma_heap_mmap,
 	.vmap = cma_heap_vmap,
 	.vunmap = cma_heap_vunmap,
 	.release = cma_heap_dma_buf_release,
+	DMA_BUF_SIMPLE_SGT_EXP_MATCH(cma_heap_map_dma_buf, cma_heap_unmap_dma_buf),
 };
 
 static struct dma_buf *cma_heap_allocate(struct dma_heap *heap,
diff --git a/drivers/dma-buf/heaps/system_heap.c b/drivers/dma-buf/heaps/system_heap.c
index c8959eadc71d..e954238463d4 100644
--- a/drivers/dma-buf/heaps/system_heap.c
+++ b/drivers/dma-buf/heaps/system_heap.c
@@ -12,6 +12,7 @@
 
 #include <linux/cc_platform.h>
 #include <linux/dma-buf.h>
+#include <linux/dma-buf-mapping.h>
 #include <linux/dma-mapping.h>
 #include <linux/dma-heap.h>
 #include <linux/err.h>
@@ -128,7 +129,7 @@ static int system_heap_attach(struct dma_buf *dmabuf,
 		return ret;
 	}
 
-	a->dev = attachment->dev;
+	a->dev = dma_buf_sgt_dma_device(attachment);
 	INIT_LIST_HEAD(&a->list);
 	a->mapped = false;
 	a->cc_shared = buffer->cc_shared;
@@ -165,7 +166,8 @@ static struct sg_table *system_heap_map_dma_buf(struct dma_buf_attachment *attac
 	int ret;
 
 	attrs = cc_shared_buffer(a) ? DMA_ATTR_CC_SHARED : 0;
-	ret = dma_map_sgtable(attachment->dev, table, direction, attrs);
+	ret = dma_map_sgtable(dma_buf_sgt_dma_device(attachment), table,
+			      direction, attrs);
 	if (ret)
 		return ERR_PTR(ret);
 
@@ -180,7 +182,8 @@ static void system_heap_unmap_dma_buf(struct dma_buf_attachment *attachment,
 	struct dma_heap_attachment *a = attachment->priv;
 
 	a->mapped = false;
-	dma_unmap_sgtable(attachment->dev, table, direction, 0);
+	dma_unmap_sgtable(dma_buf_sgt_dma_device(attachment), table, direction,
+			  0);
 }
 
 static int system_heap_dma_buf_begin_cpu_access(struct dma_buf *dmabuf,
@@ -365,14 +368,14 @@ static void system_heap_dma_buf_release(struct dma_buf *dmabuf)
 static const struct dma_buf_ops system_heap_buf_ops = {
 	.attach = system_heap_attach,
 	.detach = system_heap_detach,
-	.map_dma_buf = system_heap_map_dma_buf,
-	.unmap_dma_buf = system_heap_unmap_dma_buf,
 	.begin_cpu_access = system_heap_dma_buf_begin_cpu_access,
 	.end_cpu_access = system_heap_dma_buf_end_cpu_access,
 	.mmap = system_heap_mmap,
 	.vmap = system_heap_vmap,
 	.vunmap = system_heap_vunmap,
 	.release = system_heap_dma_buf_release,
+	DMA_BUF_SIMPLE_SGT_EXP_MATCH(system_heap_map_dma_buf,
+				     system_heap_unmap_dma_buf),
 };
 
 static struct page *alloc_largest_available(unsigned long size,
diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c
index df6dd0046242..911a3fa347b3 100644
--- a/drivers/dma-buf/udmabuf.c
+++ b/drivers/dma-buf/udmabuf.c
@@ -2,6 +2,7 @@
 #include <linux/cred.h>
 #include <linux/device.h>
 #include <linux/dma-buf.h>
+#include <linux/dma-buf-mapping.h>
 #include <linux/dma-resv.h>
 #include <linux/highmem.h>
 #include <linux/init.h>
@@ -168,14 +169,14 @@ static void put_sg_table(struct device *dev, struct sg_table *sg,
 static struct sg_table *map_udmabuf(struct dma_buf_attachment *at,
 				    enum dma_data_direction direction)
 {
-	return get_sg_table(at->dev, at->dmabuf, direction);
+	return get_sg_table(dma_buf_sgt_dma_device(at), at->dmabuf, direction);
 }
 
 static void unmap_udmabuf(struct dma_buf_attachment *at,
 			  struct sg_table *sg,
 			  enum dma_data_direction direction)
 {
-	return put_sg_table(at->dev, sg, direction);
+	return put_sg_table(dma_buf_sgt_dma_device(at), sg, direction);
 }
 
 static void unpin_all_folios(struct udmabuf *ubuf)
@@ -256,14 +257,13 @@ static int end_cpu_udmabuf(struct dma_buf *buf,
 }
 
 static const struct dma_buf_ops udmabuf_ops = {
-	.map_dma_buf	   = map_udmabuf,
-	.unmap_dma_buf	   = unmap_udmabuf,
 	.release	   = release_udmabuf,
 	.mmap		   = mmap_udmabuf,
 	.vmap		   = vmap_udmabuf,
 	.vunmap		   = vunmap_udmabuf,
 	.begin_cpu_access  = begin_cpu_udmabuf,
 	.end_cpu_access    = end_cpu_udmabuf,
+	DMA_BUF_SIMPLE_SGT_EXP_MATCH(map_udmabuf, unmap_udmabuf),
 };
 
 #define SEALS_WANTED (F_SEAL_SHRINK)
diff --git a/drivers/gpu/drm/armada/armada_gem.c b/drivers/gpu/drm/armada/armada_gem.c
index da7335cbe82d..5cea1eab6e5c 100644
--- a/drivers/gpu/drm/armada/armada_gem.c
+++ b/drivers/gpu/drm/armada/armada_gem.c
@@ -4,6 +4,7 @@
  */
 
 #include <linux/dma-buf.h>
+#include <linux/dma-buf-mapping.h>
 #include <linux/dma-mapping.h>
 #include <linux/mman.h>
 #include <linux/shmem_fs.h>
@@ -387,6 +388,7 @@ static struct sg_table *
 armada_gem_prime_map_dma_buf(struct dma_buf_attachment *attach,
 	enum dma_data_direction dir)
 {
+	struct device *dma_dev = dma_buf_sgt_dma_device(attach);
 	struct drm_gem_object *obj = attach->dmabuf->priv;
 	struct armada_gem_object *dobj = drm_to_armada_gem(obj);
 	struct scatterlist *sg;
@@ -417,7 +419,7 @@ armada_gem_prime_map_dma_buf(struct dma_buf_attachment *attach,
 			sg_set_page(sg, page, PAGE_SIZE, 0);
 		}
 
-		if (dma_map_sgtable(attach->dev, sgt, dir, 0))
+		if (dma_map_sgtable(dma_dev, sgt, dir, 0))
 			goto release;
 	} else if (dobj->page) {
 		/* Single contiguous page */
@@ -426,7 +428,7 @@ armada_gem_prime_map_dma_buf(struct dma_buf_attachment *attach,
 
 		sg_set_page(sgt->sgl, dobj->page, dobj->obj.size, 0);
 
-		if (dma_map_sgtable(attach->dev, sgt, dir, 0))
+		if (dma_map_sgtable(dma_dev, sgt, dir, 0))
 			goto free_table;
 	} else if (dobj->linear) {
 		/* Single contiguous physical region - no struct page */
@@ -458,7 +460,7 @@ static void armada_gem_prime_unmap_dma_buf(struct dma_buf_attachment *attach,
 	int i;
 
 	if (!dobj->linear)
-		dma_unmap_sgtable(attach->dev, sgt, dir, 0);
+		dma_unmap_sgtable(dma_buf_sgt_dma_device(attach), sgt, dir, 0);
 
 	if (dobj->obj.filp) {
 		struct scatterlist *sg;
@@ -478,10 +480,10 @@ armada_gem_dmabuf_mmap(struct dma_buf *buf, struct vm_area_struct *vma)
 }
 
 static const struct dma_buf_ops armada_gem_prime_dmabuf_ops = {
-	.map_dma_buf	= armada_gem_prime_map_dma_buf,
-	.unmap_dma_buf	= armada_gem_prime_unmap_dma_buf,
 	.release	= drm_gem_dmabuf_release,
 	.mmap		= armada_gem_dmabuf_mmap,
+	DMA_BUF_SIMPLE_SGT_EXP_MATCH(armada_gem_prime_map_dma_buf,
+				     armada_gem_prime_unmap_dma_buf),
 };
 
 struct dma_buf *
diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c
index cf53b8cab4da..d797598e42f7 100644
--- a/drivers/gpu/drm/drm_prime.c
+++ b/drivers/gpu/drm/drm_prime.c
@@ -693,7 +693,7 @@ struct sg_table *drm_gem_map_dma_buf(struct dma_buf_attachment *attach,
 	if (IS_ERR(sgt))
 		return sgt;
 
-	ret = dma_map_sgtable(attach->dev, sgt, dir,
+	ret = dma_map_sgtable(dma_buf_sgt_dma_device(attach), sgt, dir,
 			      DMA_ATTR_SKIP_CPU_SYNC);
 	if (ret) {
 		sg_free_table(sgt);
@@ -720,7 +720,8 @@ void drm_gem_unmap_dma_buf(struct dma_buf_attachment *attach,
 	if (!sgt)
 		return;
 
-	dma_unmap_sgtable(attach->dev, sgt, dir, DMA_ATTR_SKIP_CPU_SYNC);
+	dma_unmap_sgtable(dma_buf_sgt_dma_device(attach), sgt, dir,
+			  DMA_ATTR_SKIP_CPU_SYNC);
 	sg_free_table(sgt);
 	kfree(sgt);
 }
@@ -840,12 +841,12 @@ EXPORT_SYMBOL(drm_gem_dmabuf_mmap);
 static const struct dma_buf_ops drm_gem_prime_dmabuf_ops =  {
 	.attach = drm_gem_map_attach,
 	.detach = drm_gem_map_detach,
-	.map_dma_buf = drm_gem_map_dma_buf,
-	.unmap_dma_buf = drm_gem_unmap_dma_buf,
 	.release = drm_gem_dmabuf_release,
 	.mmap = drm_gem_dmabuf_mmap,
 	.vmap = drm_gem_dmabuf_vmap,
 	.vunmap = drm_gem_dmabuf_vunmap,
+	DMA_BUF_SIMPLE_SGT_EXP_MATCH(drm_gem_map_dma_buf,
+				     drm_gem_unmap_dma_buf),
 };
 
 /**
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
index b43d34c7d641..5333e77e62e0 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
@@ -4,6 +4,7 @@
  */
 
 #include <linux/dma-buf.h>
+#include <linux/dma-buf-mapping.h>
 #include <linux/highmem.h>
 #include <linux/dma-resv.h>
 #include <linux/module.h>
@@ -52,7 +53,8 @@ static struct sg_table *i915_gem_map_dma_buf(struct dma_buf_attachment *attach,
 		dst = sg_next(dst);
 	}
 
-	ret = dma_map_sgtable(attach->dev, sgt, dir, DMA_ATTR_SKIP_CPU_SYNC);
+	ret = dma_map_sgtable(dma_buf_sgt_dma_device(attach), sgt, dir,
+			      DMA_ATTR_SKIP_CPU_SYNC);
 	if (ret)
 		goto err_free_sg;
 
@@ -203,14 +205,14 @@ static void i915_gem_dmabuf_detach(struct dma_buf *dmabuf,
 static const struct dma_buf_ops i915_dmabuf_ops =  {
 	.attach = i915_gem_dmabuf_attach,
 	.detach = i915_gem_dmabuf_detach,
-	.map_dma_buf = i915_gem_map_dma_buf,
-	.unmap_dma_buf = drm_gem_unmap_dma_buf,
 	.release = drm_gem_dmabuf_release,
 	.mmap = i915_gem_dmabuf_mmap,
 	.vmap = i915_gem_dmabuf_vmap,
 	.vunmap = i915_gem_dmabuf_vunmap,
 	.begin_cpu_access = i915_gem_begin_cpu_access,
 	.end_cpu_access = i915_gem_end_cpu_access,
+	DMA_BUF_SIMPLE_SGT_EXP_MATCH(i915_gem_map_dma_buf,
+				     drm_gem_unmap_dma_buf),
 };
 
 struct dma_buf *i915_gem_prime_export(struct drm_gem_object *gem_obj, int flags)
diff --git a/drivers/gpu/drm/i915/gem/selftests/mock_dmabuf.c b/drivers/gpu/drm/i915/gem/selftests/mock_dmabuf.c
index f2863da7f5c1..911d8f59011a 100644
--- a/drivers/gpu/drm/i915/gem/selftests/mock_dmabuf.c
+++ b/drivers/gpu/drm/i915/gem/selftests/mock_dmabuf.c
@@ -4,6 +4,7 @@
  * Copyright © 2016 Intel Corporation
  */
 
+#include <linux/dma-buf-mapping.h>
 #include <linux/vmalloc.h>
 #include "mock_dmabuf.h"
 
@@ -29,7 +30,7 @@ static struct sg_table *mock_map_dma_buf(struct dma_buf_attachment *attachment,
 		sg = sg_next(sg);
 	}
 
-	err = dma_map_sgtable(attachment->dev, st, dir, 0);
+	err = dma_map_sgtable(dma_buf_sgt_dma_device(attachment), st, dir, 0);
 	if (err)
 		goto err_st;
 
@@ -46,7 +47,7 @@ static void mock_unmap_dma_buf(struct dma_buf_attachment *attachment,
 			       struct sg_table *st,
 			       enum dma_data_direction dir)
 {
-	dma_unmap_sgtable(attachment->dev, st, dir, 0);
+	dma_unmap_sgtable(dma_buf_sgt_dma_device(attachment), st, dir, 0);
 	sg_free_table(st);
 	kfree(st);
 }
@@ -88,12 +89,11 @@ static int mock_dmabuf_mmap(struct dma_buf *dma_buf, struct vm_area_struct *vma)
 }
 
 static const struct dma_buf_ops mock_dmabuf_ops =  {
-	.map_dma_buf = mock_map_dma_buf,
-	.unmap_dma_buf = mock_unmap_dma_buf,
 	.release = mock_dmabuf_release,
 	.mmap = mock_dmabuf_mmap,
 	.vmap = mock_dmabuf_vmap,
 	.vunmap = mock_dmabuf_vunmap,
+	DMA_BUF_SIMPLE_SGT_EXP_MATCH(mock_map_dma_buf, mock_unmap_dma_buf),
 };
 
 static struct dma_buf *mock_dmabuf(int npages)
diff --git a/drivers/gpu/drm/msm/msm_gem_prime.c b/drivers/gpu/drm/msm/msm_gem_prime.c
index beb7f22fd694..46cccbe5f378 100644
--- a/drivers/gpu/drm/msm/msm_gem_prime.c
+++ b/drivers/gpu/drm/msm/msm_gem_prime.c
@@ -5,6 +5,7 @@
  */
 
 #include <linux/dma-buf.h>
+#include <linux/dma-buf-mapping.h>
 
 #include <drm/drm_drv.h>
 #include <drm/drm_prime.h>
@@ -54,12 +55,12 @@ static void msm_gem_dmabuf_release(struct dma_buf *dma_buf)
 static const struct dma_buf_ops msm_gem_prime_dmabuf_ops =  {
 	.attach = drm_gem_map_attach,
 	.detach = drm_gem_map_detach,
-	.map_dma_buf = drm_gem_map_dma_buf,
-	.unmap_dma_buf = drm_gem_unmap_dma_buf,
 	.release = msm_gem_dmabuf_release,
 	.mmap = drm_gem_dmabuf_mmap,
 	.vmap = drm_gem_dmabuf_vmap,
 	.vunmap = drm_gem_dmabuf_vunmap,
+	DMA_BUF_SIMPLE_SGT_EXP_MATCH(drm_gem_map_dma_buf,
+				     drm_gem_unmap_dma_buf),
 };
 
 struct drm_gem_object *msm_gem_prime_import(struct drm_device *dev,
@@ -132,3 +133,5 @@ void msm_gem_prime_unpin(struct drm_gem_object *obj)
 
 	msm_gem_unpin_pages_locked(obj);
 }
+
+MODULE_IMPORT_NS("DMA_BUF");
diff --git a/drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c b/drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c
index 30cf1cdc1aa3..23beaeefab67 100644
--- a/drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c
+++ b/drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c
@@ -5,6 +5,7 @@
  */
 
 #include <linux/dma-buf.h>
+#include <linux/dma-buf-mapping.h>
 #include <linux/highmem.h>
 
 #include <drm/drm_prime.h>
@@ -69,12 +70,12 @@ static int omap_gem_dmabuf_mmap(struct dma_buf *buffer,
 }
 
 static const struct dma_buf_ops omap_dmabuf_ops = {
-	.map_dma_buf = omap_gem_map_dma_buf,
-	.unmap_dma_buf = omap_gem_unmap_dma_buf,
 	.release = drm_gem_dmabuf_release,
 	.begin_cpu_access = omap_gem_dmabuf_begin_cpu_access,
 	.end_cpu_access = omap_gem_dmabuf_end_cpu_access,
 	.mmap = omap_gem_dmabuf_mmap,
+	DMA_BUF_SIMPLE_SGT_EXP_MATCH(omap_gem_map_dma_buf,
+				     omap_gem_unmap_dma_buf),
 };
 
 struct dma_buf *omap_gem_prime_export(struct drm_gem_object *obj, int flags)
diff --git a/drivers/gpu/drm/panfrost/panfrost_gem.c b/drivers/gpu/drm/panfrost/panfrost_gem.c
index 3a7fce428898..b1ce00989be4 100644
--- a/drivers/gpu/drm/panfrost/panfrost_gem.c
+++ b/drivers/gpu/drm/panfrost/panfrost_gem.c
@@ -6,6 +6,7 @@
 #include <linux/err.h>
 #include <linux/slab.h>
 #include <linux/dma-buf.h>
+#include <linux/dma-buf-mapping.h>
 #include <linux/dma-mapping.h>
 
 #include <drm/panfrost_drm.h>
@@ -15,6 +16,8 @@
 #include "panfrost_gem.h"
 #include "panfrost_mmu.h"
 
+MODULE_IMPORT_NS("DMA_BUF");
+
 void panfrost_gem_init(struct panfrost_device *pfdev)
 {
 	int err;
@@ -318,7 +321,8 @@ panfrost_gem_prime_begin_cpu_access(struct dma_buf *dma_buf,
 		struct sg_table *sgt = attach->priv;
 
 		if (sgt)
-			dma_sync_sgtable_for_cpu(attach->dev, sgt, dir);
+			dma_sync_sgtable_for_cpu(dma_buf_sgt_dma_device(attach),
+						 sgt, dir);
 	}
 	dma_resv_unlock(obj->resv);
 
@@ -339,7 +343,8 @@ panfrost_gem_prime_end_cpu_access(struct dma_buf *dma_buf,
 		struct sg_table *sgt = attach->priv;
 
 		if (sgt)
-			dma_sync_sgtable_for_device(attach->dev, sgt, dir);
+			dma_sync_sgtable_for_device(dma_buf_sgt_dma_device(attach),
+						    sgt, dir);
 	}
 
 	if (shmem->vaddr)
@@ -355,14 +360,14 @@ panfrost_gem_prime_end_cpu_access(struct dma_buf *dma_buf,
 static const struct dma_buf_ops panfrost_dma_buf_ops = {
 	.attach = drm_gem_map_attach,
 	.detach = drm_gem_map_detach,
-	.map_dma_buf = panfrost_gem_prime_map_dma_buf,
-	.unmap_dma_buf = panfrost_gem_prime_unmap_dma_buf,
 	.release = drm_gem_dmabuf_release,
 	.mmap = drm_gem_dmabuf_mmap,
 	.vmap = drm_gem_dmabuf_vmap,
 	.vunmap = drm_gem_dmabuf_vunmap,
 	.begin_cpu_access = panfrost_gem_prime_begin_cpu_access,
 	.end_cpu_access = panfrost_gem_prime_end_cpu_access,
+	DMA_BUF_SIMPLE_SGT_EXP_MATCH(panfrost_gem_prime_map_dma_buf,
+				     panfrost_gem_prime_unmap_dma_buf),
 };
 
 static struct dma_buf *
diff --git a/drivers/gpu/drm/panthor/panthor_gem.c b/drivers/gpu/drm/panthor/panthor_gem.c
index 72908be5e144..4478a37562e6 100644
--- a/drivers/gpu/drm/panthor/panthor_gem.c
+++ b/drivers/gpu/drm/panthor/panthor_gem.c
@@ -7,6 +7,7 @@
 #include <linux/cleanup.h>
 #include <linux/debugfs.h>
 #include <linux/dma-buf.h>
+#include <linux/dma-buf-mapping.h>
 #include <linux/dma-mapping.h>
 #include <linux/err.h>
 #include <linux/slab.h>
@@ -512,7 +513,8 @@ panthor_gem_prime_begin_cpu_access(struct dma_buf *dma_buf,
 		struct sg_table *sgt = attach->priv;
 
 		if (sgt)
-			dma_sync_sgtable_for_cpu(attach->dev, sgt, dir);
+			dma_sync_sgtable_for_cpu(dma_buf_sgt_dma_device(attach),
+						 sgt, dir);
 	}
 	dma_resv_unlock(obj->resv);
 
@@ -533,7 +535,8 @@ panthor_gem_prime_end_cpu_access(struct dma_buf *dma_buf,
 		struct sg_table *sgt = attach->priv;
 
 		if (sgt)
-			dma_sync_sgtable_for_device(attach->dev, sgt, dir);
+			dma_sync_sgtable_for_device(dma_buf_sgt_dma_device(attach),
+						    sgt, dir);
 	}
 
 	if (bo->cmap.vaddr)
@@ -549,14 +552,14 @@ panthor_gem_prime_end_cpu_access(struct dma_buf *dma_buf,
 static const struct dma_buf_ops panthor_dma_buf_ops = {
 	.attach = drm_gem_map_attach,
 	.detach = drm_gem_map_detach,
-	.map_dma_buf = panthor_gem_prime_map_dma_buf,
-	.unmap_dma_buf = panthor_gem_prime_unmap_dma_buf,
 	.release = drm_gem_dmabuf_release,
 	.mmap = drm_gem_dmabuf_mmap,
 	.vmap = drm_gem_dmabuf_vmap,
 	.vunmap = drm_gem_dmabuf_vunmap,
 	.begin_cpu_access = panthor_gem_prime_begin_cpu_access,
 	.end_cpu_access = panthor_gem_prime_end_cpu_access,
+	DMA_BUF_SIMPLE_SGT_EXP_MATCH(panthor_gem_prime_map_dma_buf,
+				     panthor_gem_prime_unmap_dma_buf),
 };
 
 static struct dma_buf *
diff --git a/drivers/gpu/drm/tegra/gem.c b/drivers/gpu/drm/tegra/gem.c
index f76af733ea79..feb783ceb0d1 100644
--- a/drivers/gpu/drm/tegra/gem.c
+++ b/drivers/gpu/drm/tegra/gem.c
@@ -11,6 +11,7 @@
  */
 
 #include <linux/dma-buf.h>
+#include <linux/dma-buf-mapping.h>
 #include <linux/iommu.h>
 #include <linux/module.h>
 #include <linux/pagemap.h>
@@ -630,6 +631,7 @@ static struct sg_table *
 tegra_gem_prime_map_dma_buf(struct dma_buf_attachment *attach,
 			    enum dma_data_direction dir)
 {
+	struct device *dma_dev = dma_buf_sgt_dma_device(attach);
 	struct drm_gem_object *gem = attach->dmabuf->priv;
 	struct tegra_bo *bo = to_tegra_bo(gem);
 	struct sg_table *sgt;
@@ -643,12 +645,12 @@ tegra_gem_prime_map_dma_buf(struct dma_buf_attachment *attach,
 					      0, gem->size, GFP_KERNEL) < 0)
 			goto free;
 	} else {
-		if (dma_get_sgtable(attach->dev, sgt, bo->vaddr, bo->iova,
+		if (dma_get_sgtable(dma_dev, sgt, bo->vaddr, bo->iova,
 				    gem->size) < 0)
 			goto free;
 	}
 
-	if (dma_map_sgtable(attach->dev, sgt, dir, 0))
+	if (dma_map_sgtable(dma_dev, sgt, dir, 0))
 		goto free;
 
 	return sgt;
@@ -667,7 +669,7 @@ static void tegra_gem_prime_unmap_dma_buf(struct dma_buf_attachment *attach,
 	struct tegra_bo *bo = to_tegra_bo(gem);
 
 	if (bo->pages)
-		dma_unmap_sgtable(attach->dev, sgt, dir, 0);
+		dma_unmap_sgtable(dma_buf_sgt_dma_device(attach), sgt, dir, 0);
 
 	sg_free_table(sgt);
 	kfree(sgt);
@@ -740,14 +742,14 @@ static void tegra_gem_prime_vunmap(struct dma_buf *buf, struct iosys_map *map)
 }
 
 static const struct dma_buf_ops tegra_gem_prime_dmabuf_ops = {
-	.map_dma_buf = tegra_gem_prime_map_dma_buf,
-	.unmap_dma_buf = tegra_gem_prime_unmap_dma_buf,
 	.release = tegra_gem_prime_release,
 	.begin_cpu_access = tegra_gem_prime_begin_cpu_access,
 	.end_cpu_access = tegra_gem_prime_end_cpu_access,
 	.mmap = tegra_gem_prime_mmap,
 	.vmap = tegra_gem_prime_vmap,
 	.vunmap = tegra_gem_prime_vunmap,
+	DMA_BUF_SIMPLE_SGT_EXP_MATCH(tegra_gem_prime_map_dma_buf,
+				     tegra_gem_prime_unmap_dma_buf),
 };
 
 struct dma_buf *tegra_gem_prime_export(struct drm_gem_object *gem,
diff --git a/drivers/gpu/drm/virtio/virtgpu_prime.c b/drivers/gpu/drm/virtio/virtgpu_prime.c
index ebf471044d06..3d5203ac19b6 100644
--- a/drivers/gpu/drm/virtio/virtgpu_prime.c
+++ b/drivers/gpu/drm/virtio/virtgpu_prime.c
@@ -24,6 +24,7 @@
 
 #include <drm/drm_prime.h>
 #include <drm/drm_print.h>
+#include <linux/dma-buf-mapping.h>
 #include <linux/virtio_dma_buf.h>
 
 #include "virtgpu_drv.h"
@@ -54,7 +55,8 @@ virtgpu_gem_map_dma_buf(struct dma_buf_attachment *attach,
 	struct virtio_gpu_object *bo = gem_to_virtio_gpu_obj(obj);
 
 	if (virtio_gpu_is_vram(bo))
-		return virtio_gpu_vram_map_dma_buf(bo, attach->dev, dir);
+		return virtio_gpu_vram_map_dma_buf(
+			bo, dma_buf_sgt_dma_device(attach), dir);
 
 	return drm_gem_map_dma_buf(attach, dir);
 }
@@ -67,7 +69,8 @@ static void virtgpu_gem_unmap_dma_buf(struct dma_buf_attachment *attach,
 	struct virtio_gpu_object *bo = gem_to_virtio_gpu_obj(obj);
 
 	if (virtio_gpu_is_vram(bo)) {
-		virtio_gpu_vram_unmap_dma_buf(attach->dev, sgt, dir);
+		virtio_gpu_vram_unmap_dma_buf(dma_buf_sgt_dma_device(attach),
+					      sgt, dir);
 		return;
 	}
 
@@ -78,12 +81,12 @@ static const struct virtio_dma_buf_ops virtgpu_dmabuf_ops =  {
 	.ops = {
 		.attach = virtio_dma_buf_attach,
 		.detach = drm_gem_map_detach,
-		.map_dma_buf = virtgpu_gem_map_dma_buf,
-		.unmap_dma_buf = virtgpu_gem_unmap_dma_buf,
 		.release = drm_gem_dmabuf_release,
 		.mmap = drm_gem_dmabuf_mmap,
 		.vmap = drm_gem_dmabuf_vmap,
 		.vunmap = drm_gem_dmabuf_vunmap,
+		DMA_BUF_SIMPLE_SGT_EXP_MATCH(virtgpu_gem_map_dma_buf,
+					     virtgpu_gem_unmap_dma_buf),
 	},
 	.device_attach = drm_gem_map_attach,
 	.get_uuid = virtgpu_virtio_get_uuid,
diff --git a/drivers/iommu/iommufd/selftest.c b/drivers/iommu/iommufd/selftest.c
index f6da927461b5..f8afbbeb360f 100644
--- a/drivers/iommu/iommufd/selftest.c
+++ b/drivers/iommu/iommufd/selftest.c
@@ -6,6 +6,7 @@
 #include <linux/anon_inodes.h>
 #include <linux/debugfs.h>
 #include <linux/dma-buf.h>
+#include <linux/dma-buf-mapping.h>
 #include <linux/dma-resv.h>
 #include <linux/fault-inject.h>
 #include <linux/file.h>
@@ -1962,17 +1963,6 @@ struct iommufd_test_dma_buf {
 	bool revoked;
 };
 
-static int iommufd_test_dma_buf_attach(struct dma_buf *dmabuf,
-				       struct dma_buf_attachment *attachment)
-{
-	return 0;
-}
-
-static void iommufd_test_dma_buf_detach(struct dma_buf *dmabuf,
-					struct dma_buf_attachment *attachment)
-{
-}
-
 static struct sg_table *
 iommufd_test_dma_buf_map(struct dma_buf_attachment *attachment,
 			 enum dma_data_direction dir)
@@ -1995,11 +1985,9 @@ static void iommufd_test_dma_buf_release(struct dma_buf *dmabuf)
 }
 
 static const struct dma_buf_ops iommufd_test_dmabuf_ops = {
-	.attach = iommufd_test_dma_buf_attach,
-	.detach = iommufd_test_dma_buf_detach,
-	.map_dma_buf = iommufd_test_dma_buf_map,
 	.release = iommufd_test_dma_buf_release,
-	.unmap_dma_buf = iommufd_test_dma_buf_unmap,
+	DMA_BUF_SIMPLE_SGT_EXP_MATCH(iommufd_test_dma_buf_map,
+				     iommufd_test_dma_buf_unmap),
 };
 
 int iommufd_test_dma_buf_iommufd_map(struct dma_buf_attachment *attachment,
diff --git a/drivers/media/common/videobuf2/videobuf2-dma-contig.c b/drivers/media/common/videobuf2/videobuf2-dma-contig.c
index 9ce6284cd5f2..536f839258c6 100644
--- a/drivers/media/common/videobuf2/videobuf2-dma-contig.c
+++ b/drivers/media/common/videobuf2/videobuf2-dma-contig.c
@@ -11,6 +11,7 @@
  */
 
 #include <linux/dma-buf.h>
+#include <linux/dma-buf-mapping.h>
 #include <linux/module.h>
 #include <linux/refcount.h>
 #include <linux/scatterlist.h>
@@ -372,8 +373,8 @@ static void vb2_dc_dmabuf_ops_detach(struct dma_buf *dbuf,
 		 * memory locations do not require any explicit cache
 		 * maintenance prior or after being used by the device.
 		 */
-		dma_unmap_sgtable(db_attach->dev, sgt, attach->dma_dir,
-				  DMA_ATTR_SKIP_CPU_SYNC);
+		dma_unmap_sgtable(dma_buf_sgt_dma_device(db_attach), sgt,
+				  attach->dma_dir, DMA_ATTR_SKIP_CPU_SYNC);
 	sg_free_table(sgt);
 	kfree(attach);
 	db_attach->priv = NULL;
@@ -392,8 +393,8 @@ static struct sg_table *vb2_dc_dmabuf_ops_map(
 
 	/* release any previous cache */
 	if (attach->dma_dir != DMA_NONE) {
-		dma_unmap_sgtable(db_attach->dev, sgt, attach->dma_dir,
-				  DMA_ATTR_SKIP_CPU_SYNC);
+		dma_unmap_sgtable(dma_buf_sgt_dma_device(db_attach), sgt,
+				  attach->dma_dir, DMA_ATTR_SKIP_CPU_SYNC);
 		attach->dma_dir = DMA_NONE;
 	}
 
@@ -401,7 +402,7 @@ static struct sg_table *vb2_dc_dmabuf_ops_map(
 	 * mapping to the client with new direction, no cache sync
 	 * required see comment in vb2_dc_dmabuf_ops_detach()
 	 */
-	if (dma_map_sgtable(db_attach->dev, sgt, dma_dir,
+	if (dma_map_sgtable(dma_buf_sgt_dma_device(db_attach), sgt, dma_dir,
 			    DMA_ATTR_SKIP_CPU_SYNC)) {
 		pr_err("failed to map scatterlist\n");
 		return ERR_PTR(-EIO);
@@ -462,13 +463,13 @@ static int vb2_dc_dmabuf_ops_mmap(struct dma_buf *dbuf,
 static const struct dma_buf_ops vb2_dc_dmabuf_ops = {
 	.attach = vb2_dc_dmabuf_ops_attach,
 	.detach = vb2_dc_dmabuf_ops_detach,
-	.map_dma_buf = vb2_dc_dmabuf_ops_map,
-	.unmap_dma_buf = vb2_dc_dmabuf_ops_unmap,
 	.begin_cpu_access = vb2_dc_dmabuf_ops_begin_cpu_access,
 	.end_cpu_access = vb2_dc_dmabuf_ops_end_cpu_access,
 	.vmap = vb2_dc_dmabuf_ops_vmap,
 	.mmap = vb2_dc_dmabuf_ops_mmap,
 	.release = vb2_dc_dmabuf_ops_release,
+	DMA_BUF_SIMPLE_SGT_EXP_MATCH(vb2_dc_dmabuf_ops_map,
+				     vb2_dc_dmabuf_ops_unmap),
 };
 
 static struct sg_table *vb2_dc_get_base_sgt(struct vb2_dc_buf *buf)
diff --git a/drivers/media/common/videobuf2/videobuf2-dma-sg.c b/drivers/media/common/videobuf2/videobuf2-dma-sg.c
index b1d0695cda26..fba2027e6e8d 100644
--- a/drivers/media/common/videobuf2/videobuf2-dma-sg.c
+++ b/drivers/media/common/videobuf2/videobuf2-dma-sg.c
@@ -10,6 +10,7 @@
  * the Free Software Foundation.
  */
 
+#include <linux/dma-buf-mapping.h>
 #include <linux/module.h>
 #include <linux/mm.h>
 #include <linux/refcount.h>
@@ -417,7 +418,8 @@ static void vb2_dma_sg_dmabuf_ops_detach(struct dma_buf *dbuf,
 
 	/* release the scatterlist cache */
 	if (attach->dma_dir != DMA_NONE)
-		dma_unmap_sgtable(db_attach->dev, sgt, attach->dma_dir, 0);
+		dma_unmap_sgtable(dma_buf_sgt_dma_device(db_attach), sgt,
+				  attach->dma_dir, 0);
 	sg_free_table(sgt);
 	kfree(attach);
 	db_attach->priv = NULL;
@@ -436,12 +438,14 @@ static struct sg_table *vb2_dma_sg_dmabuf_ops_map(
 
 	/* release any previous cache */
 	if (attach->dma_dir != DMA_NONE) {
-		dma_unmap_sgtable(db_attach->dev, sgt, attach->dma_dir, 0);
+		dma_unmap_sgtable(dma_buf_sgt_dma_device(db_attach), sgt,
+				  attach->dma_dir, 0);
 		attach->dma_dir = DMA_NONE;
 	}
 
 	/* mapping to the client with new direction */
-	if (dma_map_sgtable(db_attach->dev, sgt, dma_dir, 0)) {
+	if (dma_map_sgtable(dma_buf_sgt_dma_device(db_attach), sgt, dma_dir,
+			    0)) {
 		pr_err("failed to map scatterlist\n");
 		return ERR_PTR(-EIO);
 	}
@@ -510,13 +514,13 @@ static int vb2_dma_sg_dmabuf_ops_mmap(struct dma_buf *dbuf,
 static const struct dma_buf_ops vb2_dma_sg_dmabuf_ops = {
 	.attach = vb2_dma_sg_dmabuf_ops_attach,
 	.detach = vb2_dma_sg_dmabuf_ops_detach,
-	.map_dma_buf = vb2_dma_sg_dmabuf_ops_map,
-	.unmap_dma_buf = vb2_dma_sg_dmabuf_ops_unmap,
 	.begin_cpu_access = vb2_dma_sg_dmabuf_ops_begin_cpu_access,
 	.end_cpu_access = vb2_dma_sg_dmabuf_ops_end_cpu_access,
 	.vmap = vb2_dma_sg_dmabuf_ops_vmap,
 	.mmap = vb2_dma_sg_dmabuf_ops_mmap,
 	.release = vb2_dma_sg_dmabuf_ops_release,
+	DMA_BUF_SIMPLE_SGT_EXP_MATCH(vb2_dma_sg_dmabuf_ops_map,
+				     vb2_dma_sg_dmabuf_ops_unmap),
 };
 
 static struct dma_buf *vb2_dma_sg_get_dmabuf(struct vb2_buffer *vb,
diff --git a/drivers/media/common/videobuf2/videobuf2-vmalloc.c b/drivers/media/common/videobuf2/videobuf2-vmalloc.c
index 63f023696f3e..d79acf83286a 100644
--- a/drivers/media/common/videobuf2/videobuf2-vmalloc.c
+++ b/drivers/media/common/videobuf2/videobuf2-vmalloc.c
@@ -10,6 +10,7 @@
  * the Free Software Foundation.
  */
 
+#include <linux/dma-buf-mapping.h>
 #include <linux/io.h>
 #include <linux/module.h>
 #include <linux/mm.h>
@@ -261,7 +262,8 @@ static void vb2_vmalloc_dmabuf_ops_detach(struct dma_buf *dbuf,
 
 	/* release the scatterlist cache */
 	if (attach->dma_dir != DMA_NONE)
-		dma_unmap_sgtable(db_attach->dev, sgt, attach->dma_dir, 0);
+		dma_unmap_sgtable(dma_buf_sgt_dma_device(db_attach), sgt,
+				  attach->dma_dir, 0);
 	sg_free_table(sgt);
 	kfree(attach);
 	db_attach->priv = NULL;
@@ -270,6 +272,7 @@ static void vb2_vmalloc_dmabuf_ops_detach(struct dma_buf *dbuf,
 static struct sg_table *vb2_vmalloc_dmabuf_ops_map(
 	struct dma_buf_attachment *db_attach, enum dma_data_direction dma_dir)
 {
+	struct device *dma_dev = dma_buf_sgt_dma_device(db_attach);
 	struct vb2_vmalloc_attachment *attach = db_attach->priv;
 	struct sg_table *sgt;
 
@@ -280,12 +283,12 @@ static struct sg_table *vb2_vmalloc_dmabuf_ops_map(
 
 	/* release any previous cache */
 	if (attach->dma_dir != DMA_NONE) {
-		dma_unmap_sgtable(db_attach->dev, sgt, attach->dma_dir, 0);
+		dma_unmap_sgtable(dma_dev, sgt, attach->dma_dir, 0);
 		attach->dma_dir = DMA_NONE;
 	}
 
 	/* mapping to the client with new direction */
-	if (dma_map_sgtable(db_attach->dev, sgt, dma_dir, 0)) {
+	if (dma_map_sgtable(dma_dev, sgt, dma_dir, 0)) {
 		pr_err("failed to map scatterlist\n");
 		return ERR_PTR(-EIO);
 	}
@@ -326,11 +329,11 @@ static int vb2_vmalloc_dmabuf_ops_mmap(struct dma_buf *dbuf,
 static const struct dma_buf_ops vb2_vmalloc_dmabuf_ops = {
 	.attach = vb2_vmalloc_dmabuf_ops_attach,
 	.detach = vb2_vmalloc_dmabuf_ops_detach,
-	.map_dma_buf = vb2_vmalloc_dmabuf_ops_map,
-	.unmap_dma_buf = vb2_vmalloc_dmabuf_ops_unmap,
 	.vmap = vb2_vmalloc_dmabuf_ops_vmap,
 	.mmap = vb2_vmalloc_dmabuf_ops_mmap,
 	.release = vb2_vmalloc_dmabuf_ops_release,
+	DMA_BUF_SIMPLE_SGT_EXP_MATCH(vb2_vmalloc_dmabuf_ops_map,
+				     vb2_vmalloc_dmabuf_ops_unmap),
 };
 
 static struct dma_buf *vb2_vmalloc_get_dmabuf(struct vb2_buffer *vb,
diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c
index d4fac2caca86..85fed3a12f9c 100644
--- a/drivers/misc/fastrpc.c
+++ b/drivers/misc/fastrpc.c
@@ -5,6 +5,7 @@
 #include <linux/completion.h>
 #include <linux/device.h>
 #include <linux/dma-buf.h>
+#include <linux/dma-buf-mapping.h>
 #include <linux/dma-mapping.h>
 #include <linux/dma-resv.h>
 #include <linux/idr.h>
@@ -778,7 +779,8 @@ fastrpc_map_dma_buf(struct dma_buf_attachment *attachment,
 
 	table = &a->sgt;
 
-	ret = dma_map_sgtable(attachment->dev, table, dir, 0);
+	ret = dma_map_sgtable(dma_buf_sgt_dma_device(attachment), table, dir,
+			      0);
 	if (ret)
 		table = ERR_PTR(ret);
 	return table;
@@ -788,7 +790,7 @@ static void fastrpc_unmap_dma_buf(struct dma_buf_attachment *attach,
 				  struct sg_table *table,
 				  enum dma_data_direction dir)
 {
-	dma_unmap_sgtable(attach->dev, table, dir, 0);
+	dma_unmap_sgtable(dma_buf_sgt_dma_device(attach), table, dir, 0);
 }
 
 static void fastrpc_release(struct dma_buf *dmabuf)
@@ -818,7 +820,7 @@ static int fastrpc_dma_buf_attach(struct dma_buf *dmabuf,
 		return -EINVAL;
 	}
 
-	a->dev = attachment->dev;
+	a->dev = dma_buf_sgt_dma_device(attachment);
 	INIT_LIST_HEAD(&a->node);
 	attachment->priv = a;
 
@@ -866,11 +868,11 @@ static int fastrpc_mmap(struct dma_buf *dmabuf,
 static const struct dma_buf_ops fastrpc_dma_buf_ops = {
 	.attach = fastrpc_dma_buf_attach,
 	.detach = fastrpc_dma_buf_detatch,
-	.map_dma_buf = fastrpc_map_dma_buf,
-	.unmap_dma_buf = fastrpc_unmap_dma_buf,
 	.mmap = fastrpc_mmap,
 	.vmap = fastrpc_vmap,
 	.release = fastrpc_release,
+	DMA_BUF_SIMPLE_SGT_EXP_MATCH(fastrpc_map_dma_buf,
+				     fastrpc_unmap_dma_buf),
 };
 
 static dma_addr_t fastrpc_compute_dma_addr(struct fastrpc_user *fl, dma_addr_t sg_dma_addr)
diff --git a/drivers/tee/tee_heap.c b/drivers/tee/tee_heap.c
index 007c00156520..099b153087a3 100644
--- a/drivers/tee/tee_heap.c
+++ b/drivers/tee/tee_heap.c
@@ -4,6 +4,7 @@
  */
 
 #include <linux/dma-buf.h>
+#include <linux/dma-buf-mapping.h>
 #include <linux/dma-heap.h>
 #include <linux/genalloc.h>
 #include <linux/module.h>
@@ -104,7 +105,7 @@ static int tee_heap_attach(struct dma_buf *dmabuf,
 		return ret;
 	}
 
-	a->dev = attachment->dev;
+	a->dev = dma_buf_sgt_dma_device(attachment);
 	attachment->priv = a;
 
 	return 0;
@@ -126,8 +127,8 @@ tee_heap_map_dma_buf(struct dma_buf_attachment *attachment,
 	struct tee_heap_attachment *a = attachment->priv;
 	int ret;
 
-	ret = dma_map_sgtable(attachment->dev, &a->table, direction,
-			      DMA_ATTR_SKIP_CPU_SYNC);
+	ret = dma_map_sgtable(dma_buf_sgt_dma_device(attachment), &a->table,
+			      direction, DMA_ATTR_SKIP_CPU_SYNC);
 	if (ret)
 		return ERR_PTR(ret);
 
@@ -142,7 +143,7 @@ static void tee_heap_unmap_dma_buf(struct dma_buf_attachment *attachment,
 
 	WARN_ON(&a->table != table);
 
-	dma_unmap_sgtable(attachment->dev, table, direction,
+	dma_unmap_sgtable(dma_buf_sgt_dma_device(attachment), table, direction,
 			  DMA_ATTR_SKIP_CPU_SYNC);
 }
 
@@ -160,9 +161,9 @@ static void tee_heap_buf_free(struct dma_buf *dmabuf)
 static const struct dma_buf_ops tee_heap_buf_ops = {
 	.attach = tee_heap_attach,
 	.detach = tee_heap_detach,
-	.map_dma_buf = tee_heap_map_dma_buf,
-	.unmap_dma_buf = tee_heap_unmap_dma_buf,
 	.release = tee_heap_buf_free,
+	DMA_BUF_SIMPLE_SGT_EXP_MATCH(tee_heap_map_dma_buf,
+				     tee_heap_unmap_dma_buf),
 };
 
 static struct dma_buf *tee_dma_heap_alloc(struct dma_heap *heap,
diff --git a/drivers/xen/gntdev-dmabuf.c b/drivers/xen/gntdev-dmabuf.c
index 83b0df460894..028cd7295fd7 100644
--- a/drivers/xen/gntdev-dmabuf.c
+++ b/drivers/xen/gntdev-dmabuf.c
@@ -11,6 +11,7 @@
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/dma-buf.h>
+#include <linux/dma-buf-mapping.h>
 #include <linux/dma-direct.h>
 #include <linux/slab.h>
 #include <linux/types.h>
@@ -241,9 +242,10 @@ static void dmabuf_exp_ops_detach(struct dma_buf *dma_buf,
 
 		if (sgt) {
 			if (gntdev_dmabuf_attach->dir != DMA_NONE)
-				dma_unmap_sgtable(attach->dev, sgt,
-						  gntdev_dmabuf_attach->dir,
-						  DMA_ATTR_SKIP_CPU_SYNC);
+				dma_unmap_sgtable(
+					dma_buf_sgt_dma_device(attach), sgt,
+					gntdev_dmabuf_attach->dir,
+					DMA_ATTR_SKIP_CPU_SYNC);
 			sg_free_table(sgt);
 		}
 
@@ -257,12 +259,13 @@ static struct sg_table *
 dmabuf_exp_ops_map_dma_buf(struct dma_buf_attachment *attach,
 			   enum dma_data_direction dir)
 {
+	struct device *dma_dev = dma_buf_sgt_dma_device(attach);
 	struct gntdev_dmabuf_attachment *gntdev_dmabuf_attach = attach->priv;
 	struct gntdev_dmabuf *gntdev_dmabuf = attach->dmabuf->priv;
 	struct sg_table *sgt;
 
 	pr_debug("Mapping %d pages for dev %p\n", gntdev_dmabuf->nr_pages,
-		 attach->dev);
+		 dma_dev);
 
 	if (dir == DMA_NONE || !gntdev_dmabuf_attach)
 		return ERR_PTR(-EINVAL);
@@ -281,7 +284,7 @@ dmabuf_exp_ops_map_dma_buf(struct dma_buf_attachment *attach,
 	sgt = dmabuf_pages_to_sgt(gntdev_dmabuf->pages,
 				  gntdev_dmabuf->nr_pages);
 	if (!IS_ERR(sgt)) {
-		if (dma_map_sgtable(attach->dev, sgt, dir,
+		if (dma_map_sgtable(dma_dev, sgt, dir,
 				    DMA_ATTR_SKIP_CPU_SYNC)) {
 			sg_free_table(sgt);
 			kfree(sgt);
@@ -292,7 +295,7 @@ dmabuf_exp_ops_map_dma_buf(struct dma_buf_attachment *attach,
 		}
 	}
 	if (IS_ERR(sgt))
-		pr_debug("Failed to map sg table for dev %p\n", attach->dev);
+		pr_debug("Failed to map sg table for dev %p\n", dma_dev);
 	return sgt;
 }
 
@@ -338,9 +341,9 @@ static void dmabuf_exp_ops_release(struct dma_buf *dma_buf)
 static const struct dma_buf_ops dmabuf_exp_ops =  {
 	.attach = dmabuf_exp_ops_attach,
 	.detach = dmabuf_exp_ops_detach,
-	.map_dma_buf = dmabuf_exp_ops_map_dma_buf,
-	.unmap_dma_buf = dmabuf_exp_ops_unmap_dma_buf,
 	.release = dmabuf_exp_ops_release,
+	DMA_BUF_SIMPLE_SGT_EXP_MATCH(dmabuf_exp_ops_map_dma_buf,
+				     dmabuf_exp_ops_unmap_dma_buf),
 };
 
 struct gntdev_dmabuf_export_args {
diff --git a/samples/vfio-mdev/mbochs.c b/samples/vfio-mdev/mbochs.c
index 64ea19253ee3..c2eaa14b9ddd 100644
--- a/samples/vfio-mdev/mbochs.c
+++ b/samples/vfio-mdev/mbochs.c
@@ -32,6 +32,7 @@
 #include <linux/pci.h>
 #include <linux/dma-buf.h>
 #include <linux/highmem.h>
+#include <linux/dma-buf-mapping.h>
 #include <drm/drm_fourcc.h>
 #include <drm/drm_rect.h>
 #include <drm/drm_modeset_lock.h>
@@ -872,7 +873,7 @@ static struct sg_table *mbochs_map_dmabuf(struct dma_buf_attachment *at,
 	if (sg_alloc_table_from_pages(sg, dmabuf->pages, dmabuf->pagecount,
 				      0, dmabuf->mode.size, GFP_KERNEL) < 0)
 		goto err2;
-	if (dma_map_sgtable(at->dev, sg, direction, 0))
+	if (dma_map_sgtable(dma_buf_sgt_dma_device(at), sg, direction, 0))
 		goto err3;
 
 	return sg;
@@ -894,7 +895,7 @@ static void mbochs_unmap_dmabuf(struct dma_buf_attachment *at,
 
 	dev_dbg(dev, "%s: %d\n", __func__, dmabuf->id);
 
-	dma_unmap_sgtable(at->dev, sg, direction, 0);
+	dma_unmap_sgtable(dma_buf_sgt_dma_device(at), sg, direction, 0);
 	sg_free_table(sg);
 	kfree(sg);
 }
@@ -918,11 +919,10 @@ static void mbochs_release_dmabuf(struct dma_buf *buf)
 	mutex_unlock(&mdev_state->ops_lock);
 }
 
-static struct dma_buf_ops mbochs_dmabuf_ops = {
-	.map_dma_buf	  = mbochs_map_dmabuf,
-	.unmap_dma_buf	  = mbochs_unmap_dmabuf,
+static const struct dma_buf_ops mbochs_dmabuf_ops = {
 	.release	  = mbochs_release_dmabuf,
 	.mmap		  = mbochs_mmap_dmabuf,
+	DMA_BUF_SIMPLE_SGT_EXP_MATCH(mbochs_map_dmabuf, mbochs_unmap_dmabuf),
 };
 
 static struct mbochs_dmabuf *mbochs_dmabuf_alloc(struct mdev_state *mdev_state,
diff --git a/sound/soc/fsl/fsl_asrc_m2m.c b/sound/soc/fsl/fsl_asrc_m2m.c
index 4bc40f328f58..63cee7b2c206 100644
--- a/sound/soc/fsl/fsl_asrc_m2m.c
+++ b/sound/soc/fsl/fsl_asrc_m2m.c
@@ -7,6 +7,7 @@
 
 #include <linux/dma/imx-dma.h>
 #include <linux/dma-buf.h>
+#include <linux/dma-buf-mapping.h>
 #include <linux/dma-mapping.h>
 #include <linux/pm_runtime.h>
 #include <sound/asound.h>
@@ -417,6 +418,7 @@ static int fsl_asrc_m2m_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma)
 static struct sg_table *fsl_asrc_m2m_map_dma_buf(struct dma_buf_attachment *attachment,
 						 enum dma_data_direction direction)
 {
+	struct device *dma_dev = dma_buf_sgt_dma_device(attachment);
 	struct snd_dma_buffer *dmab = attachment->dmabuf->priv;
 	struct sg_table *sgt;
 
@@ -424,10 +426,10 @@ static struct sg_table *fsl_asrc_m2m_map_dma_buf(struct dma_buf_attachment *atta
 	if (!sgt)
 		return NULL;
 
-	if (dma_get_sgtable(attachment->dev, sgt, dmab->area, dmab->addr, dmab->bytes) < 0)
+	if (dma_get_sgtable(dma_dev, sgt, dmab->area, dmab->addr, dmab->bytes) < 0)
 		goto free;
 
-	if (dma_map_sgtable(attachment->dev, sgt, direction, 0))
+	if (dma_map_sgtable(dma_dev, sgt, direction, 0))
 		goto free;
 
 	return sgt;
@@ -442,7 +444,7 @@ static void fsl_asrc_m2m_unmap_dma_buf(struct dma_buf_attachment *attachment,
 				       struct sg_table *table,
 				       enum dma_data_direction direction)
 {
-	dma_unmap_sgtable(attachment->dev, table, direction, 0);
+	dma_unmap_sgtable(dma_buf_sgt_dma_device(attachment), table, direction, 0);
 }
 
 static void fsl_asrc_m2m_release(struct dma_buf *dmabuf)
@@ -452,9 +454,9 @@ static void fsl_asrc_m2m_release(struct dma_buf *dmabuf)
 
 static const struct dma_buf_ops fsl_asrc_m2m_dma_buf_ops = {
 	.mmap = fsl_asrc_m2m_mmap,
-	.map_dma_buf = fsl_asrc_m2m_map_dma_buf,
-	.unmap_dma_buf = fsl_asrc_m2m_unmap_dma_buf,
 	.release = fsl_asrc_m2m_release,
+	DMA_BUF_SIMPLE_SGT_EXP_MATCH(fsl_asrc_m2m_map_dma_buf,
+				     fsl_asrc_m2m_unmap_dma_buf),
 };
 
 static int fsl_asrc_m2m_comp_task_create(struct snd_compr_stream *stream,
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 71+ messages in thread

* [PATCH 11/26] drm/vmwgfx: Use match_mapping instead of dummy calls
  2026-10-26  5:35 [PATCH 00/26] DMA-buf mapping types Alistair Popple
                   ` (9 preceding siblings ...)
  2026-10-26  5:36 ` [PATCH 10/26] dma-buf: Convert all the simple exporters to use SGT mapping type Alistair Popple
@ 2026-10-26  5:36 ` Alistair Popple
  2026-10-26  8:13   ` sashiko-bot
  2026-10-26  5:36 ` [PATCH 12/26] accel/habanalabs: Use the SGT_P2P mapping type Alistair Popple
                   ` (14 subsequent siblings)
  25 siblings, 1 reply; 71+ messages in thread
From: Alistair Popple @ 2026-10-26  5:36 UTC (permalink / raw)
  To: dri-devel, christian.koenig, sumit.semwal, jgg
  Cc: Alistair Popple, Thomas Hellström, Simona Vetter,
	Matthew Brost, Vivek Kasireddy, Dongwon Kim, Leon Romanovsky,
	Kevin Tian, Xu Yilun, Karl Mehltretter, Baolu Lu, Felix Kuehling,
	Alex Deucher, intel-xe, amd-gfx, linux-media, linaro-mm-sig,
	linux-rdma, iommu, Alexey Kardashevskiy, zhipingz, treding,
	jhubbard

From: Jason Gunthorpe <jgg@nvidia.com>

vmwgfx is creating a DMA-buf that cannot be attached by providing
always fail functions for dma_buf_ops.

The attach/detach callbacks are already optional inside DMA-buf, but
dma_buf_export() is checking for non-null map/unmap callbacks.

Instead use the mapping type interface and provide an always fail
match_mapping(). Remove the unused SGT and attach/detach functions, they
can never be called if match_mapping() fails.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/gpu/drm/vmwgfx/vmwgfx_prime.c | 32 +++++----------------------
 1 file changed, 5 insertions(+), 27 deletions(-)

diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_prime.c b/drivers/gpu/drm/vmwgfx/vmwgfx_prime.c
index 598b90ac7590..90e4342a378d 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_prime.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_prime.c
@@ -35,41 +35,19 @@
 #include "vmwgfx_bo.h"
 #include "ttm_object.h"
 #include <linux/dma-buf.h>
+#include <linux/dma-buf-mapping.h>
 
 /*
- * DMA-BUF attach- and mapping methods. No need to implement
- * these until we have other virtual devices use them.
+ * No need to implement these until we have other virtual devices use them.
  */
-
-static int vmw_prime_map_attach(struct dma_buf *dma_buf,
-				struct dma_buf_attachment *attach)
-{
-	return -ENOSYS;
-}
-
-static void vmw_prime_map_detach(struct dma_buf *dma_buf,
-				 struct dma_buf_attachment *attach)
-{
-}
-
-static struct sg_table *vmw_prime_map_dma_buf(struct dma_buf_attachment *attach,
-					      enum dma_data_direction dir)
-{
-	return ERR_PTR(-ENOSYS);
-}
-
-static void vmw_prime_unmap_dma_buf(struct dma_buf_attachment *attach,
-				    struct sg_table *sgb,
-				    enum dma_data_direction dir)
+static int vmw_prime_match_mapping(struct dma_buf_match_args *args)
 {
+	return -EOPNOTSUPP;
 }
 
 const struct dma_buf_ops vmw_prime_dmabuf_ops =  {
-	.attach = vmw_prime_map_attach,
-	.detach = vmw_prime_map_detach,
-	.map_dma_buf = vmw_prime_map_dma_buf,
-	.unmap_dma_buf = vmw_prime_unmap_dma_buf,
 	.release = NULL,
+	.match_mapping = vmw_prime_match_mapping,
 };
 
 int vmw_prime_fd_to_handle(struct drm_device *dev,
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 71+ messages in thread

* [PATCH 12/26] accel/habanalabs: Use the SGT_P2P mapping type
  2026-10-26  5:35 [PATCH 00/26] DMA-buf mapping types Alistair Popple
                   ` (10 preceding siblings ...)
  2026-10-26  5:36 ` [PATCH 11/26] drm/vmwgfx: Use match_mapping instead of dummy calls Alistair Popple
@ 2026-10-26  5:36 ` Alistair Popple
  2026-10-26  8:18   ` sashiko-bot
  2026-10-26  5:36 ` [PATCH 13/26] drm/xe/dma-buf: Use the SGT " Alistair Popple
                   ` (13 subsequent siblings)
  25 siblings, 1 reply; 71+ messages in thread
From: Alistair Popple @ 2026-10-26  5:36 UTC (permalink / raw)
  To: dri-devel, christian.koenig, sumit.semwal, jgg
  Cc: Alistair Popple, Thomas Hellström, Simona Vetter,
	Matthew Brost, Vivek Kasireddy, Dongwon Kim, Leon Romanovsky,
	Kevin Tian, Xu Yilun, Karl Mehltretter, Baolu Lu, Felix Kuehling,
	Alex Deucher, intel-xe, amd-gfx, linux-media, linaro-mm-sig,
	linux-rdma, iommu, Alexey Kardashevskiy, zhipingz, treding,
	jhubbard

From: Jason Gunthorpe <jgg@nvidia.com>

habana has special code to check pci_p2pdma_distance() and rejects any
importer that cannot do P2P DMA to its MMIO.

Convert this directly to a SGT_P2P match which does the same check
inside the matching logic.

Someday this should be converted to use dma_buf_phys_vec_to_sgt() which
does the P2P checking correctly, for both direct and IOMMU based cases,
instead of this hack.

Remove the now empty attach function.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/accel/habanalabs/common/memory.c | 54 +++++++++++-------------
 1 file changed, 24 insertions(+), 30 deletions(-)

diff --git a/drivers/accel/habanalabs/common/memory.c b/drivers/accel/habanalabs/common/memory.c
index 361cff577381..6745af1328c1 100644
--- a/drivers/accel/habanalabs/common/memory.c
+++ b/drivers/accel/habanalabs/common/memory.c
@@ -9,10 +9,10 @@
 #include "habanalabs.h"
 #include "../include/hw_ip/mmu/mmu_general.h"
 
+#include <linux/dma-buf-mapping.h>
 #include <linux/uaccess.h>
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
-#include <linux/pci-p2pdma.h>
 
 MODULE_IMPORT_NS("DMA_BUF");
 
@@ -1704,23 +1704,6 @@ static struct sg_table *alloc_sgt_from_device_pages(struct hl_device *hdev, u64
 	return ERR_PTR(rc);
 }
 
-static int hl_dmabuf_attach(struct dma_buf *dmabuf,
-				struct dma_buf_attachment *attachment)
-{
-	struct hl_dmabuf_priv *hl_dmabuf;
-	struct hl_device *hdev;
-	int rc;
-
-	hl_dmabuf = dmabuf->priv;
-	hdev = hl_dmabuf->ctx->hdev;
-
-	rc = pci_p2pdma_distance(hdev->pdev, attachment->dev, true);
-
-	if (rc < 0)
-		attachment->peer2peer = false;
-	return 0;
-}
-
 static struct sg_table *hl_map_dmabuf(struct dma_buf_attachment *attachment,
 					enum dma_data_direction dir)
 {
@@ -1734,11 +1717,6 @@ static struct sg_table *hl_map_dmabuf(struct dma_buf_attachment *attachment,
 	hl_dmabuf = dma_buf->priv;
 	hdev = hl_dmabuf->ctx->hdev;
 
-	if (!attachment->peer2peer) {
-		dev_dbg(hdev->dev, "Failed to map dmabuf because p2p is disabled\n");
-		return ERR_PTR(-EPERM);
-	}
-
 	exported_size = hl_dmabuf->dmabuf->size;
 	offset = hl_dmabuf->offset;
 	phys_pg_pack = hl_dmabuf->phys_pg_pack;
@@ -1753,8 +1731,10 @@ static struct sg_table *hl_map_dmabuf(struct dma_buf_attachment *attachment,
 		page_size = hl_dmabuf->dmabuf->size;
 	}
 
-	sgt = alloc_sgt_from_device_pages(hdev, pages, npages, page_size, exported_size, offset,
-						attachment->dev, dir);
+	sgt = alloc_sgt_from_device_pages(hdev, pages, npages, page_size,
+					  exported_size, offset,
+					  dma_buf_sgt_dma_device(attachment),
+					  dir);
 	if (IS_ERR(sgt))
 		dev_err(hdev->dev, "failed (%ld) to initialize sgt for dmabuf\n", PTR_ERR(sgt));
 
@@ -1776,9 +1756,9 @@ static void hl_unmap_dmabuf(struct dma_buf_attachment *attachment,
 	 * a sync of the memory to the CPU's cache, as it never resided inside that cache.
 	 */
 	for_each_sgtable_dma_sg(sgt, sg, i)
-		dma_unmap_resource(attachment->dev, sg_dma_address(sg),
-					sg_dma_len(sg), dir,
-					DMA_ATTR_SKIP_CPU_SYNC);
+		dma_unmap_resource(dma_buf_sgt_dma_device(attachment),
+				   sg_dma_address(sg), sg_dma_len(sg), dir,
+				   DMA_ATTR_SKIP_CPU_SYNC);
 
 	/* Need to restore orig_nents because sg_free_table use that field */
 	sgt->orig_nents = sgt->nents;
@@ -1848,11 +1828,25 @@ static void hl_release_dmabuf(struct dma_buf *dmabuf)
 	kfree(hl_dmabuf);
 }
 
-static const struct dma_buf_ops habanalabs_dmabuf_ops = {
-	.attach = hl_dmabuf_attach,
+static const struct dma_buf_mapping_sgt_exp_ops hl_dma_buf_sgt_ops = {
 	.map_dma_buf = hl_map_dmabuf,
 	.unmap_dma_buf = hl_unmap_dmabuf,
+};
+
+static int hl_match_mapping(struct dma_buf_match_args *args)
+{
+	struct hl_dmabuf_priv *hl_dmabuf = args->dmabuf->priv;
+	struct dma_buf_mapping_match sgt_match[] = {
+		DMA_BUF_EMAPPING_SGT_P2P(&hl_dma_buf_sgt_ops,
+					 hl_dmabuf->ctx->hdev->pdev),
+	};
+
+	return dma_buf_match_mapping(args, sgt_match, ARRAY_SIZE(sgt_match));
+}
+
+static const struct dma_buf_ops habanalabs_dmabuf_ops = {
 	.release = hl_release_dmabuf,
+	.match_mapping = hl_match_mapping,
 };
 
 static int export_dmabuf(struct hl_ctx *ctx,
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 71+ messages in thread

* [PATCH 13/26] drm/xe/dma-buf: Use the SGT mapping type
  2026-10-26  5:35 [PATCH 00/26] DMA-buf mapping types Alistair Popple
                   ` (11 preceding siblings ...)
  2026-10-26  5:36 ` [PATCH 12/26] accel/habanalabs: Use the SGT_P2P mapping type Alistair Popple
@ 2026-10-26  5:36 ` Alistair Popple
  2026-10-26  8:34   ` sashiko-bot
  2026-10-26  5:36 ` [PATCH 14/26] drm/amdgpu: " Alistair Popple
                   ` (12 subsequent siblings)
  25 siblings, 1 reply; 71+ messages in thread
From: Alistair Popple @ 2026-10-26  5:36 UTC (permalink / raw)
  To: dri-devel, christian.koenig, sumit.semwal, jgg
  Cc: Alistair Popple, Thomas Hellström, Simona Vetter,
	Matthew Brost, Vivek Kasireddy, Dongwon Kim, Leon Romanovsky,
	Kevin Tian, Xu Yilun, Karl Mehltretter, Baolu Lu, Felix Kuehling,
	Alex Deucher, intel-xe, amd-gfx, linux-media, linaro-mm-sig,
	linux-rdma, iommu, Alexey Kardashevskiy, zhipingz, treding,
	jhubbard

From: Jason Gunthorpe <jgg@nvidia.com>

Like habana, xe wants to check pci_p2pdma_distance(), but unlike
habana, it can migrate to system memory and support non-p2p DMAs as well.

Add two exporter SGT mapping types, one that matches P2P and one that
matches all of the non-p2p. The pin and map code will force migrate if
the non-p2p one is matched.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
[ rebased onto v7.3-rc5: CONFIG_DMABUF_MOVE_NOTIFY no longer
  exists (609fc8766d68 "dma-buf: Always build with DMABUF_MOVE_NOTIFY"), so
  the IS_ENABLED() guards are dropped, the P2P match is always offered and
  xe_dma_buf_pin() only walks the attachments. dma_buf_match_mapping() is
  passed num_match rather than ARRAY_SIZE(sgt_match) so an unfilled entry
  is never read. Upstream's xe_dma_buf_release() is kept. The pin walk asks
  the other attachments what they accept with
  dma_buf_attach_accepts_sgt_p2p(), since those may not have selected a
  type yet; the attachment being pinned has just been selected and uses
  dma_buf_sgt_p2p_allowed(). - apopple ]
Signed-off-by: Alistair Popple <apopple@nvidia.com>
---
 drivers/gpu/drm/xe/xe_dma_buf.c | 62 ++++++++++++++++++++++-----------
 1 file changed, 41 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/xe/xe_dma_buf.c b/drivers/gpu/drm/xe/xe_dma_buf.c
index bf0728838ead..3ca198da6ee8 100644
--- a/drivers/gpu/drm/xe/xe_dma_buf.c
+++ b/drivers/gpu/drm/xe/xe_dma_buf.c
@@ -7,7 +7,7 @@
 
 #include <kunit/test.h>
 #include <linux/dma-buf.h>
-#include <linux/pci-p2pdma.h>
+#include <linux/dma-buf-mapping.h>
 
 #include <drm/drm_device.h>
 #include <drm/drm_prime.h>
@@ -27,13 +27,6 @@ static int xe_dma_buf_attach(struct dma_buf *dmabuf,
 {
 	struct drm_gem_object *obj = attach->dmabuf->priv;
 
-	if (attach->peer2peer &&
-	    pci_p2pdma_distance(to_pci_dev(obj->dev->dev), attach->dev, false) < 0)
-		attach->peer2peer = false;
-
-	if (!attach->peer2peer && !xe_bo_can_migrate(gem_to_xe_bo(obj), XE_PL_TT))
-		return -EOPNOTSUPP;
-
 	xe_pm_runtime_get(to_xe_device(obj->dev));
 	return 0;
 }
@@ -53,13 +46,16 @@ static int xe_dma_buf_pin(struct dma_buf_attachment *attach)
 	struct xe_bo *bo = gem_to_xe_bo(obj);
 	struct xe_device *xe = xe_bo_device(bo);
 	struct drm_exec *exec = XE_VALIDATION_UNSUPPORTED;
-	bool allow_vram = true;
+	bool allow_vram = dma_buf_sgt_p2p_allowed(attach);
 	int ret;
 
-	list_for_each_entry(attach, &dmabuf->attachments, node) {
-		if (!attach->peer2peer) {
-			allow_vram = false;
-			break;
+	if (allow_vram) {
+		/* Other attachments may be unmapped: ask what they accept */
+		list_for_each_entry(attach, &dmabuf->attachments, node) {
+			if (!dma_buf_attach_accepts_sgt_p2p(attach)) {
+				allow_vram = false;
+				break;
+			}
 		}
 	}
 
@@ -97,6 +93,8 @@ static void xe_dma_buf_unpin(struct dma_buf_attachment *attach)
 static struct sg_table *xe_dma_buf_map(struct dma_buf_attachment *attach,
 				       enum dma_data_direction dir)
 {
+	struct device *dma_dev = dma_buf_sgt_dma_device(attach);
+	bool peer2peer = dma_buf_sgt_p2p_allowed(attach);
 	struct dma_buf *dma_buf = attach->dmabuf;
 	struct drm_gem_object *obj = dma_buf->priv;
 	struct xe_bo *bo = gem_to_xe_bo(obj);
@@ -104,11 +102,11 @@ static struct sg_table *xe_dma_buf_map(struct dma_buf_attachment *attach,
 	struct sg_table *sgt;
 	int r = 0;
 
-	if (!attach->peer2peer && !xe_bo_can_migrate(bo, XE_PL_TT))
+	if (!peer2peer && !xe_bo_can_migrate(bo, XE_PL_TT))
 		return ERR_PTR(-EOPNOTSUPP);
 
 	if (!xe_bo_is_pinned(bo)) {
-		if (!attach->peer2peer)
+		if (!peer2peer)
 			r = xe_bo_migrate(bo, XE_PL_TT, NULL, exec);
 		else
 			r = xe_bo_validate(bo, NULL, false, exec);
@@ -124,7 +122,7 @@ static struct sg_table *xe_dma_buf_map(struct dma_buf_attachment *attach,
 		if (IS_ERR(sgt))
 			return sgt;
 
-		if (dma_map_sgtable(attach->dev, sgt, dir,
+		if (dma_map_sgtable(dma_dev, sgt, dir,
 				    DMA_ATTR_SKIP_CPU_SYNC))
 			goto error_free;
 		break;
@@ -133,7 +131,7 @@ static struct sg_table *xe_dma_buf_map(struct dma_buf_attachment *attach,
 	case XE_PL_VRAM1:
 		r = xe_ttm_vram_mgr_alloc_sgt(xe_bo_device(bo),
 					      bo->ttm.resource, 0,
-					      bo->ttm.base.size, attach->dev,
+					      bo->ttm.base.size, dma_dev,
 					      dir, &sgt);
 		if (r)
 			return ERR_PTR(r);
@@ -154,12 +152,14 @@ static void xe_dma_buf_unmap(struct dma_buf_attachment *attach,
 			     struct sg_table *sgt,
 			     enum dma_data_direction dir)
 {
+	struct device *dma_dev = dma_buf_sgt_dma_device(attach);
+
 	if (sg_page(sgt->sgl)) {
-		dma_unmap_sgtable(attach->dev, sgt, dir, 0);
+		dma_unmap_sgtable(dma_dev, sgt, dir, 0);
 		sg_free_table(sgt);
 		kfree(sgt);
 	} else {
-		xe_ttm_vram_mgr_free_sgt(attach->dev, dir, sgt);
+		xe_ttm_vram_mgr_free_sgt(dma_dev, dir, sgt);
 	}
 }
 
@@ -205,18 +205,38 @@ static void xe_dma_buf_release(struct dma_buf *dmabuf)
 	drm_gem_dmabuf_release(dmabuf);
 }
 
+static const struct dma_buf_mapping_sgt_exp_ops xe_dma_buf_sgt_ops = {
+	.map_dma_buf = xe_dma_buf_map,
+	.unmap_dma_buf = xe_dma_buf_unmap,
+};
+
+static int xe_dma_buf_match_mapping(struct dma_buf_match_args *args)
+{
+	struct drm_gem_object *obj = args->dmabuf->priv;
+	struct dma_buf_mapping_match sgt_match[2];
+	unsigned int num_match = 0;
+
+	sgt_match[num_match++] = DMA_BUF_EMAPPING_SGT_P2P(
+		&xe_dma_buf_sgt_ops, to_pci_dev(obj->dev->dev));
+
+	if (xe_bo_can_migrate(gem_to_xe_bo(obj), XE_PL_TT))
+		sgt_match[num_match++] =
+			DMA_BUF_EMAPPING_SGT(&xe_dma_buf_sgt_ops);
+
+	return dma_buf_match_mapping(args, sgt_match, num_match);
+}
+
 static const struct dma_buf_ops xe_dmabuf_ops = {
 	.attach = xe_dma_buf_attach,
 	.detach = xe_dma_buf_detach,
 	.pin = xe_dma_buf_pin,
 	.unpin = xe_dma_buf_unpin,
-	.map_dma_buf = xe_dma_buf_map,
-	.unmap_dma_buf = xe_dma_buf_unmap,
 	.release = xe_dma_buf_release,
 	.begin_cpu_access = xe_dma_buf_begin_cpu_access,
 	.mmap = drm_gem_dmabuf_mmap,
 	.vmap = drm_gem_dmabuf_vmap,
 	.vunmap = drm_gem_dmabuf_vunmap,
+	.match_mapping = xe_dma_buf_match_mapping,
 };
 
 struct dma_buf *xe_gem_prime_export(struct drm_gem_object *obj, int flags)
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 71+ messages in thread

* [PATCH 14/26] drm/amdgpu: Use the SGT mapping type
  2026-10-26  5:35 [PATCH 00/26] DMA-buf mapping types Alistair Popple
                   ` (12 preceding siblings ...)
  2026-10-26  5:36 ` [PATCH 13/26] drm/xe/dma-buf: Use the SGT " Alistair Popple
@ 2026-10-26  5:36 ` Alistair Popple
  2026-10-26  8:46   ` sashiko-bot
  2026-10-26  5:36 ` [PATCH 15/26] vfio/pci: Change the DMA-buf exporter to use mapping_type Alistair Popple
                   ` (11 subsequent siblings)
  25 siblings, 1 reply; 71+ messages in thread
From: Alistair Popple @ 2026-10-26  5:36 UTC (permalink / raw)
  To: dri-devel, christian.koenig, sumit.semwal, jgg
  Cc: Alistair Popple, Thomas Hellström, Simona Vetter,
	Matthew Brost, Vivek Kasireddy, Dongwon Kim, Leon Romanovsky,
	Kevin Tian, Xu Yilun, Karl Mehltretter, Baolu Lu, Felix Kuehling,
	Alex Deucher, intel-xe, amd-gfx, linux-media, linaro-mm-sig,
	linux-rdma, iommu, Alexey Kardashevskiy, zhipingz, treding,
	jhubbard

From: Jason Gunthorpe <jgg@nvidia.com>

Similar to xe, amdgpu wants to check pci_p2pdma_distance(), and
only needs that if peer2peer can be supported by the GPU. It can migrate to
system memory and support non-p2p DMA as well.

Further it supports a private non-PCI XGMI path. For now hack this on top
of a SGT type, but eventually this is likely better off as its own mapping
type.

Add two exporter SGT mapping types, one that matches P2P and one that
matches all of the non-p2p. The pin and map code will force migrate if
the non-p2p one is matched.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
[ the match set is recorded in attach->matches and the type
  selected from it at pin or map, so the pin walk, detach and the attach
  error path ask dma_buf_attach_accepts_sgt_p2p() whether an attachment
  could take P2P at all, and the XGMI override rewrites the recorded match
  set entry rather than only attach->map_type. The map path keeps using
  dma_buf_sgt_p2p_allowed() for the attachment being mapped, which has just
  been selected. The runtime PM reference follows the same question: held
  while P2P is in the match set, dropped in detach. - apopple ]
Signed-off-by: Alistair Popple <apopple@nvidia.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c | 137 +++++++++++++-------
 1 file changed, 92 insertions(+), 45 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
index 9adf3eed8822..19ee9f85ff30 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
@@ -41,6 +41,7 @@
 #include <drm/amdgpu_drm.h>
 #include <drm/ttm/ttm_tt.h>
 #include <linux/dma-buf.h>
+#include <linux/dma-buf-mapping.h>
 #include <linux/dma-fence-array.h>
 #include <linux/pci-p2pdma.h>
 #include <linux/pm_runtime.h>
@@ -79,43 +80,11 @@ static struct amdgpu_device *dma_buf_attach_adev(struct dma_buf_attachment *atta
 static int amdgpu_dma_buf_attach(struct dma_buf *dmabuf,
 				 struct dma_buf_attachment *attach)
 {
-	struct amdgpu_device *attach_adev = dma_buf_attach_adev(attach);
 	struct drm_gem_object *obj = dmabuf->priv;
 	struct amdgpu_bo *bo = gem_to_amdgpu_bo(obj);
 	struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
 	int r;
 
-	/*
-	 * Disable peer-to-peer access for DCC-enabled VRAM surfaces on GFX12+.
-	 * Such buffers cannot be safely accessed over P2P due to device-local
-	 * compression metadata. Fallback to system-memory path instead.
-	 * Device supports GFX12 (GC 12.x or newer)
-	 * BO was created with the AMDGPU_GEM_CREATE_GFX12_DCC flag
-	 *
-	 */
-	if (amdgpu_ip_version(adev, GC_HWIP, 0) >= IP_VERSION(12, 0, 0) &&
-	    bo->flags & AMDGPU_GEM_CREATE_GFX12_DCC)
-		attach->peer2peer = false;
-
-	if (!amdgpu_dmabuf_is_xgmi_accessible(attach_adev, bo) &&
-	    pci_p2pdma_distance(adev->pdev, attach->dev, false) < 0)
-		attach->peer2peer = false;
-
-	/*
-	 * Only allow P2P while the exporter is active, and keep it active
-	 * until detach.  With runtime PM disabled take a plain reference so
-	 * the put in detach stays balanced.
-	 */
-	if (attach->peer2peer) {
-		struct device *dev = adev_to_drm(adev)->dev;
-		int ret = pm_runtime_get_if_active(dev);
-
-		if (!ret)
-			attach->peer2peer = false;
-		else if (ret < 0)
-			pm_runtime_get_noresume(dev);
-	}
-
 	r = dma_resv_lock(bo->tbo.base.resv, NULL);
 	if (r)
 		goto err_pm_put;
@@ -127,7 +96,8 @@ static int amdgpu_dma_buf_attach(struct dma_buf *dmabuf,
 	return 0;
 
 err_pm_put:
-	if (attach->peer2peer)
+	/* Drop the reference taken in amdgpu_dma_buf_match_mapping() */
+	if (dma_buf_attach_accepts_sgt_p2p(attach))
 		pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
 	return r;
 }
@@ -138,7 +108,7 @@ static int amdgpu_dma_buf_attach(struct dma_buf *dmabuf,
  * @dmabuf: DMA-buf where we remove the attachment from
  * @attach: the attachment to remove
  *
- * Drop the runtime PM reference taken in amdgpu_dma_buf_attach().
+ * Drop the runtime PM reference taken in amdgpu_dma_buf_match_mapping().
  */
 static void amdgpu_dma_buf_detach(struct dma_buf *dmabuf,
 				  struct dma_buf_attachment *attach)
@@ -147,7 +117,7 @@ static void amdgpu_dma_buf_detach(struct dma_buf *dmabuf,
 	struct amdgpu_bo *bo = gem_to_amdgpu_bo(obj);
 	struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
 
-	if (attach->peer2peer)
+	if (dma_buf_attach_accepts_sgt_p2p(attach))
 		pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
 }
 
@@ -175,7 +145,7 @@ static int amdgpu_dma_buf_pin(struct dma_buf_attachment *attach)
 	 * notiers are enabled.
 	 */
 	list_for_each_entry(attach, &dmabuf->attachments, node)
-		if (!attach->peer2peer)
+		if (!dma_buf_attach_accepts_sgt_p2p(attach))
 			domains &= ~AMDGPU_GEM_DOMAIN_VRAM;
 
 	if (domains & AMDGPU_GEM_DOMAIN_VRAM)
@@ -218,6 +188,7 @@ static void amdgpu_dma_buf_unpin(struct dma_buf_attachment *attach)
 static struct sg_table *amdgpu_dma_buf_map(struct dma_buf_attachment *attach,
 					   enum dma_data_direction dir)
 {
+	struct device *dma_dev = dma_buf_sgt_dma_device(attach);
 	struct dma_buf *dma_buf = attach->dmabuf;
 	struct drm_gem_object *obj = dma_buf->priv;
 	struct amdgpu_bo *bo = gem_to_amdgpu_bo(obj);
@@ -231,7 +202,7 @@ static struct sg_table *amdgpu_dma_buf_map(struct dma_buf_attachment *attach,
 		unsigned int domains = AMDGPU_GEM_DOMAIN_GTT;
 
 		if (bo->preferred_domains & AMDGPU_GEM_DOMAIN_VRAM &&
-		    attach->peer2peer) {
+		    dma_buf_sgt_p2p_allowed(attach)) {
 			bo->flags |= AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED;
 			domains |= AMDGPU_GEM_DOMAIN_VRAM;
 		}
@@ -249,7 +220,7 @@ static struct sg_table *amdgpu_dma_buf_map(struct dma_buf_attachment *attach,
 		if (IS_ERR(sgt))
 			return sgt;
 
-		if (dma_map_sgtable(attach->dev, sgt, dir,
+		if (dma_map_sgtable(dma_dev, sgt, dir,
 				    DMA_ATTR_SKIP_CPU_SYNC))
 			goto error_free;
 		break;
@@ -261,7 +232,7 @@ static struct sg_table *amdgpu_dma_buf_map(struct dma_buf_attachment *attach,
 			return ERR_PTR(-EINVAL);
 
 		r = amdgpu_vram_mgr_alloc_sgt(adev, bo->tbo.resource, 0,
-					      bo->tbo.base.size, attach->dev,
+					      bo->tbo.base.size, dma_dev,
 					      dir, &sgt);
 		if (r)
 			return ERR_PTR(r);
@@ -269,7 +240,7 @@ static struct sg_table *amdgpu_dma_buf_map(struct dma_buf_attachment *attach,
 
 	case AMDGPU_PL_MMIO_REMAP:
 		r = amdgpu_ttm_mmio_remap_alloc_sgt(adev, bo->tbo.resource,
-						    attach->dev, dir, &sgt);
+						    dma_dev, dir, &sgt);
 		if (r)
 			return ERR_PTR(r);
 		break;
@@ -299,21 +270,22 @@ static void amdgpu_dma_buf_unmap(struct dma_buf_attachment *attach,
 				 struct sg_table *sgt,
 				 enum dma_data_direction dir)
 {
+	struct device *dma_dev = dma_buf_sgt_dma_device(attach);
 	struct drm_gem_object *obj = attach->dmabuf->priv;
 	struct amdgpu_bo *bo = gem_to_amdgpu_bo(obj);
 
 	if (bo->tbo.resource &&
 	    bo->tbo.resource->mem_type == AMDGPU_PL_MMIO_REMAP) {
-		amdgpu_ttm_mmio_remap_free_sgt(attach->dev, dir, sgt);
+		amdgpu_ttm_mmio_remap_free_sgt(dma_dev, dir, sgt);
 		return;
 	}
 
 	if (sg_page(sgt->sgl)) {
-		dma_unmap_sgtable(attach->dev, sgt, dir, 0);
+		dma_unmap_sgtable(dma_dev, sgt, dir, 0);
 		sg_free_table(sgt);
 		kfree(sgt);
 	} else {
-		amdgpu_vram_mgr_free_sgt(attach->dev, dir, sgt);
+		amdgpu_vram_mgr_free_sgt(dma_dev, dir, sgt);
 	}
 }
 
@@ -388,18 +360,93 @@ static void amdgpu_dma_buf_vunmap(struct dma_buf *dma_buf, struct iosys_map *map
 	amdgpu_bo_unpin(bo);
 }
 
+static const struct dma_buf_mapping_sgt_exp_ops amdgpu_dma_buf_sgt_ops = {
+	.map_dma_buf = amdgpu_dma_buf_map,
+	.unmap_dma_buf = amdgpu_dma_buf_unmap,
+};
+
+static int amdgpu_dma_buf_match_mapping(struct dma_buf_match_args *args)
+{
+	struct dma_buf_attachment *attach = args->attach;
+	struct drm_gem_object *obj = args->dmabuf->priv;
+	struct amdgpu_bo *bo = gem_to_amdgpu_bo(obj);
+	struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
+	struct device *dev = adev_to_drm(adev)->dev;
+	struct dma_buf_mapping_match sgt_match[2];
+	unsigned int num_match = 0;
+	bool peer2peer = true;
+	int ret;
+
+	/*
+	 * Disable peer-to-peer access for DCC-enabled VRAM surfaces on GFX12+.
+	 * Such buffers cannot be safely accessed over P2P due to device-local
+	 * compression metadata. Fallback to system-memory path instead.
+	 * Device supports GFX12 (GC 12.x or newer)
+	 * BO was created with the AMDGPU_GEM_CREATE_GFX12_DCC flag
+	 *
+	 */
+	if (amdgpu_ip_version(adev, GC_HWIP, 0) >= IP_VERSION(12, 0, 0) &&
+	    bo->flags & AMDGPU_GEM_CREATE_GFX12_DCC)
+		peer2peer = false;
+
+	/*
+	 * Only allow P2P while the exporter is active, and keep it active
+	 * until detach.  With runtime PM disabled take a plain reference so
+	 * the put in detach stays balanced.
+	 */
+	if (peer2peer) {
+		ret = pm_runtime_get_if_active(dev);
+		if (!ret)
+			peer2peer = false;
+		else if (ret < 0)
+			pm_runtime_get_noresume(dev);
+	}
+
+	if (peer2peer)
+		sgt_match[num_match++] = DMA_BUF_EMAPPING_SGT_P2P(
+			&amdgpu_dma_buf_sgt_ops, adev->pdev);
+	sgt_match[num_match++] = DMA_BUF_EMAPPING_SGT(&amdgpu_dma_buf_sgt_ops);
+
+	ret = dma_buf_match_mapping(args, sgt_match, num_match);
+	if (ret)
+		goto err_pm_put;
+
+	/*
+	 * If the transfer will use XGMI then force a P2P match: the importer
+	 * reaches VRAM over XGMI, so the BO may stay there even though PCIe
+	 * P2P did not match. Rewrite the recorded match set entry rather than
+	 * only attach->map_type, which is what dma_buf_mapping_select() will
+	 * copy from at pin or map time.
+	 */
+	if (peer2peer && !dma_buf_attach_accepts_sgt_p2p(attach) &&
+	    amdgpu_dmabuf_is_xgmi_accessible(dma_buf_attach_adev(attach), bo)) {
+		attach->matches[0].sgt_data.exporter_requires_p2p =
+			DMA_SGT_EXPORTER_REQUIRES_P2P_DISTANCE;
+		attach->map_type = attach->matches[0];
+	}
+
+	/* The PM reference is only needed while P2P is actually possible. */
+	if (peer2peer && !dma_buf_attach_accepts_sgt_p2p(attach))
+		pm_runtime_put_autosuspend(dev);
+	return 0;
+
+err_pm_put:
+	if (peer2peer)
+		pm_runtime_put_autosuspend(dev);
+	return ret;
+}
+
 const struct dma_buf_ops amdgpu_dmabuf_ops = {
 	.attach = amdgpu_dma_buf_attach,
 	.detach = amdgpu_dma_buf_detach,
 	.pin = amdgpu_dma_buf_pin,
 	.unpin = amdgpu_dma_buf_unpin,
-	.map_dma_buf = amdgpu_dma_buf_map,
-	.unmap_dma_buf = amdgpu_dma_buf_unmap,
 	.release = drm_gem_dmabuf_release,
 	.begin_cpu_access = amdgpu_dma_buf_begin_cpu_access,
 	.mmap = drm_gem_dmabuf_mmap,
 	.vmap = amdgpu_dma_buf_vmap,
 	.vunmap = amdgpu_dma_buf_vunmap,
+	.match_mapping = amdgpu_dma_buf_match_mapping,
 };
 
 /**
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 71+ messages in thread

* [PATCH 15/26] vfio/pci: Change the DMA-buf exporter to use mapping_type
  2026-10-26  5:35 [PATCH 00/26] DMA-buf mapping types Alistair Popple
                   ` (13 preceding siblings ...)
  2026-10-26  5:36 ` [PATCH 14/26] drm/amdgpu: " Alistair Popple
@ 2026-10-26  5:36 ` Alistair Popple
  2026-10-26  9:00   ` sashiko-bot
  2026-10-26  5:36 ` [PATCH 16/26] RDMA/uverbs: Use the SGT_P2P mapping type Alistair Popple
                   ` (10 subsequent siblings)
  25 siblings, 1 reply; 71+ messages in thread
From: Alistair Popple @ 2026-10-26  5:36 UTC (permalink / raw)
  To: dri-devel, christian.koenig, sumit.semwal, jgg
  Cc: Alistair Popple, Thomas Hellström, Simona Vetter,
	Matthew Brost, Vivek Kasireddy, Dongwon Kim, Leon Romanovsky,
	Kevin Tian, Xu Yilun, Karl Mehltretter, Baolu Lu, Felix Kuehling,
	Alex Deucher, intel-xe, amd-gfx, linux-media, linaro-mm-sig,
	linux-rdma, iommu, Alexey Kardashevskiy, zhipingz, treding,
	jhubbard

From: Jason Gunthorpe <jgg@nvidia.com>

Simple conversion to add a match_mapping() callback that offers an
exporter SGT mapping type. Later patches will add a physical address
exporter so go straight to adding the match_mapping() function.

The check for attachment->peer2peer is replaced with setting
exporter_requires_p2p=true. VFIO always uses MMIO memory.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
[ dma_buf_mapping_attach() calls ->match_mapping() without
  holding the dma_resv lock, so the dma_resv_assert_held() in
  vfio_pci_dma_buf_match_mapping() fires under lockdep and the priv->vdev
  read it guarded was not serialised against vfio_pci_dma_buf_cleanup()
  either. Fixed as Jason proposed in
  https://lore.kernel.org/all/20260413130147.GG2588311@nvidia.com/: hold a
  pci_dev reference for the lifetime of the dmabuf and use it for the P2P
  match instead of dereferencing priv->vdev. - apopple ]
Reported-by: Baolu Lu <baolu.lu@linux.intel.com>
Closes: https://lore.kernel.org/all/f4e2171a-da58-488f-be02-26a39b5afbe3@linux.intel.com/
Signed-off-by: Alistair Popple <apopple@nvidia.com>
---
 drivers/vfio/pci/vfio_pci_dmabuf.c | 25 ++++++++++++++++++++-----
 1 file changed, 20 insertions(+), 5 deletions(-)

diff --git a/drivers/vfio/pci/vfio_pci_dmabuf.c b/drivers/vfio/pci/vfio_pci_dmabuf.c
index c16f460c01d6..58e771309c5f 100644
--- a/drivers/vfio/pci/vfio_pci_dmabuf.c
+++ b/drivers/vfio/pci/vfio_pci_dmabuf.c
@@ -12,6 +12,7 @@ MODULE_IMPORT_NS("DMA_BUF");
 struct vfio_pci_dma_buf {
 	struct dma_buf *dmabuf;
 	struct vfio_pci_core_device *vdev;
+	struct pci_dev *pdev;
 	struct list_head dmabufs_elm;
 	size_t size;
 	struct phys_vec *phys_vec;
@@ -27,9 +28,6 @@ static int vfio_pci_dma_buf_attach(struct dma_buf *dmabuf,
 {
 	struct vfio_pci_dma_buf *priv = dmabuf->priv;
 
-	if (!attachment->peer2peer)
-		return -EOPNOTSUPP;
-
 	if (priv->revoked)
 		return -ENODEV;
 
@@ -95,15 +93,31 @@ static void vfio_pci_dma_buf_release(struct dma_buf *dmabuf)
 		up_write(&priv->vdev->memory_lock);
 		vfio_device_put_registration(&priv->vdev->vdev);
 	}
+	pci_dev_put(priv->pdev);
 	kfree(priv->phys_vec);
 	kfree(priv);
 }
 
-static const struct dma_buf_ops vfio_pci_dmabuf_ops = {
-	.attach = vfio_pci_dma_buf_attach,
+static const struct dma_buf_mapping_sgt_exp_ops vfio_pci_dma_buf_sgt_ops = {
 	.map_dma_buf = vfio_pci_dma_buf_map,
 	.unmap_dma_buf = vfio_pci_dma_buf_unmap,
+};
+
+static int vfio_pci_dma_buf_match_mapping(struct dma_buf_match_args *args)
+{
+	struct vfio_pci_dma_buf *priv = args->dmabuf->priv;
+	struct dma_buf_mapping_match sgt_match[1];
+
+	sgt_match[0] = DMA_BUF_EMAPPING_SGT_P2P(&vfio_pci_dma_buf_sgt_ops,
+						priv->pdev);
+
+	return dma_buf_match_mapping(args, sgt_match, ARRAY_SIZE(sgt_match));
+}
+
+static const struct dma_buf_ops vfio_pci_dmabuf_ops = {
+	.attach = vfio_pci_dma_buf_attach,
 	.release = vfio_pci_dma_buf_release,
+	.match_mapping = vfio_pci_dma_buf_match_mapping,
 };
 
 /*
@@ -300,6 +314,7 @@ int vfio_pci_core_feature_dma_buf(struct vfio_pci_core_device *vdev, u32 flags,
 		goto err_dev_put;
 	}
 
+	priv->pdev = pci_dev_get(vdev->pdev);
 	kref_init(&priv->kref);
 	init_completion(&priv->comp);
 
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 71+ messages in thread

* [PATCH 16/26] RDMA/uverbs: Use the SGT_P2P mapping type
  2026-10-26  5:35 [PATCH 00/26] DMA-buf mapping types Alistair Popple
                   ` (14 preceding siblings ...)
  2026-10-26  5:36 ` [PATCH 15/26] vfio/pci: Change the DMA-buf exporter to use mapping_type Alistair Popple
@ 2026-10-26  5:36 ` Alistair Popple
  2026-10-26  9:16   ` sashiko-bot
  2026-10-26  5:36 ` [PATCH 17/26] dma-buf: Update dma_buf_phys_vec_to_sgt() to use the SGT " Alistair Popple
                   ` (9 subsequent siblings)
  25 siblings, 1 reply; 71+ messages in thread
From: Alistair Popple @ 2026-10-26  5:36 UTC (permalink / raw)
  To: dri-devel, christian.koenig, sumit.semwal, jgg
  Cc: Alistair Popple, Thomas Hellström, Simona Vetter,
	Matthew Brost, Vivek Kasireddy, Dongwon Kim, Leon Romanovsky,
	Kevin Tian, Xu Yilun, Karl Mehltretter, Baolu Lu, Felix Kuehling,
	Alex Deucher, intel-xe, amd-gfx, linux-media, linaro-mm-sig,
	linux-rdma, iommu, Alexey Kardashevskiy, zhipingz, treding,
	jhubbard

From: Jason Gunthorpe <jgg@nvidia.com>

Very similar to habana, except the rejection of unsupported
pci_p2p_dma_distance() is done inside map not attach via
dma_buf_phys_vec_to_sgt().

Convert this directly to a SGT_P2P match which will prevent matching if
dma_buf_phys_vec_to_sgt() would fail.

Remove the now empty attach function.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
[ rebase context change, upstream added MODULE_IMPORT_NS("DMA_BUF") - apopple ]
Signed-off-by: Alistair Popple <apopple@nvidia.com>
---
 .../infiniband/core/uverbs_std_types_dmabuf.c | 30 ++++++++++++-------
 1 file changed, 19 insertions(+), 11 deletions(-)

diff --git a/drivers/infiniband/core/uverbs_std_types_dmabuf.c b/drivers/infiniband/core/uverbs_std_types_dmabuf.c
index 2411ebee69e2..3c5c3ea2cf55 100644
--- a/drivers/infiniband/core/uverbs_std_types_dmabuf.c
+++ b/drivers/infiniband/core/uverbs_std_types_dmabuf.c
@@ -12,15 +12,6 @@
 
 MODULE_IMPORT_NS("DMA_BUF");
 
-static int uverbs_dmabuf_attach(struct dma_buf *dmabuf,
-				struct dma_buf_attachment *attachment)
-{
-	if (!attachment->peer2peer)
-		return -EOPNOTSUPP;
-
-	return 0;
-}
-
 static struct sg_table *
 uverbs_dmabuf_map(struct dma_buf_attachment *attachment,
 		  enum dma_data_direction dir)
@@ -76,13 +67,30 @@ static void uverbs_dmabuf_release(struct dma_buf *dmabuf)
 	uverbs_uobject_release(&priv->uobj);
 }
 
-static const struct dma_buf_ops uverbs_dmabuf_ops = {
-	.attach = uverbs_dmabuf_attach,
+static const struct dma_buf_mapping_sgt_exp_ops uverbs_dma_buf_sgt_ops = {
 	.map_dma_buf = uverbs_dmabuf_map,
 	.unmap_dma_buf = uverbs_dmabuf_unmap,
+};
+
+static int uverbs_dmabuf_match_mapping(struct dma_buf_match_args *args)
+{
+	struct ib_uverbs_dmabuf_file *priv = args->dmabuf->priv;
+	struct dma_buf_mapping_match sgt_match[1];
+
+	if (WARN_ON(!dev_is_pci(priv->provider->owner)))
+		return -EINVAL;
+
+	sgt_match[0] = DMA_BUF_EMAPPING_SGT_P2P(
+		&uverbs_dma_buf_sgt_ops, to_pci_dev(priv->provider->owner));
+
+	return dma_buf_match_mapping(args, sgt_match, ARRAY_SIZE(sgt_match));
+}
+
+static const struct dma_buf_ops uverbs_dmabuf_ops = {
 	.pin = uverbs_dmabuf_pin,
 	.unpin = uverbs_dmabuf_unpin,
 	.release = uverbs_dmabuf_release,
+	.match_mapping = uverbs_dmabuf_match_mapping,
 };
 
 static int UVERBS_HANDLER(UVERBS_METHOD_DMABUF_ALLOC)(
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 71+ messages in thread

* [PATCH 17/26] dma-buf: Update dma_buf_phys_vec_to_sgt() to use the SGT mapping type
  2026-10-26  5:35 [PATCH 00/26] DMA-buf mapping types Alistair Popple
                   ` (15 preceding siblings ...)
  2026-10-26  5:36 ` [PATCH 16/26] RDMA/uverbs: Use the SGT_P2P mapping type Alistair Popple
@ 2026-10-26  5:36 ` Alistair Popple
  2026-10-26  9:26   ` sashiko-bot
  2026-10-26  5:36 ` [PATCH 18/26] iio: buffer: convert " Alistair Popple
                   ` (8 subsequent siblings)
  25 siblings, 1 reply; 71+ messages in thread
From: Alistair Popple @ 2026-10-26  5:36 UTC (permalink / raw)
  To: dri-devel, christian.koenig, sumit.semwal, jgg
  Cc: Alistair Popple, Thomas Hellström, Simona Vetter,
	Matthew Brost, Vivek Kasireddy, Dongwon Kim, Leon Romanovsky,
	Kevin Tian, Xu Yilun, Karl Mehltretter, Baolu Lu, Felix Kuehling,
	Alex Deucher, intel-xe, amd-gfx, linux-media, linaro-mm-sig,
	linux-rdma, iommu, Alexey Kardashevskiy, zhipingz, treding,
	jhubbard

From: Jason Gunthorpe <jgg@nvidia.com>

These helpers only work when matched to a SGT mapping type, call
dma_buf_sgt_dma_device() to get the DMA device.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/dma-buf/dma-buf-mapping.c | 22 ++++++++++++----------
 1 file changed, 12 insertions(+), 10 deletions(-)

diff --git a/drivers/dma-buf/dma-buf-mapping.c b/drivers/dma-buf/dma-buf-mapping.c
index 7a5a379a372e..7d20979af7fb 100644
--- a/drivers/dma-buf/dma-buf-mapping.c
+++ b/drivers/dma-buf/dma-buf-mapping.c
@@ -105,6 +105,7 @@ struct sg_table *dma_buf_phys_vec_to_sgt(struct dma_buf_attachment *attach,
 					 size_t nr_ranges, size_t size,
 					 enum dma_data_direction dir)
 {
+	struct device *dma_dev = dma_buf_sgt_dma_device(attach);
 	struct dma_buf_dma *dma;
 	struct scatterlist *sgl;
 	size_t mapped_len = 0;
@@ -123,7 +124,7 @@ struct sg_table *dma_buf_phys_vec_to_sgt(struct dma_buf_attachment *attach,
 	if (!dma)
 		return ERR_PTR(-ENOMEM);
 
-	switch (pci_p2pdma_map_type(provider, attach->dev)) {
+	switch (pci_p2pdma_map_type(provider, dma_dev)) {
 	case PCI_P2PDMA_MAP_BUS_ADDR:
 		/*
 		 * There is no need in IOVA at all for this flow.
@@ -136,7 +137,7 @@ struct sg_table *dma_buf_phys_vec_to_sgt(struct dma_buf_attachment *attach,
 			goto err_free_dma;
 		}
 
-		dma_iova_try_alloc(attach->dev, dma->state, 0, size);
+		dma_iova_try_alloc(dma_dev, dma->state, 0, size);
 		break;
 	default:
 		ret = -EINVAL;
@@ -157,7 +158,7 @@ struct sg_table *dma_buf_phys_vec_to_sgt(struct dma_buf_attachment *attach,
 			addr = pci_p2pdma_bus_addr_map(provider,
 						       phys_vec[i].paddr);
 		} else if (dma_use_iova(dma->state)) {
-			ret = dma_iova_link(attach->dev, dma->state,
+			ret = dma_iova_link(dma_dev, dma->state,
 					    phys_vec[i].paddr, 0,
 					    phys_vec[i].len, dir,
 					    DMA_ATTR_MMIO);
@@ -166,10 +167,10 @@ struct sg_table *dma_buf_phys_vec_to_sgt(struct dma_buf_attachment *attach,
 
 			mapped_len += phys_vec[i].len;
 		} else {
-			addr = dma_map_phys(attach->dev, phys_vec[i].paddr,
+			addr = dma_map_phys(dma_dev, phys_vec[i].paddr,
 					    phys_vec[i].len, dir,
 					    DMA_ATTR_MMIO);
-			ret = dma_mapping_error(attach->dev, addr);
+			ret = dma_mapping_error(dma_dev, addr);
 			if (ret)
 				goto err_unmap_dma;
 		}
@@ -180,7 +181,7 @@ struct sg_table *dma_buf_phys_vec_to_sgt(struct dma_buf_attachment *attach,
 
 	if (dma->state && dma_use_iova(dma->state)) {
 		WARN_ON_ONCE(mapped_len != size);
-		ret = dma_iova_sync(attach->dev, dma->state, 0, mapped_len);
+		ret = dma_iova_sync(dma_dev, dma->state, 0, mapped_len);
 		if (ret)
 			goto err_unmap_dma;
 
@@ -207,11 +208,11 @@ struct sg_table *dma_buf_phys_vec_to_sgt(struct dma_buf_attachment *attach,
 	if (!i || !dma->state) {
 		; /* Do nothing */
 	} else if (dma_use_iova(dma->state)) {
-		dma_iova_destroy(attach->dev, dma->state, mapped_len, dir,
+		dma_iova_destroy(dma_dev, dma->state, mapped_len, dir,
 				 DMA_ATTR_MMIO);
 	} else {
 		for_each_sgtable_dma_sg(&dma->sgt, sgl, i)
-			dma_unmap_phys(attach->dev, sg_dma_address(sgl),
+			dma_unmap_phys(dma_dev, sg_dma_address(sgl),
 				       sg_dma_len(sgl), dir, DMA_ATTR_MMIO);
 	}
 	sg_free_table(&dma->sgt);
@@ -236,6 +237,7 @@ void dma_buf_free_sgt(struct dma_buf_attachment *attach, struct sg_table *sgt,
 		      enum dma_data_direction dir)
 {
 	struct dma_buf_dma *dma = container_of(sgt, struct dma_buf_dma, sgt);
+	struct device *dma_dev = dma_buf_sgt_dma_device(attach);
 	int i;
 
 	dma_resv_assert_held(attach->dmabuf->resv);
@@ -243,13 +245,13 @@ void dma_buf_free_sgt(struct dma_buf_attachment *attach, struct sg_table *sgt,
 	if (!dma->state) {
 		; /* Do nothing */
 	} else if (dma_use_iova(dma->state)) {
-		dma_iova_destroy(attach->dev, dma->state, dma->size, dir,
+		dma_iova_destroy(dma_dev, dma->state, dma->size, dir,
 				 DMA_ATTR_MMIO);
 	} else {
 		struct scatterlist *sgl;
 
 		for_each_sgtable_dma_sg(sgt, sgl, i)
-			dma_unmap_phys(attach->dev, sg_dma_address(sgl),
+			dma_unmap_phys(dma_dev, sg_dma_address(sgl),
 				       sg_dma_len(sgl), dir, DMA_ATTR_MMIO);
 	}
 
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 71+ messages in thread

* [PATCH 18/26] iio: buffer: convert to use the SGT mapping type
  2026-10-26  5:35 [PATCH 00/26] DMA-buf mapping types Alistair Popple
                   ` (16 preceding siblings ...)
  2026-10-26  5:36 ` [PATCH 17/26] dma-buf: Update dma_buf_phys_vec_to_sgt() to use the SGT " Alistair Popple
@ 2026-10-26  5:36 ` Alistair Popple
  2026-10-26  9:28   ` sashiko-bot
  2026-10-26  5:36 ` [PATCH 19/26] functionfs: " Alistair Popple
                   ` (7 subsequent siblings)
  25 siblings, 1 reply; 71+ messages in thread
From: Alistair Popple @ 2026-10-26  5:36 UTC (permalink / raw)
  To: dri-devel, christian.koenig, sumit.semwal, jgg
  Cc: Alistair Popple, Thomas Hellström, Simona Vetter,
	Matthew Brost, Vivek Kasireddy, Dongwon Kim, Leon Romanovsky,
	Kevin Tian, Xu Yilun, Karl Mehltretter, Baolu Lu, Felix Kuehling,
	Alex Deucher, intel-xe, amd-gfx, linux-media, linaro-mm-sig,
	linux-rdma, iommu, Alexey Kardashevskiy, zhipingz, treding,
	jhubbard

From: Jason Gunthorpe <jgg@nvidia.com>

These importer helper functions should call dma_buf_sgt_dma_device() as
they are always working with SGTs.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/iio/industrialio-buffer.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/iio/industrialio-buffer.c b/drivers/iio/industrialio-buffer.c
index 2c9ec93dff47..a00985c92251 100644
--- a/drivers/iio/industrialio-buffer.c
+++ b/drivers/iio/industrialio-buffer.c
@@ -16,6 +16,7 @@
 #include <linux/export.h>
 #include <linux/device.h>
 #include <linux/dma-buf.h>
+#include <linux/dma-buf-mapping.h>
 #include <linux/dma-fence.h>
 #include <linux/dma-resv.h>
 #include <linux/file.h>
@@ -1672,7 +1673,7 @@ iio_buffer_find_attachment(struct iio_dev_buffer_pair *ib,
 	guard(mutex)(&buffer->dmabufs_mutex);
 
 	list_for_each_entry(priv, &buffer->dmabufs, entry) {
-		if (priv->attach->dev == dma_dev
+		if (dma_buf_sgt_dma_device(priv->attach) == dma_dev
 		    && priv->attach->dmabuf == dmabuf) {
 			attach = priv->attach;
 			break;
@@ -1756,7 +1757,7 @@ static int iio_buffer_attach_dmabuf(struct iio_dev_buffer_pair *ib,
 	 * combo. If we do, refuse to attach.
 	 */
 	list_for_each_entry(each, &buffer->dmabufs, entry) {
-		if (each->attach->dev == dma_dev
+		if (dma_buf_sgt_dma_device(each->attach) == dma_dev
 		    && each->attach->dmabuf == dmabuf) {
 			/*
 			 * We unlocked the reservation object, so going through
@@ -1810,7 +1811,7 @@ static int iio_buffer_detach_dmabuf(struct iio_dev_buffer_pair *ib,
 	guard(mutex)(&buffer->dmabufs_mutex);
 
 	list_for_each_entry(priv, &buffer->dmabufs, entry) {
-		if (priv->attach->dev == dma_dev
+		if (dma_buf_sgt_dma_device(priv->attach) == dma_dev
 		    && priv->attach->dmabuf == dmabuf) {
 			list_del(&priv->entry);
 
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 71+ messages in thread

* [PATCH 19/26] functionfs: convert to use the SGT mapping type
  2026-10-26  5:35 [PATCH 00/26] DMA-buf mapping types Alistair Popple
                   ` (17 preceding siblings ...)
  2026-10-26  5:36 ` [PATCH 18/26] iio: buffer: convert " Alistair Popple
@ 2026-10-26  5:36 ` Alistair Popple
  2026-10-26  9:35   ` sashiko-bot
  2026-10-26  5:36 ` [PATCH 20/26] dma-buf: Remove unused SGT stuff from the common structures Alistair Popple
                   ` (6 subsequent siblings)
  25 siblings, 1 reply; 71+ messages in thread
From: Alistair Popple @ 2026-10-26  5:36 UTC (permalink / raw)
  To: dri-devel, christian.koenig, sumit.semwal, jgg
  Cc: Alistair Popple, Thomas Hellström, Simona Vetter,
	Matthew Brost, Vivek Kasireddy, Dongwon Kim, Leon Romanovsky,
	Kevin Tian, Xu Yilun, Karl Mehltretter, Baolu Lu, Felix Kuehling,
	Alex Deucher, intel-xe, amd-gfx, linux-media, linaro-mm-sig,
	linux-rdma, iommu, Alexey Kardashevskiy, zhipingz, treding,
	jhubbard

From: Jason Gunthorpe <jgg@nvidia.com>

These importer helper functions should call dma_buf_sgt_dma_device() as
they are always working with SGTs.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/usb/gadget/function/f_fs.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c
index 43962e05eacf..09680534623e 100644
--- a/drivers/usb/gadget/function/f_fs.c
+++ b/drivers/usb/gadget/function/f_fs.c
@@ -16,6 +16,7 @@
 
 #include <linux/blkdev.h>
 #include <linux/dma-buf.h>
+#include <linux/dma-buf-mapping.h>
 #include <linux/dma-fence.h>
 #include <linux/dma-resv.h>
 #include <linux/pagemap.h>
@@ -1514,7 +1515,7 @@ ffs_dmabuf_find_attachment(struct ffs_epfile *epfile, struct dma_buf *dmabuf)
 	mutex_lock(&epfile->dmabufs_mutex);
 
 	list_for_each_entry(priv, &epfile->dmabufs, entry) {
-		if (priv->attach->dev == dev
+		if (dma_buf_sgt_dma_device(priv->attach) == dev
 		    && priv->attach->dmabuf == dmabuf) {
 			attach = priv->attach;
 			break;
@@ -1616,7 +1617,7 @@ static int ffs_dmabuf_detach(struct file *file, int fd)
 	mutex_lock(&epfile->dmabufs_mutex);
 
 	list_for_each_entry_safe(priv, tmp, &epfile->dmabufs, entry) {
-		if (priv->attach->dev == dev
+		if (dma_buf_sgt_dma_device(priv->attach) == dev
 		    && priv->attach->dmabuf == dmabuf) {
 			/* Cancel any pending transfer */
 			spin_lock_irq(&ffs->eps_lock);
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 71+ messages in thread

* [PATCH 20/26] dma-buf: Remove unused SGT stuff from the common structures
  2026-10-26  5:35 [PATCH 00/26] DMA-buf mapping types Alistair Popple
                   ` (18 preceding siblings ...)
  2026-10-26  5:36 ` [PATCH 19/26] functionfs: " Alistair Popple
@ 2026-10-26  5:36 ` Alistair Popple
  2026-10-26  9:39   ` sashiko-bot
  2026-10-26  5:36 ` [PATCH 21/26] treewide: Rename dma_buf_map_attachment(_unlocked) to dma_buf_sgt_ Alistair Popple
                   ` (5 subsequent siblings)
  25 siblings, 1 reply; 71+ messages in thread
From: Alistair Popple @ 2026-10-26  5:36 UTC (permalink / raw)
  To: dri-devel, christian.koenig, sumit.semwal, jgg
  Cc: Alistair Popple, Thomas Hellström, Simona Vetter,
	Matthew Brost, Vivek Kasireddy, Dongwon Kim, Leon Romanovsky,
	Kevin Tian, Xu Yilun, Karl Mehltretter, Baolu Lu, Felix Kuehling,
	Alex Deucher, intel-xe, amd-gfx, linux-media, linaro-mm-sig,
	linux-rdma, iommu, Alexey Kardashevskiy, zhipingz, treding,
	jhubbard

From: Jason Gunthorpe <jgg@nvidia.com>

Now that all exporters are converted these compatibility things can be
removed:

dma_buf_ops: map_dma_buf/unmap_dma_buf
             Moved to dma_buf_mapping_sgt_exp_ops

dma_buf_attachment: dev
		    Moved to attach->map_type.importing_dma_device

dma_buf_attachment: peer2peer
		    Moved to attach->map_type.exporter_requires_p2p
                    accessed via dma_buf_sgt_p2p_allowed()

dma_buf_sgt_exp_compat_match: No compatibility exporters anymore

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
[ use dma_buf_sgt_dma_device(attach) in dma_buf_detach trace point instead of attach->dev - apopple ]
Signed-off-by: Alistair Popple <apopple@nvidia.com>
---
 drivers/dma-buf/dma-buf-mapping.c | 40 -----------------
 drivers/dma-buf/dma-buf.c         | 27 +++---------
 drivers/gpu/drm/drm_prime.c       |  2 -
 include/linux/dma-buf-mapping.h   | 67 +++++++++++++++++++++++++++-
 include/linux/dma-buf.h           | 73 -------------------------------
 5 files changed, 72 insertions(+), 137 deletions(-)

diff --git a/drivers/dma-buf/dma-buf-mapping.c b/drivers/dma-buf/dma-buf-mapping.c
index 7d20979af7fb..403f8432586a 100644
--- a/drivers/dma-buf/dma-buf-mapping.c
+++ b/drivers/dma-buf/dma-buf-mapping.c
@@ -479,16 +479,6 @@ dma_buf_sgt_finish_match(struct dma_buf_match_args *args,
 			.exporter_requires_p2p = exp->sgt_data.exporter_requires_p2p,
 		},
 	};
-
-	/*
-	 * Setup the SGT type variables stored in attach because importers and
-	 * exporters that do not natively use mappings expect them to be there.
-	 * When converting to use mappings users should use the match versions
-	 * of these instead.
-	 */
-	attach->dev = imp->sgt_data.importing_dma_device;
-	attach->peer2peer = attach->map_type.sgt_data.importer_accepts_p2p ==
-			    DMA_SGT_IMPORTER_ACCEPTS_P2P;
 }
 
 static void dma_buf_sgt_debugfs_dump(struct seq_file *s,
@@ -506,33 +496,3 @@ struct dma_buf_mapping_type dma_buf_mapping_sgt_type = {
 	.unmap = dma_buf_sgt_type_unmap,
 };
 EXPORT_SYMBOL_NS_GPL(dma_buf_mapping_sgt_type, "DMA_BUF");
-
-static struct sg_table *
-dma_buf_sgt_compat_map_dma_buf(struct dma_buf_attachment *attach,
-			       enum dma_data_direction dir)
-{
-	return attach->dmabuf->ops->map_dma_buf(attach, dir);
-}
-
-static void dma_buf_sgt_compat_unmap_dma_buf(struct dma_buf_attachment *attach,
-					     struct sg_table *sgt,
-					     enum dma_data_direction dir)
-{
-	attach->dmabuf->ops->unmap_dma_buf(attach, sgt, dir);
-}
-
-/* Route the classic map/unmap ops through the exp ops for old importers */
-static const struct dma_buf_mapping_sgt_exp_ops dma_buf_sgt_compat_exp_ops = {
-	.map_dma_buf = dma_buf_sgt_compat_map_dma_buf,
-	.unmap_dma_buf = dma_buf_sgt_compat_unmap_dma_buf,
-};
-
-/*
- * This mapping type is used for unaware exporters that do not support
- * match_mapping(). It wraps the dma_buf ops for SGT mappings into a mapping
- * type so aware importers can transparently work with unaware exporters. This
- * does not require p2p because old exporters will check it through the
- * attach->peer2peer mechanism.
- */
-const struct dma_buf_mapping_match dma_buf_sgt_exp_compat_match =
-	DMA_BUF_EMAPPING_SGT(&dma_buf_sgt_compat_exp_ops);
diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c
index 6c9ab8bc09ac..dc65752fb0fa 100644
--- a/drivers/dma-buf/dma-buf.c
+++ b/drivers/dma-buf/dma-buf.c
@@ -718,19 +718,9 @@ struct dma_buf *dma_buf_export(const struct dma_buf_export_info *exp_info)
 		    || !exp_info->ops->release))
 		return ERR_PTR(-EINVAL);
 
-	if (exp_info->ops->match_mapping ||
-	    exp_info->ops->single_exporter_match) {
-		if (WARN_ON(exp_info->ops->map_dma_buf ||
-			    exp_info->ops->unmap_dma_buf))
-			return ERR_PTR(-EINVAL);
-		if (WARN_ON(exp_info->ops->match_mapping &&
-			    exp_info->ops->single_exporter_match))
-			return ERR_PTR(-EINVAL);
-	} else {
-		if (WARN_ON(!exp_info->ops->map_dma_buf ||
-			    !exp_info->ops->unmap_dma_buf))
-			return ERR_PTR(-EINVAL);
-	}
+	if (WARN_ON(!exp_info->ops->match_mapping &&
+		    !exp_info->ops->single_exporter_match))
+		return ERR_PTR(-EINVAL);
 
 	if (WARN_ON(!exp_info->ops->pin != !exp_info->ops->unpin))
 		return ERR_PTR(-EINVAL);
@@ -1082,12 +1072,8 @@ struct dma_buf_attachment *dma_buf_mapping_attach(
 		if (ret)
 			goto err_attach;
 	} else {
-		const struct dma_buf_mapping_match *exp_match =
-			dmabuf->ops->single_exporter_match;
-
-		if (!exp_match)
-			exp_match = &dma_buf_sgt_exp_compat_match;
-		ret = dma_buf_match_mapping(&match_args, exp_match, 1);
+		ret = dma_buf_match_mapping(
+			&match_args, dmabuf->ops->single_exporter_match, 1);
 		if (ret)
 			goto err_attach;
 	}
@@ -1180,7 +1166,8 @@ void dma_buf_detach(struct dma_buf *dmabuf, struct dma_buf_attachment *attach)
 		dmabuf->ops->detach(dmabuf, attach);
 
 	DMA_BUF_TRACE(trace_dma_buf_detach, dmabuf, attach,
-		dma_buf_attachment_is_dynamic(attach), attach->dev);
+		dma_buf_attachment_is_dynamic(attach),
+		dma_buf_sgt_dma_device(attach));
 
 	kfree(attach);
 }
diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c
index d797598e42f7..7792caf87883 100644
--- a/drivers/gpu/drm/drm_prime.c
+++ b/drivers/gpu/drm/drm_prime.c
@@ -593,8 +593,6 @@ static bool is_gem_map_dma_buf(struct dma_buf_attachment *attach)
 	const struct dma_buf_mapping_sgt_exp_ops *sgt_exp_ops =
 		dma_buf_get_sgt_ops(attach);
 
-	if (attach->dmabuf->ops->map_dma_buf == drm_gem_map_dma_buf)
-		return true;
 	if (sgt_exp_ops && sgt_exp_ops->map_dma_buf == drm_gem_map_dma_buf)
 		return true;
 	return false;
diff --git a/include/linux/dma-buf-mapping.h b/include/linux/dma-buf-mapping.h
index 4aaddad8c7be..91a55cbe0bb4 100644
--- a/include/linux/dma-buf-mapping.h
+++ b/include/linux/dma-buf-mapping.h
@@ -202,8 +202,73 @@ dma_buf_sgt_mapping_table(struct dma_buf_mapping *mapping)
 
 struct dma_buf_mapping_sgt_exp_ops {
 	struct dma_buf_mapping_exp_ops ops;
+
+	/**
+	 * @map_dma_buf:
+	 *
+	 * This is called by dma_buf_map_attachment() and is used to map a
+	 * shared &dma_buf into device address space, and it is mandatory. It
+	 * can only be called if @attach has been called successfully.
+	 *
+	 * This call may sleep, e.g. when the backing storage first needs to be
+	 * allocated, or moved to a location suitable for all currently attached
+	 * devices.
+	 *
+	 * Note that any specific buffer attributes required for this function
+	 * should get added to device_dma_parameters accessible via
+	 * &device.dma_params from the &dma_buf_attachment. The @attach callback
+	 * should also check these constraints.
+	 *
+	 * If this is being called for the first time, the exporter can now
+	 * choose to scan through the list of attachments for this buffer,
+	 * collate the requirements of the attached devices, and choose an
+	 * appropriate backing storage for the buffer.
+	 *
+	 * Based on enum dma_data_direction, it might be possible to have
+	 * multiple users accessing at the same time (for reading, maybe), or
+	 * any other kind of sharing that the exporter might wish to make
+	 * available to buffer-users.
+	 *
+	 * This is always called with the dmabuf->resv object locked when
+	 * the dynamic_mapping flag is true.
+	 *
+	 * Note that for non-dynamic exporters the driver must guarantee that
+	 * that the memory is available for use and cleared of any old data by
+	 * the time this function returns.  Drivers which pipeline their buffer
+	 * moves internally must wait for all moves and clears to complete.
+	 * Dynamic exporters do not need to follow this rule: For non-dynamic
+	 * importers the buffer is already pinned through @pin, which has the
+	 * same requirements. Dynamic importers otoh are required to obey the
+	 * dma_resv fences.
+	 *
+	 * Returns:
+	 *
+	 * A &sg_table scatter list of the backing storage of the DMA buffer,
+	 * already mapped into the device address space of the &device attached
+	 * with the provided &dma_buf_attachment. The addresses and lengths in
+	 * the scatter list are PAGE_SIZE aligned.
+	 *
+	 * On failure, returns a negative error value wrapped into a pointer.
+	 * May also return -EINTR when a signal was received while being
+	 * blocked.
+	 *
+	 * Note that exporters should not try to cache the scatter list, or
+	 * return the same one for multiple calls. Caching is done either by the
+	 * DMA-BUF code (for non-dynamic importers) or the importer. Ownership
+	 * of the scatter list is transferred to the caller, and returned by
+	 * @unmap_dma_buf.
+	 */
 	struct sg_table *(*map_dma_buf)(struct dma_buf_attachment *attach,
 					enum dma_data_direction dir);
+
+	/**
+	 * @unmap_dma_buf:
+	 *
+	 * This is called by dma_buf_unmap_attachment() and should unmap and
+	 * release the &sg_table allocated in @map_dma_buf, and it is mandatory.
+	 * For static dma_buf handling this might also unpin the backing
+	 * storage if this is the last mapping of the DMA buffer.
+	 */
 	void (*unmap_dma_buf)(struct dma_buf_attachment *attach,
 			      struct sg_table *sgt,
 			      enum dma_data_direction dir);
@@ -304,8 +369,6 @@ DMA_BUF_EMAPPING_SGT_P2P(const struct dma_buf_mapping_sgt_exp_ops *exp_ops,
 	return match;
 }
 
-extern const struct dma_buf_mapping_match dma_buf_sgt_exp_compat_match;
-
 /*
  * dma_buf_ops initializer helper for simple drivers that use a single
  * SGT map/unmap operation without P2P.
diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h
index d78eec3476f3..77a18b9817ac 100644
--- a/include/linux/dma-buf.h
+++ b/include/linux/dma-buf.h
@@ -152,75 +152,6 @@ struct dma_buf_ops {
 	 */
 	void (*unpin)(struct dma_buf_attachment *attach);
 
-	/**
-	 * @map_dma_buf:
-	 *
-	 * This is called by dma_buf_map_attachment() and is used to map a
-	 * shared &dma_buf into device address space, and it is mandatory. It
-	 * can only be called if @attach has been called successfully.
-	 *
-	 * This call may sleep, e.g. when the backing storage first needs to be
-	 * allocated, or moved to a location suitable for all currently attached
-	 * devices.
-	 *
-	 * Note that any specific buffer attributes required for this function
-	 * should get added to device_dma_parameters accessible via
-	 * &device.dma_params from the &dma_buf_attachment. The @attach callback
-	 * should also check these constraints.
-	 *
-	 * If this is being called for the first time, the exporter can now
-	 * choose to scan through the list of attachments for this buffer,
-	 * collate the requirements of the attached devices, and choose an
-	 * appropriate backing storage for the buffer.
-	 *
-	 * Based on enum dma_data_direction, it might be possible to have
-	 * multiple users accessing at the same time (for reading, maybe), or
-	 * any other kind of sharing that the exporter might wish to make
-	 * available to buffer-users.
-	 *
-	 * This is always called with the dmabuf->resv object locked when
-	 * the dynamic_mapping flag is true.
-	 *
-	 * Note that for non-dynamic exporters the driver must guarantee that
-	 * that the memory is available for use and cleared of any old data by
-	 * the time this function returns.  Drivers which pipeline their buffer
-	 * moves internally must wait for all moves and clears to complete.
-	 * Dynamic exporters do not need to follow this rule: For non-dynamic
-	 * importers the buffer is already pinned through @pin, which has the
-	 * same requirements. Dynamic importers otoh are required to obey the
-	 * dma_resv fences.
-	 *
-	 * Returns:
-	 *
-	 * A &sg_table scatter list of the backing storage of the DMA buffer,
-	 * already mapped into the device address space of the &device attached
-	 * with the provided &dma_buf_attachment. The addresses and lengths in
-	 * the scatter list are PAGE_SIZE aligned.
-	 *
-	 * On failure, returns a negative error value wrapped into a pointer.
-	 * May also return -EINTR when a signal was received while being
-	 * blocked.
-	 *
-	 * Note that exporters should not try to cache the scatter list, or
-	 * return the same one for multiple calls. Caching is done either by the
-	 * DMA-BUF code (for non-dynamic importers) or the importer. Ownership
-	 * of the scatter list is transferred to the caller, and returned by
-	 * @unmap_dma_buf.
-	 */
-	struct sg_table * (*map_dma_buf)(struct dma_buf_attachment *,
-					 enum dma_data_direction);
-	/**
-	 * @unmap_dma_buf:
-	 *
-	 * This is called by dma_buf_unmap_attachment() and should unmap and
-	 * release the &sg_table allocated in @map_dma_buf, and it is mandatory.
-	 * For static dma_buf handling this might also unpin the backing
-	 * storage if this is the last mapping of the DMA buffer.
-	 */
-	void (*unmap_dma_buf)(struct dma_buf_attachment *,
-			      struct sg_table *,
-			      enum dma_data_direction);
-
 	/* TODO: Add try_map_dma_buf version, to return immed with -EBUSY
 	 * if the call would block.
 	 */
@@ -562,9 +493,7 @@ struct dma_buf_attach_ops {
 /**
  * struct dma_buf_attachment - holds device-buffer attachment data
  * @dmabuf: buffer for this attachment.
- * @dev: device attached to the buffer.
  * @node: list of dma_buf_attachment, protected by dma_resv lock of the dmabuf.
- * @peer2peer: true if the importer can handle peer resources without pages.
  * @priv: exporter specific attachment data.
  * @importer_ops: importer operations for this attachment, if provided
  * dma_buf_map/unmap_attachment() must be called with the dma_resv lock held.
@@ -591,9 +520,7 @@ struct dma_buf_attach_ops {
  */
 struct dma_buf_attachment {
 	struct dma_buf *dmabuf;
-	struct device *dev;
 	struct list_head node;
-	bool peer2peer;
 	const struct dma_buf_attach_ops *importer_ops;
 	void *importer_priv;
 	void *priv;
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 71+ messages in thread

* [PATCH 21/26] treewide: Rename dma_buf_map_attachment(_unlocked) to dma_buf_sgt_
  2026-10-26  5:35 [PATCH 00/26] DMA-buf mapping types Alistair Popple
                   ` (19 preceding siblings ...)
  2026-10-26  5:36 ` [PATCH 20/26] dma-buf: Remove unused SGT stuff from the common structures Alistair Popple
@ 2026-10-26  5:36 ` Alistair Popple
  2026-10-26  9:49   ` sashiko-bot
  2026-10-27 12:05   ` Christian König
  2026-10-26  5:36 ` [PATCH 22/26] treewide: Rename dma_buf_unmap_attachment(_unlocked) to dma_buf_sgt_* Alistair Popple
                   ` (4 subsequent siblings)
  25 siblings, 2 replies; 71+ messages in thread
From: Alistair Popple @ 2026-10-26  5:36 UTC (permalink / raw)
  To: dri-devel, christian.koenig, sumit.semwal, jgg
  Cc: Alistair Popple, Thomas Hellström, Simona Vetter,
	Matthew Brost, Vivek Kasireddy, Dongwon Kim, Leon Romanovsky,
	Kevin Tian, Xu Yilun, Karl Mehltretter, Baolu Lu, Felix Kuehling,
	Alex Deucher, intel-xe, amd-gfx, linux-media, linaro-mm-sig,
	linux-rdma, iommu, Alexey Kardashevskiy, zhipingz, treding,
	jhubbard

From: Jason Gunthorpe <jgg@nvidia.com>

This map function only works with SGT importers.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
[ also rename the io_uring zcrx caller, which the unmap rename
  used to pick up, so that this commit builds with CONFIG_IO_URING_ZCRX - apopple ]
Signed-off-by: Alistair Popple <apopple@nvidia.com>
---
 drivers/accel/amdxdna/amdxdna_gem.c           |  2 +-
 drivers/accel/ivpu/ivpu_gem.c                 |  3 +-
 drivers/accel/qaic/qaic_data.c                |  4 +--
 drivers/dma-buf/dma-buf.c                     | 28 +++++++++----------
 drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c       |  3 +-
 drivers/gpu/drm/armada/armada_gem.c           | 14 ++++++----
 drivers/gpu/drm/drm_prime.c                   |  2 +-
 drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c    |  4 +--
 .../drm/i915/gem/selftests/i915_gem_dmabuf.c  |  3 +-
 drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c     |  2 +-
 drivers/gpu/drm/tegra/gem.c                   |  6 ++--
 drivers/gpu/drm/virtio/virtgpu_prime.c        |  2 +-
 drivers/gpu/drm/xe/xe_bo.c                    |  2 +-
 drivers/iio/industrialio-buffer.c             |  2 +-
 drivers/infiniband/core/umem_dmabuf.c         |  4 +--
 .../media/common/videobuf2/videobuf2-core.c   |  2 +-
 .../common/videobuf2/videobuf2-dma-contig.c   |  2 +-
 .../media/common/videobuf2/videobuf2-dma-sg.c |  2 +-
 .../platform/nvidia/tegra-vde/dmabuf-cache.c  |  2 +-
 drivers/misc/fastrpc.c                        |  3 +-
 drivers/usb/gadget/function/f_fs.c            |  2 +-
 drivers/xen/gntdev-dmabuf.c                   |  2 +-
 include/linux/dma-buf-mapping.h               |  4 +--
 include/linux/dma-buf.h                       | 10 +++----
 io_uring/zcrx.c                               |  3 +-
 net/core/devmem.c                             |  4 +--
 26 files changed, 63 insertions(+), 54 deletions(-)

diff --git a/drivers/accel/amdxdna/amdxdna_gem.c b/drivers/accel/amdxdna/amdxdna_gem.c
index 6253a720cc22..c679ec8230ff 100644
--- a/drivers/accel/amdxdna/amdxdna_gem.c
+++ b/drivers/accel/amdxdna/amdxdna_gem.c
@@ -898,7 +898,7 @@ amdxdna_gem_prime_import(struct drm_device *dev, struct dma_buf *dma_buf)
 		goto put_buf;
 	}
 
-	sgt = dma_buf_map_attachment_unlocked(attach, DMA_BIDIRECTIONAL);
+	sgt = dma_buf_sgt_map_attachment_unlocked(attach, DMA_BIDIRECTIONAL);
 	if (IS_ERR(sgt)) {
 		ret = PTR_ERR(sgt);
 		goto fail_detach;
diff --git a/drivers/accel/ivpu/ivpu_gem.c b/drivers/accel/ivpu/ivpu_gem.c
index 4f2005a8d496..0342a3fc9185 100644
--- a/drivers/accel/ivpu/ivpu_gem.c
+++ b/drivers/accel/ivpu/ivpu_gem.c
@@ -54,7 +54,8 @@ static struct sg_table *ivpu_bo_map_attachment(struct ivpu_device *vdev, struct
 
 	sgt = bo->base.sgt;
 	if (!sgt) {
-		sgt = dma_buf_map_attachment(bo->base.base.import_attach, DMA_BIDIRECTIONAL);
+		sgt = dma_buf_sgt_map_attachment(bo->base.base.import_attach,
+						 DMA_BIDIRECTIONAL);
 		if (IS_ERR(sgt))
 			ivpu_err(vdev, "Failed to map BO in IOMMU: %ld\n", PTR_ERR(sgt));
 		else
diff --git a/drivers/accel/qaic/qaic_data.c b/drivers/accel/qaic/qaic_data.c
index ef0351b6dc9b..b8de1a1e2ab9 100644
--- a/drivers/accel/qaic/qaic_data.c
+++ b/drivers/accel/qaic/qaic_data.c
@@ -863,7 +863,7 @@ struct drm_gem_object *qaic_gem_prime_import(struct drm_device *dev, struct dma_
 
 	drm_gem_private_object_init(dev, obj, attach->dmabuf->size);
 	/*
-	 * skipping dma_buf_map_attachment() as we do not know the direction
+	 * skipping dma_buf_sgt_map_attachment() as we do not know the direction
 	 * just yet. Once the direction is known in the subsequent IOCTL to
 	 * attach slicing, we can do it then.
 	 */
@@ -889,7 +889,7 @@ static int qaic_prepare_import_bo(struct qaic_bo *bo, struct qaic_attach_slice_h
 	struct sg_table *sgt;
 	int ret;
 
-	sgt = dma_buf_map_attachment(obj->import_attach, hdr->dir);
+	sgt = dma_buf_sgt_map_attachment(obj->import_attach, hdr->dir);
 	if (IS_ERR(sgt)) {
 		ret = PTR_ERR(sgt);
 		return ret;
diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c
index dc65752fb0fa..209a1dca19d0 100644
--- a/drivers/dma-buf/dma-buf.c
+++ b/drivers/dma-buf/dma-buf.c
@@ -678,7 +678,7 @@ static struct file *dma_buf_getfile(size_t size, int flags)
  *
  * 3. Once the buffer is attached to all devices userspace can initiate DMA
  *    access to the shared buffer. In the kernel this is done by calling
- *    dma_buf_map_attachment() and dma_buf_unmap_attachment().
+ *    dma_buf_sgt_map_attachment() and dma_buf_unmap_attachment().
  *
  * 4. Once a driver is done with a shared buffer it needs to call
  *    dma_buf_detach() (after cleaning up any mappings) and then release the
@@ -958,7 +958,7 @@ dma_buf_pin_on_map(struct dma_buf_attachment *attach)
  *
  *     - dma_buf_pin()
  *     - dma_buf_unpin()
- *     - dma_buf_map_attachment()
+ *     - dma_buf_sgt_map_attachment()
  *     - dma_buf_unmap_attachment()
  *     - dma_buf_vmap()
  *     - dma_buf_vunmap()
@@ -976,7 +976,7 @@ dma_buf_pin_on_map(struct dma_buf_attachment *attach)
  *     - dma_buf_mmap()
  *     - dma_buf_begin_cpu_access()
  *     - dma_buf_end_cpu_access()
- *     - dma_buf_map_attachment_unlocked()
+ *     - dma_buf_sgt_map_attachment_unlocked()
  *     - dma_buf_unmap_attachment_unlocked()
  *     - dma_buf_vmap_unlocked()
  *     - dma_buf_vunmap_unlocked()
@@ -1302,7 +1302,7 @@ __dma_buf_sgt_map_attachment(struct dma_buf_attachment *attach,
 }
 
 /**
- * dma_buf_map_attachment - Returns the scatterlist table of the attachment;
+ * dma_buf_sgt_map_attachment - Returns the scatterlist table of the attachment;
  * mapped into _device_ address space. Is a wrapper for map_dma_buf() of the
  * dma_buf_ops.
  * @attach:	[in]	attachment whose scatterlist is to be returned
@@ -1322,8 +1322,8 @@ __dma_buf_sgt_map_attachment(struct dma_buf_attachment *attach,
  * Important: Dynamic importers must wait for the exclusive fence of the struct
  * dma_resv attached to the DMA-BUF first.
  */
-struct sg_table *dma_buf_map_attachment(struct dma_buf_attachment *attach,
-					enum dma_data_direction direction)
+struct sg_table *dma_buf_sgt_map_attachment(struct dma_buf_attachment *attach,
+					    enum dma_data_direction direction)
 {
 	struct sg_table *sg_table;
 	int ret;
@@ -1346,7 +1346,7 @@ struct sg_table *dma_buf_map_attachment(struct dma_buf_attachment *attach,
 
 	return sg_table;
 }
-EXPORT_SYMBOL_NS_GPL(dma_buf_map_attachment, "DMA_BUF");
+EXPORT_SYMBOL_NS_GPL(dma_buf_sgt_map_attachment, "DMA_BUF");
 
 /* &dma_buf_mapping_type.map / .unmap for the SGT type */
 struct dma_buf_mapping *dma_buf_sgt_type_map(struct dma_buf_attachment *attach,
@@ -1382,17 +1382,17 @@ void dma_buf_sgt_type_unmap(struct dma_buf_attachment *attach,
 }
 
 /**
- * dma_buf_map_attachment_unlocked - Returns the scatterlist table of the attachment;
+ * dma_buf_sgt_map_attachment_unlocked - Returns the scatterlist table of the attachment;
  * mapped into _device_ address space. Is a wrapper for map_dma_buf() of the
  * dma_buf_ops.
  * @attach:	[in]	attachment whose scatterlist is to be returned
  * @direction:	[in]	direction of DMA transfer
  *
- * Unlocked variant of dma_buf_map_attachment().
+ * Unlocked variant of dma_buf_sgt_map_attachment().
  */
 struct sg_table *
-dma_buf_map_attachment_unlocked(struct dma_buf_attachment *attach,
-				enum dma_data_direction direction)
+dma_buf_sgt_map_attachment_unlocked(struct dma_buf_attachment *attach,
+				    enum dma_data_direction direction)
 {
 	struct sg_table *sg_table;
 
@@ -1402,12 +1402,12 @@ dma_buf_map_attachment_unlocked(struct dma_buf_attachment *attach,
 		return ERR_PTR(-EINVAL);
 
 	dma_resv_lock(attach->dmabuf->resv, NULL);
-	sg_table = dma_buf_map_attachment(attach, direction);
+	sg_table = dma_buf_sgt_map_attachment(attach, direction);
 	dma_resv_unlock(attach->dmabuf->resv);
 
 	return sg_table;
 }
-EXPORT_SYMBOL_NS_GPL(dma_buf_map_attachment_unlocked, "DMA_BUF");
+EXPORT_SYMBOL_NS_GPL(dma_buf_sgt_map_attachment_unlocked, "DMA_BUF");
 
 /**
  * dma_buf_unmap_attachment - unmaps and decreases usecount of the buffer;might
@@ -1417,7 +1417,7 @@ EXPORT_SYMBOL_NS_GPL(dma_buf_map_attachment_unlocked, "DMA_BUF");
  * @sg_table:	[in]	scatterlist info of the buffer to unmap
  * @direction:  [in]    direction of DMA transfer
  *
- * This unmaps a DMA mapping for @attached obtained by dma_buf_map_attachment().
+ * This unmaps a DMA mapping for @attached obtained by dma_buf_sgt_map_attachment().
  */
 void dma_buf_unmap_attachment(struct dma_buf_attachment *attach,
 				struct sg_table *sg_table,
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
index 016957cac1f2..169e1b27ff8e 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
@@ -954,7 +954,8 @@ static int amdgpu_ttm_backend_bind(struct ttm_device *bdev,
 			struct sg_table *sgt;
 
 			attach = gtt->gobj->import_attach;
-			sgt = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL);
+			sgt = dma_buf_sgt_map_attachment(attach,
+							 DMA_BIDIRECTIONAL);
 			if (IS_ERR(sgt))
 				return PTR_ERR(sgt);
 
diff --git a/drivers/gpu/drm/armada/armada_gem.c b/drivers/gpu/drm/armada/armada_gem.c
index 5cea1eab6e5c..506bc82f20d6 100644
--- a/drivers/gpu/drm/armada/armada_gem.c
+++ b/drivers/gpu/drm/armada/armada_gem.c
@@ -531,7 +531,7 @@ armada_gem_prime_import(struct drm_device *dev, struct dma_buf *buf)
 	get_dma_buf(buf);
 
 	/*
-	 * Don't call dma_buf_map_attachment() here - it maps the
+	 * Don't call dma_buf_sgt_map_attachment() here - it maps the
 	 * scatterlist immediately for DMA, and this is not always
 	 * an appropriate thing to do.
 	 */
@@ -542,20 +542,22 @@ int armada_gem_map_import(struct armada_gem_object *dobj)
 {
 	int ret;
 
-	dobj->sgt = dma_buf_map_attachment_unlocked(dobj->obj.import_attach,
-						    DMA_TO_DEVICE);
+	dobj->sgt = dma_buf_sgt_map_attachment_unlocked(dobj->obj.import_attach,
+							DMA_TO_DEVICE);
 	if (IS_ERR(dobj->sgt)) {
 		ret = PTR_ERR(dobj->sgt);
 		dobj->sgt = NULL;
-		DRM_ERROR("dma_buf_map_attachment() error: %d\n", ret);
+		DRM_ERROR("dma_buf_sgt_map_attachment() error: %d\n", ret);
 		return ret;
 	}
 	if (dobj->sgt->nents > 1) {
-		DRM_ERROR("dma_buf_map_attachment() returned an (unsupported) scattered list\n");
+		DRM_ERROR(
+			"dma_buf_sgt_map_attachment() returned an (unsupported) scattered list\n");
 		return -EINVAL;
 	}
 	if (sg_dma_len(dobj->sgt->sgl) < dobj->obj.size) {
-		DRM_ERROR("dma_buf_map_attachment() returned a small buffer\n");
+		DRM_ERROR(
+			"dma_buf_sgt_map_attachment() returned a small buffer\n");
 		return -EINVAL;
 	}
 	dobj->dev_addr = sg_dma_address(dobj->sgt->sgl);
diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c
index 7792caf87883..330b64b3324a 100644
--- a/drivers/gpu/drm/drm_prime.c
+++ b/drivers/gpu/drm/drm_prime.c
@@ -1005,7 +1005,7 @@ struct drm_gem_object *drm_gem_prime_import_dev(struct drm_device *dev,
 
 	get_dma_buf(dma_buf);
 
-	sgt = dma_buf_map_attachment_unlocked(attach, DMA_BIDIRECTIONAL);
+	sgt = dma_buf_sgt_map_attachment_unlocked(attach, DMA_BIDIRECTIONAL);
 	if (IS_ERR(sgt)) {
 		ret = PTR_ERR(sgt);
 		goto fail_detach;
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
index 5333e77e62e0..04c7b9a97681 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
@@ -242,8 +242,8 @@ static int i915_gem_object_get_pages_dmabuf(struct drm_i915_gem_object *obj)
 
 	assert_object_held(obj);
 
-	sgt = dma_buf_map_attachment(obj->base.import_attach,
-				     DMA_BIDIRECTIONAL);
+	sgt = dma_buf_sgt_map_attachment(obj->base.import_attach,
+					 DMA_BIDIRECTIONAL);
 	if (IS_ERR(sgt))
 		return PTR_ERR(sgt);
 
diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_dmabuf.c b/drivers/gpu/drm/i915/gem/selftests/i915_gem_dmabuf.c
index 2fda549dd82d..fcfa819caa38 100644
--- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_dmabuf.c
+++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_dmabuf.c
@@ -293,7 +293,8 @@ static int igt_dmabuf_import_same_driver(struct drm_i915_private *i915,
 		goto out_import;
 	}
 
-	st = dma_buf_map_attachment_unlocked(import_attach, DMA_BIDIRECTIONAL);
+	st = dma_buf_sgt_map_attachment_unlocked(import_attach,
+						 DMA_BIDIRECTIONAL);
 	if (IS_ERR(st)) {
 		err = PTR_ERR(st);
 		goto out_detach;
diff --git a/drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c b/drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c
index 23beaeefab67..569ee2d3ab6f 100644
--- a/drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c
+++ b/drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c
@@ -121,7 +121,7 @@ struct drm_gem_object *omap_gem_prime_import(struct drm_device *dev,
 
 	get_dma_buf(dma_buf);
 
-	sgt = dma_buf_map_attachment_unlocked(attach, DMA_TO_DEVICE);
+	sgt = dma_buf_sgt_map_attachment_unlocked(attach, DMA_TO_DEVICE);
 	if (IS_ERR(sgt)) {
 		ret = PTR_ERR(sgt);
 		goto fail_detach;
diff --git a/drivers/gpu/drm/tegra/gem.c b/drivers/gpu/drm/tegra/gem.c
index feb783ceb0d1..fcb9308f49f0 100644
--- a/drivers/gpu/drm/tegra/gem.c
+++ b/drivers/gpu/drm/tegra/gem.c
@@ -87,7 +87,8 @@ static struct host1x_bo_mapping *tegra_bo_pin(struct device *dev, struct host1x_
 			goto free;
 		}
 
-		map->sgt = dma_buf_map_attachment_unlocked(map->attach, direction);
+		map->sgt = dma_buf_sgt_map_attachment_unlocked(map->attach,
+							       direction);
 		if (IS_ERR(map->sgt)) {
 			dma_buf_detach(buf, map->attach);
 			err = PTR_ERR(map->sgt);
@@ -480,7 +481,8 @@ static struct tegra_bo *tegra_bo_import(struct drm_device *drm,
 			goto free;
 		}
 
-		bo->sgt = dma_buf_map_attachment_unlocked(attach, DMA_TO_DEVICE);
+		bo->sgt = dma_buf_sgt_map_attachment_unlocked(attach,
+							      DMA_TO_DEVICE);
 		if (IS_ERR(bo->sgt)) {
 			err = PTR_ERR(bo->sgt);
 			goto detach;
diff --git a/drivers/gpu/drm/virtio/virtgpu_prime.c b/drivers/gpu/drm/virtio/virtgpu_prime.c
index 3d5203ac19b6..de69590b5076 100644
--- a/drivers/gpu/drm/virtio/virtgpu_prime.c
+++ b/drivers/gpu/drm/virtio/virtgpu_prime.c
@@ -164,7 +164,7 @@ int virtgpu_dma_buf_import_sgt(struct virtio_gpu_mem_entry **ents,
 	if (ret <= 0)
 		return ret < 0 ? ret : -ETIMEDOUT;
 
-	sgt = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL);
+	sgt = dma_buf_sgt_map_attachment(attach, DMA_BIDIRECTIONAL);
 	if (IS_ERR(sgt))
 		return PTR_ERR(sgt);
 
diff --git a/drivers/gpu/drm/xe/xe_bo.c b/drivers/gpu/drm/xe/xe_bo.c
index b4921a627ff3..4d93b8926ed6 100644
--- a/drivers/gpu/drm/xe/xe_bo.c
+++ b/drivers/gpu/drm/xe/xe_bo.c
@@ -771,7 +771,7 @@ static int xe_bo_move_dmabuf(struct ttm_buffer_object *ttm_bo,
 		ttm_bo->sg = NULL;
 	}
 
-	sg = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL);
+	sg = dma_buf_sgt_map_attachment(attach, DMA_BIDIRECTIONAL);
 	if (IS_ERR(sg))
 		return PTR_ERR(sg);
 
diff --git a/drivers/iio/industrialio-buffer.c b/drivers/iio/industrialio-buffer.c
index a00985c92251..619181968ff9 100644
--- a/drivers/iio/industrialio-buffer.c
+++ b/drivers/iio/industrialio-buffer.c
@@ -1730,7 +1730,7 @@ static int iio_buffer_attach_dmabuf(struct iio_dev_buffer_pair *ib,
 	priv->dir = buffer->direction == IIO_BUFFER_DIRECTION_IN
 		? DMA_FROM_DEVICE : DMA_TO_DEVICE;
 
-	priv->sgt = dma_buf_map_attachment(attach, priv->dir);
+	priv->sgt = dma_buf_sgt_map_attachment(attach, priv->dir);
 	if (IS_ERR(priv->sgt)) {
 		err = PTR_ERR(priv->sgt);
 		dev_err(&indio_dev->dev, "Unable to map attachment: %d\n", err);
diff --git a/drivers/infiniband/core/umem_dmabuf.c b/drivers/infiniband/core/umem_dmabuf.c
index 39b5564a4c35..dd584f8dcd1c 100644
--- a/drivers/infiniband/core/umem_dmabuf.c
+++ b/drivers/infiniband/core/umem_dmabuf.c
@@ -29,8 +29,8 @@ int ib_umem_dmabuf_map_pages(struct ib_umem_dmabuf *umem_dmabuf)
 	if (umem_dmabuf->sgt)
 		goto wait_fence;
 
-	sgt = dma_buf_map_attachment(umem_dmabuf->attach,
-				     DMA_BIDIRECTIONAL);
+	sgt = dma_buf_sgt_map_attachment(umem_dmabuf->attach,
+					 DMA_BIDIRECTIONAL);
 	if (IS_ERR(sgt))
 		return PTR_ERR(sgt);
 
diff --git a/drivers/media/common/videobuf2/videobuf2-core.c b/drivers/media/common/videobuf2/videobuf2-core.c
index b0a6084f1757..5cd53e06da0b 100644
--- a/drivers/media/common/videobuf2/videobuf2-core.c
+++ b/drivers/media/common/videobuf2/videobuf2-core.c
@@ -1464,7 +1464,7 @@ static int __prepare_dmabuf(struct vb2_buffer *vb)
 			vb->planes[plane].mem_priv = mem_priv;
 
 			/*
-			 * This pins the buffer(s) with dma_buf_map_attachment()). It's done
+			 * This pins the buffer(s) with dma_buf_sgt_map_attachment()). It's done
 			 * here instead just before the DMA, while queueing the buffer(s) so
 			 * userspace knows sooner rather than later if the dma-buf map fails.
 			 */
diff --git a/drivers/media/common/videobuf2/videobuf2-dma-contig.c b/drivers/media/common/videobuf2/videobuf2-dma-contig.c
index 536f839258c6..0ce643940898 100644
--- a/drivers/media/common/videobuf2/videobuf2-dma-contig.c
+++ b/drivers/media/common/videobuf2/videobuf2-dma-contig.c
@@ -706,7 +706,7 @@ static int vb2_dc_map_dmabuf(void *mem_priv)
 	}
 
 	/* get the associated scatterlist for this buffer */
-	sgt = dma_buf_map_attachment_unlocked(buf->db_attach, buf->dma_dir);
+	sgt = dma_buf_sgt_map_attachment_unlocked(buf->db_attach, buf->dma_dir);
 	if (IS_ERR(sgt)) {
 		pr_err("Error getting dmabuf scatterlist\n");
 		return -EINVAL;
diff --git a/drivers/media/common/videobuf2/videobuf2-dma-sg.c b/drivers/media/common/videobuf2/videobuf2-dma-sg.c
index fba2027e6e8d..17191373c69c 100644
--- a/drivers/media/common/videobuf2/videobuf2-dma-sg.c
+++ b/drivers/media/common/videobuf2/videobuf2-dma-sg.c
@@ -569,7 +569,7 @@ static int vb2_dma_sg_map_dmabuf(void *mem_priv)
 	}
 
 	/* get the associated scatterlist for this buffer */
-	sgt = dma_buf_map_attachment_unlocked(buf->db_attach, buf->dma_dir);
+	sgt = dma_buf_sgt_map_attachment_unlocked(buf->db_attach, buf->dma_dir);
 	if (IS_ERR(sgt)) {
 		pr_err("Error getting dmabuf scatterlist\n");
 		return -EINVAL;
diff --git a/drivers/media/platform/nvidia/tegra-vde/dmabuf-cache.c b/drivers/media/platform/nvidia/tegra-vde/dmabuf-cache.c
index 7752064be783..8f3443fa0eb5 100644
--- a/drivers/media/platform/nvidia/tegra-vde/dmabuf-cache.c
+++ b/drivers/media/platform/nvidia/tegra-vde/dmabuf-cache.c
@@ -102,7 +102,7 @@ int tegra_vde_dmabuf_cache_map(struct tegra_vde *vde,
 		goto err_unlock;
 	}
 
-	sgt = dma_buf_map_attachment_unlocked(attachment, dma_dir);
+	sgt = dma_buf_sgt_map_attachment_unlocked(attachment, dma_dir);
 	if (IS_ERR(sgt)) {
 		dev_err(dev, "Failed to get dmabufs sg_table\n");
 		err = PTR_ERR(sgt);
diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c
index 85fed3a12f9c..fce849417eb7 100644
--- a/drivers/misc/fastrpc.c
+++ b/drivers/misc/fastrpc.c
@@ -911,7 +911,8 @@ static int fastrpc_map_attach(struct fastrpc_user *fl, int fd,
 		goto attach_err;
 	}
 
-	table = dma_buf_map_attachment_unlocked(map->attach, DMA_BIDIRECTIONAL);
+	table = dma_buf_sgt_map_attachment_unlocked(map->attach,
+						    DMA_BIDIRECTIONAL);
 	if (IS_ERR(table)) {
 		err = PTR_ERR(table);
 		goto map_err;
diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c
index 09680534623e..fe3c43ba72c6 100644
--- a/drivers/usb/gadget/function/f_fs.c
+++ b/drivers/usb/gadget/function/f_fs.c
@@ -1567,7 +1567,7 @@ static int ffs_dmabuf_attach(struct file *file, int fd)
 	if (err)
 		goto err_free_priv;
 
-	sg_table = dma_buf_map_attachment(attach, dir);
+	sg_table = dma_buf_sgt_map_attachment(attach, dir);
 	dma_resv_unlock(dmabuf->resv);
 
 	if (IS_ERR(sg_table)) {
diff --git a/drivers/xen/gntdev-dmabuf.c b/drivers/xen/gntdev-dmabuf.c
index 028cd7295fd7..3bb05596920e 100644
--- a/drivers/xen/gntdev-dmabuf.c
+++ b/drivers/xen/gntdev-dmabuf.c
@@ -588,7 +588,7 @@ dmabuf_imp_to_refs(struct gntdev_dmabuf_priv *priv, struct device *dev,
 
 	gntdev_dmabuf->u.imp.attach = attach;
 
-	sgt = dma_buf_map_attachment_unlocked(attach, DMA_BIDIRECTIONAL);
+	sgt = dma_buf_sgt_map_attachment_unlocked(attach, DMA_BIDIRECTIONAL);
 	if (IS_ERR(sgt)) {
 		ret = ERR_CAST(sgt);
 		goto fail_detach;
diff --git a/include/linux/dma-buf-mapping.h b/include/linux/dma-buf-mapping.h
index 91a55cbe0bb4..02d79d5615b5 100644
--- a/include/linux/dma-buf-mapping.h
+++ b/include/linux/dma-buf-mapping.h
@@ -171,7 +171,7 @@ void dma_buf_sgt_type_unmap(struct dma_buf_attachment *attach,
  *
  * When this type is matched the map/unmap functions are:
  *
- *  dma_buf_map_attachment()
+ *  dma_buf_sgt_map_attachment()
  *  dma_buf_unmap_attachment()
  *
  * The struct sg_table returned by those functions has only the DMA portions
@@ -206,7 +206,7 @@ struct dma_buf_mapping_sgt_exp_ops {
 	/**
 	 * @map_dma_buf:
 	 *
-	 * This is called by dma_buf_map_attachment() and is used to map a
+	 * This is called by dma_buf_sgt_map_attachment() and is used to map a
 	 * shared &dma_buf into device address space, and it is mandatory. It
 	 * can only be called if @attach has been called successfully.
 	 *
diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h
index 77a18b9817ac..ee6c97a5cecd 100644
--- a/include/linux/dma-buf.h
+++ b/include/linux/dma-buf.h
@@ -515,7 +515,7 @@ struct dma_buf_attach_ops {
  *
  * An attachment is created by calling dma_buf_attach(), and released again by
  * calling dma_buf_detach(). The DMA mapping itself needed to initiate a
- * transfer is created by dma_buf_map_attachment() and freed again by calling
+ * transfer is created by dma_buf_sgt_map_attachment() and freed again by calling
  * dma_buf_unmap_attachment().
  */
 struct dma_buf_attachment {
@@ -614,8 +614,8 @@ void dma_buf_fd_install(struct dma_buf *dmabuf, int fd);
 struct dma_buf *dma_buf_get(int fd);
 void dma_buf_put(struct dma_buf *dmabuf);
 
-struct sg_table *dma_buf_map_attachment(struct dma_buf_attachment *,
-					enum dma_data_direction);
+struct sg_table *dma_buf_sgt_map_attachment(struct dma_buf_attachment *,
+					    enum dma_data_direction);
 void dma_buf_unmap_attachment(struct dma_buf_attachment *, struct sg_table *,
 				enum dma_data_direction);
 void dma_buf_invalidate_mappings(struct dma_buf *dma_buf);
@@ -625,8 +625,8 @@ int dma_buf_begin_cpu_access(struct dma_buf *dma_buf,
 int dma_buf_end_cpu_access(struct dma_buf *dma_buf,
 			   enum dma_data_direction dir);
 struct sg_table *
-dma_buf_map_attachment_unlocked(struct dma_buf_attachment *attach,
-				enum dma_data_direction direction);
+dma_buf_sgt_map_attachment_unlocked(struct dma_buf_attachment *attach,
+				    enum dma_data_direction direction);
 void dma_buf_unmap_attachment_unlocked(struct dma_buf_attachment *attach,
 				       struct sg_table *sg_table,
 				       enum dma_data_direction direction);
diff --git a/io_uring/zcrx.c b/io_uring/zcrx.c
index 86d580d4410d..3f8be77a50dc 100644
--- a/io_uring/zcrx.c
+++ b/io_uring/zcrx.c
@@ -182,7 +182,8 @@ static int io_import_dmabuf(struct io_zcrx_ifq *ifq,
 		goto err;
 	}
 
-	mem->sgt = dma_buf_map_attachment_unlocked(mem->attach, DMA_FROM_DEVICE);
+	mem->sgt = dma_buf_sgt_map_attachment_unlocked(mem->attach,
+						       DMA_FROM_DEVICE);
 	if (IS_ERR(mem->sgt)) {
 		ret = PTR_ERR(mem->sgt);
 		mem->sgt = NULL;
diff --git a/net/core/devmem.c b/net/core/devmem.c
index f4d60654ce7f..86b3c54933bb 100644
--- a/net/core/devmem.c
+++ b/net/core/devmem.c
@@ -241,8 +241,8 @@ net_devmem_bind_dmabuf(struct net_device *dev, void *vdev,
 		goto err_exit_ref;
 	}
 
-	binding->sgt = dma_buf_map_attachment_unlocked(binding->attachment,
-						       direction);
+	binding->sgt = dma_buf_sgt_map_attachment_unlocked(binding->attachment,
+							   direction);
 	if (IS_ERR(binding->sgt)) {
 		err = PTR_ERR(binding->sgt);
 		NL_SET_ERR_MSG(extack, "Failed to map dmabuf attachment");
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 71+ messages in thread

* [PATCH 22/26] treewide: Rename dma_buf_unmap_attachment(_unlocked) to dma_buf_sgt_*
  2026-10-26  5:35 [PATCH 00/26] DMA-buf mapping types Alistair Popple
                   ` (20 preceding siblings ...)
  2026-10-26  5:36 ` [PATCH 21/26] treewide: Rename dma_buf_map_attachment(_unlocked) to dma_buf_sgt_ Alistair Popple
@ 2026-10-26  5:36 ` Alistair Popple
  2026-10-26  9:56   ` sashiko-bot
  2026-10-26  5:36 ` [PATCH 23/26] treewide: Rename dma_buf_attach() to dma_buf_sgt_attach() Alistair Popple
                   ` (3 subsequent siblings)
  25 siblings, 1 reply; 71+ messages in thread
From: Alistair Popple @ 2026-10-26  5:36 UTC (permalink / raw)
  To: dri-devel, christian.koenig, sumit.semwal, jgg
  Cc: Alistair Popple, Thomas Hellström, Simona Vetter,
	Matthew Brost, Vivek Kasireddy, Dongwon Kim, Leon Romanovsky,
	Kevin Tian, Xu Yilun, Karl Mehltretter, Baolu Lu, Felix Kuehling,
	Alex Deucher, intel-xe, amd-gfx, linux-media, linaro-mm-sig,
	linux-rdma, iommu, Alexey Kardashevskiy, zhipingz, treding,
	jhubbard

From: Jason Gunthorpe <jgg@nvidia.com>

This unmap function only works with SGT importers.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/accel/amdxdna/amdxdna_gem.c           |  5 +--
 drivers/accel/ivpu/ivpu_gem.c                 |  5 +--
 drivers/accel/qaic/qaic_data.c                |  2 +-
 drivers/dma-buf/dma-buf.c                     | 34 +++++++++----------
 drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c       |  3 +-
 drivers/gpu/drm/armada/armada_gem.c           |  5 +--
 drivers/gpu/drm/drm_prime.c                   |  5 +--
 drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c    |  4 +--
 drivers/gpu/drm/i915/gem/i915_gem_object.c    |  2 +-
 .../drm/i915/gem/selftests/i915_gem_dmabuf.c  |  3 +-
 drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c     |  2 +-
 drivers/gpu/drm/tegra/gem.c                   | 11 +++---
 drivers/gpu/drm/virtio/virtgpu_prime.c        |  6 ++--
 drivers/gpu/drm/xe/xe_bo.c                    | 16 +++++----
 drivers/iio/industrialio-buffer.c             |  4 +--
 drivers/infiniband/core/umem_dmabuf.c         |  4 +--
 .../common/videobuf2/videobuf2-dma-contig.c   |  7 ++--
 .../media/common/videobuf2/videobuf2-dma-sg.c |  3 +-
 .../platform/nvidia/tegra-vde/dmabuf-cache.c  |  5 +--
 drivers/misc/fastrpc.c                        |  4 +--
 drivers/usb/gadget/function/f_fs.c            |  2 +-
 drivers/xen/gntdev-dmabuf.c                   |  6 ++--
 include/linux/dma-buf-mapping.h               |  4 +--
 include/linux/dma-buf.h                       | 12 +++----
 io_uring/zcrx.c                               |  4 +--
 net/core/devmem.c                             |  8 ++---
 26 files changed, 89 insertions(+), 77 deletions(-)

diff --git a/drivers/accel/amdxdna/amdxdna_gem.c b/drivers/accel/amdxdna/amdxdna_gem.c
index c679ec8230ff..a7e759bb0460 100644
--- a/drivers/accel/amdxdna/amdxdna_gem.c
+++ b/drivers/accel/amdxdna/amdxdna_gem.c
@@ -592,7 +592,8 @@ static struct dma_buf *amdxdna_gem_prime_export(struct drm_gem_object *gobj, int
 
 static void amdxdna_imported_obj_free(struct amdxdna_gem_obj *abo)
 {
-	dma_buf_unmap_attachment_unlocked(abo->attach, abo->base.sgt, DMA_BIDIRECTIONAL);
+	dma_buf_sgt_unmap_attachment_unlocked(abo->attach, abo->base.sgt,
+					      DMA_BIDIRECTIONAL);
 	dma_buf_detach(abo->dma_buf, abo->attach);
 	dma_buf_put(abo->dma_buf);
 	drm_gem_object_release(to_gobj(abo));
@@ -919,7 +920,7 @@ amdxdna_gem_prime_import(struct drm_device *dev, struct dma_buf *dma_buf)
 	return gobj;
 
 fail_unmap:
-	dma_buf_unmap_attachment_unlocked(attach, sgt, DMA_BIDIRECTIONAL);
+	dma_buf_sgt_unmap_attachment_unlocked(attach, sgt, DMA_BIDIRECTIONAL);
 fail_detach:
 	dma_buf_detach(dma_buf, attach);
 put_buf:
diff --git a/drivers/accel/ivpu/ivpu_gem.c b/drivers/accel/ivpu/ivpu_gem.c
index 0342a3fc9185..8d6ed95ccc7c 100644
--- a/drivers/accel/ivpu/ivpu_gem.c
+++ b/drivers/accel/ivpu/ivpu_gem.c
@@ -159,8 +159,9 @@ static void ivpu_bo_unbind_locked(struct ivpu_bo *bo)
 
 	if (bo->base.sgt) {
 		if (drm_gem_is_imported(&bo->base.base)) {
-			dma_buf_unmap_attachment(bo->base.base.import_attach,
-						 bo->base.sgt, DMA_BIDIRECTIONAL);
+			dma_buf_sgt_unmap_attachment(
+				bo->base.base.import_attach, bo->base.sgt,
+				DMA_BIDIRECTIONAL);
 		} else {
 			dma_unmap_sgtable(vdev->drm.dev, bo->base.sgt, DMA_BIDIRECTIONAL, 0);
 			sg_free_table(bo->base.sgt);
diff --git a/drivers/accel/qaic/qaic_data.c b/drivers/accel/qaic/qaic_data.c
index b8de1a1e2ab9..92d49448df72 100644
--- a/drivers/accel/qaic/qaic_data.c
+++ b/drivers/accel/qaic/qaic_data.c
@@ -930,7 +930,7 @@ static int qaic_prepare_bo(struct qaic_device *qdev, struct qaic_bo *bo,
 
 static void qaic_unprepare_import_bo(struct qaic_bo *bo)
 {
-	dma_buf_unmap_attachment(bo->base.import_attach, bo->sgt, bo->dir);
+	dma_buf_sgt_unmap_attachment(bo->base.import_attach, bo->sgt, bo->dir);
 	bo->sgt = NULL;
 }
 
diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c
index 209a1dca19d0..12604c60122e 100644
--- a/drivers/dma-buf/dma-buf.c
+++ b/drivers/dma-buf/dma-buf.c
@@ -678,7 +678,7 @@ static struct file *dma_buf_getfile(size_t size, int flags)
  *
  * 3. Once the buffer is attached to all devices userspace can initiate DMA
  *    access to the shared buffer. In the kernel this is done by calling
- *    dma_buf_sgt_map_attachment() and dma_buf_unmap_attachment().
+ *    dma_buf_sgt_map_attachment() and dma_buf_sgt_unmap_attachment().
  *
  * 4. Once a driver is done with a shared buffer it needs to call
  *    dma_buf_detach() (after cleaning up any mappings) and then release the
@@ -959,7 +959,7 @@ dma_buf_pin_on_map(struct dma_buf_attachment *attach)
  *     - dma_buf_pin()
  *     - dma_buf_unpin()
  *     - dma_buf_sgt_map_attachment()
- *     - dma_buf_unmap_attachment()
+ *     - dma_buf_sgt_unmap_attachment()
  *     - dma_buf_vmap()
  *     - dma_buf_vunmap()
  *
@@ -977,7 +977,7 @@ dma_buf_pin_on_map(struct dma_buf_attachment *attach)
  *     - dma_buf_begin_cpu_access()
  *     - dma_buf_end_cpu_access()
  *     - dma_buf_sgt_map_attachment_unlocked()
- *     - dma_buf_unmap_attachment_unlocked()
+ *     - dma_buf_sgt_unmap_attachment_unlocked()
  *     - dma_buf_vmap_unlocked()
  *     - dma_buf_vunmap_unlocked()
  *
@@ -1314,7 +1314,7 @@ __dma_buf_sgt_map_attachment(struct dma_buf_attachment *attach,
  * On success, the DMA addresses and lengths in the returned scatterlist are
  * PAGE_SIZE aligned.
  *
- * A mapping must be unmapped by using dma_buf_unmap_attachment(). Note that
+ * A mapping must be unmapped by using dma_buf_sgt_unmap_attachment(). Note that
  * the underlying backing storage is pinned for as long as a mapping exists,
  * therefore users/importers should not hold onto a mapping for undue amounts of
  * time.
@@ -1377,7 +1377,7 @@ void dma_buf_sgt_type_unmap(struct dma_buf_attachment *attach,
 	struct dma_buf_sgt_mapping *mapping =
 		container_of(base, struct dma_buf_sgt_mapping, base);
 
-	dma_buf_unmap_attachment(attach, mapping->sgt, dir);
+	dma_buf_sgt_unmap_attachment(attach, mapping->sgt, dir);
 	kfree(mapping);
 }
 
@@ -1410,7 +1410,7 @@ dma_buf_sgt_map_attachment_unlocked(struct dma_buf_attachment *attach,
 EXPORT_SYMBOL_NS_GPL(dma_buf_sgt_map_attachment_unlocked, "DMA_BUF");
 
 /**
- * dma_buf_unmap_attachment - unmaps and decreases usecount of the buffer;might
+ * dma_buf_sgt_unmap_attachment - unmaps and decreases usecount of the buffer;might
  * deallocate the scatterlist associated. Is a wrapper for unmap_dma_buf() of
  * dma_buf_ops.
  * @attach:	[in]	attachment to unmap buffer from
@@ -1419,9 +1419,9 @@ EXPORT_SYMBOL_NS_GPL(dma_buf_sgt_map_attachment_unlocked, "DMA_BUF");
  *
  * This unmaps a DMA mapping for @attached obtained by dma_buf_sgt_map_attachment().
  */
-void dma_buf_unmap_attachment(struct dma_buf_attachment *attach,
-				struct sg_table *sg_table,
-				enum dma_data_direction direction)
+void dma_buf_sgt_unmap_attachment(struct dma_buf_attachment *attach,
+				  struct sg_table *sg_table,
+				  enum dma_data_direction direction)
 {
 	const struct dma_buf_mapping_sgt_exp_ops *sgt_exp_ops =
 		dma_buf_get_sgt_ops(attach);
@@ -1439,21 +1439,21 @@ void dma_buf_unmap_attachment(struct dma_buf_attachment *attach,
 	if (dma_buf_pin_on_map(attach))
 		attach->dmabuf->ops->unpin(attach);
 }
-EXPORT_SYMBOL_NS_GPL(dma_buf_unmap_attachment, "DMA_BUF");
+EXPORT_SYMBOL_NS_GPL(dma_buf_sgt_unmap_attachment, "DMA_BUF");
 
 /**
- * dma_buf_unmap_attachment_unlocked - unmaps and decreases usecount of the buffer;might
+ * dma_buf_sgt_unmap_attachment_unlocked - unmaps and decreases usecount of the buffer;might
  * deallocate the scatterlist associated. Is a wrapper for unmap_dma_buf() of
  * dma_buf_ops.
  * @attach:	[in]	attachment to unmap buffer from
  * @sg_table:	[in]	scatterlist info of the buffer to unmap
  * @direction:	[in]	direction of DMA transfer
  *
- * Unlocked variant of dma_buf_unmap_attachment().
+ * Unlocked variant of dma_buf_sgt_unmap_attachment().
  */
-void dma_buf_unmap_attachment_unlocked(struct dma_buf_attachment *attach,
-				       struct sg_table *sg_table,
-				       enum dma_data_direction direction)
+void dma_buf_sgt_unmap_attachment_unlocked(struct dma_buf_attachment *attach,
+					   struct sg_table *sg_table,
+					   enum dma_data_direction direction)
 {
 	might_sleep();
 
@@ -1461,10 +1461,10 @@ void dma_buf_unmap_attachment_unlocked(struct dma_buf_attachment *attach,
 		return;
 
 	dma_resv_lock(attach->dmabuf->resv, NULL);
-	dma_buf_unmap_attachment(attach, sg_table, direction);
+	dma_buf_sgt_unmap_attachment(attach, sg_table, direction);
 	dma_resv_unlock(attach->dmabuf->resv);
 }
-EXPORT_SYMBOL_NS_GPL(dma_buf_unmap_attachment_unlocked, "DMA_BUF");
+EXPORT_SYMBOL_NS_GPL(dma_buf_sgt_unmap_attachment_unlocked, "DMA_BUF");
 
 /**
  * dma_buf_attach_revocable - check if a DMA-buf importer implements
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
index 169e1b27ff8e..e22dbd2e43b9 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
@@ -1076,7 +1076,8 @@ static void amdgpu_ttm_backend_unbind(struct ttm_device *bdev,
 		struct dma_buf_attachment *attach;
 
 		attach = gtt->gobj->import_attach;
-		dma_buf_unmap_attachment(attach, ttm->sg, DMA_BIDIRECTIONAL);
+		dma_buf_sgt_unmap_attachment(attach, ttm->sg,
+					     DMA_BIDIRECTIONAL);
 		ttm->sg = NULL;
 	}
 
diff --git a/drivers/gpu/drm/armada/armada_gem.c b/drivers/gpu/drm/armada/armada_gem.c
index 506bc82f20d6..72c7cd2b3fb9 100644
--- a/drivers/gpu/drm/armada/armada_gem.c
+++ b/drivers/gpu/drm/armada/armada_gem.c
@@ -68,8 +68,9 @@ void armada_gem_free_object(struct drm_gem_object *obj)
 	if (dobj->obj.import_attach) {
 		/* We only ever display imported data */
 		if (dobj->sgt)
-			dma_buf_unmap_attachment_unlocked(dobj->obj.import_attach,
-							  dobj->sgt, DMA_TO_DEVICE);
+			dma_buf_sgt_unmap_attachment_unlocked(
+				dobj->obj.import_attach, dobj->sgt,
+				DMA_TO_DEVICE);
 		drm_prime_gem_destroy(&dobj->obj, NULL);
 	}
 
diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c
index 330b64b3324a..3ffbe3d28929 100644
--- a/drivers/gpu/drm/drm_prime.c
+++ b/drivers/gpu/drm/drm_prime.c
@@ -1023,7 +1023,7 @@ struct drm_gem_object *drm_gem_prime_import_dev(struct drm_device *dev,
 	return obj;
 
 fail_unmap:
-	dma_buf_unmap_attachment_unlocked(attach, sgt, DMA_BIDIRECTIONAL);
+	dma_buf_sgt_unmap_attachment_unlocked(attach, sgt, DMA_BIDIRECTIONAL);
 fail_detach:
 	dma_buf_detach(dma_buf, attach);
 	dma_buf_put(dma_buf);
@@ -1121,7 +1121,8 @@ void drm_prime_gem_destroy(struct drm_gem_object *obj, struct sg_table *sg)
 
 	attach = obj->import_attach;
 	if (sg)
-		dma_buf_unmap_attachment_unlocked(attach, sg, DMA_BIDIRECTIONAL);
+		dma_buf_sgt_unmap_attachment_unlocked(attach, sg,
+						      DMA_BIDIRECTIONAL);
 	dma_buf = attach->dmabuf;
 	dma_buf_detach(attach->dmabuf, attach);
 	/* remove the reference */
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
index 04c7b9a97681..7f939c281308 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
@@ -270,8 +270,8 @@ static int i915_gem_object_get_pages_dmabuf(struct drm_i915_gem_object *obj)
 static void i915_gem_object_put_pages_dmabuf(struct drm_i915_gem_object *obj,
 					     struct sg_table *sgt)
 {
-	dma_buf_unmap_attachment(obj->base.import_attach, sgt,
-				 DMA_BIDIRECTIONAL);
+	dma_buf_sgt_unmap_attachment(obj->base.import_attach, sgt,
+				     DMA_BIDIRECTIONAL);
 }
 
 static const struct drm_i915_gem_object_ops i915_gem_object_dmabuf_ops = {
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.c b/drivers/gpu/drm/i915/gem/i915_gem_object.c
index 9e01f8b2079a..510d914494de 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_object.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_object.c
@@ -367,7 +367,7 @@ void __i915_gem_object_pages_fini(struct drm_i915_gem_object *obj)
 	atomic_set(&obj->mm.pages_pin_count, 0);
 
 	/*
-	 * dma_buf_unmap_attachment() requires reservation to be
+	 * dma_buf_sgt_unmap_attachment() requires reservation to be
 	 * locked. The imported GEM shouldn't share reservation lock
 	 * and ttm_bo_cleanup_memtype_use() shouldn't be invoked for
 	 * dma-buf, so it's safe to take the lock.
diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_dmabuf.c b/drivers/gpu/drm/i915/gem/selftests/i915_gem_dmabuf.c
index fcfa819caa38..6b6d235fd3e9 100644
--- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_dmabuf.c
+++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_dmabuf.c
@@ -307,7 +307,8 @@ static int igt_dmabuf_import_same_driver(struct drm_i915_private *i915,
 		timeout = -ETIME;
 	}
 	err = timeout > 0 ? 0 : timeout;
-	dma_buf_unmap_attachment_unlocked(import_attach, st, DMA_BIDIRECTIONAL);
+	dma_buf_sgt_unmap_attachment_unlocked(import_attach, st,
+					      DMA_BIDIRECTIONAL);
 out_detach:
 	dma_buf_detach(dmabuf, import_attach);
 out_import:
diff --git a/drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c b/drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c
index 569ee2d3ab6f..c549b94b2e8a 100644
--- a/drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c
+++ b/drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c
@@ -138,7 +138,7 @@ struct drm_gem_object *omap_gem_prime_import(struct drm_device *dev,
 	return obj;
 
 fail_unmap:
-	dma_buf_unmap_attachment_unlocked(attach, sgt, DMA_TO_DEVICE);
+	dma_buf_sgt_unmap_attachment_unlocked(attach, sgt, DMA_TO_DEVICE);
 fail_detach:
 	dma_buf_detach(dma_buf, attach);
 	dma_buf_put(dma_buf);
diff --git a/drivers/gpu/drm/tegra/gem.c b/drivers/gpu/drm/tegra/gem.c
index fcb9308f49f0..f06826fe8366 100644
--- a/drivers/gpu/drm/tegra/gem.c
+++ b/drivers/gpu/drm/tegra/gem.c
@@ -164,8 +164,8 @@ static struct host1x_bo_mapping *tegra_bo_pin(struct device *dev, struct host1x_
 static void tegra_bo_unpin(struct host1x_bo_mapping *map)
 {
 	if (map->attach) {
-		dma_buf_unmap_attachment_unlocked(map->attach, map->sgt,
-						  map->direction);
+		dma_buf_sgt_unmap_attachment_unlocked(map->attach, map->sgt,
+						      map->direction);
 		dma_buf_detach(map->attach->dmabuf, map->attach);
 	} else {
 		dma_unmap_sgtable(map->dev, map->sgt, map->direction, 0);
@@ -502,7 +502,8 @@ static struct tegra_bo *tegra_bo_import(struct drm_device *drm,
 
 detach:
 	if (!IS_ERR_OR_NULL(bo->sgt))
-		dma_buf_unmap_attachment_unlocked(attach, bo->sgt, DMA_TO_DEVICE);
+		dma_buf_sgt_unmap_attachment_unlocked(attach, bo->sgt,
+						      DMA_TO_DEVICE);
 
 	dma_buf_detach(buf, attach);
 	dma_buf_put(buf);
@@ -523,8 +524,8 @@ void tegra_bo_free_object(struct drm_gem_object *gem)
 		tegra_bo_iommu_unmap(tegra, bo);
 
 		if (drm_gem_is_imported(gem)) {
-			dma_buf_unmap_attachment_unlocked(gem->import_attach, bo->sgt,
-							  DMA_TO_DEVICE);
+			dma_buf_sgt_unmap_attachment_unlocked(
+				gem->import_attach, bo->sgt, DMA_TO_DEVICE);
 			dma_buf_detach(gem->import_attach->dmabuf, gem->import_attach);
 		}
 	}
diff --git a/drivers/gpu/drm/virtio/virtgpu_prime.c b/drivers/gpu/drm/virtio/virtgpu_prime.c
index de69590b5076..2faa22875a51 100644
--- a/drivers/gpu/drm/virtio/virtgpu_prime.c
+++ b/drivers/gpu/drm/virtio/virtgpu_prime.c
@@ -170,7 +170,7 @@ int virtgpu_dma_buf_import_sgt(struct virtio_gpu_mem_entry **ents,
 
 	*ents = kvmalloc_objs(struct virtio_gpu_mem_entry, sgt->nents);
 	if (!(*ents)) {
-		dma_buf_unmap_attachment(attach, sgt, DMA_BIDIRECTIONAL);
+		dma_buf_sgt_unmap_attachment(attach, sgt, DMA_BIDIRECTIONAL);
 		return -ENOMEM;
 	}
 
@@ -195,8 +195,8 @@ static void virtgpu_dma_buf_unmap(struct virtio_gpu_object *bo)
 		virtio_gpu_detach_object_fenced(bo);
 
 		if (bo->sgt)
-			dma_buf_unmap_attachment(attach, bo->sgt,
-						 DMA_BIDIRECTIONAL);
+			dma_buf_sgt_unmap_attachment(attach, bo->sgt,
+						     DMA_BIDIRECTIONAL);
 
 		bo->sgt = NULL;
 	}
diff --git a/drivers/gpu/drm/xe/xe_bo.c b/drivers/gpu/drm/xe/xe_bo.c
index 4d93b8926ed6..be7cfd8725fe 100644
--- a/drivers/gpu/drm/xe/xe_bo.c
+++ b/drivers/gpu/drm/xe/xe_bo.c
@@ -759,7 +759,8 @@ static int xe_bo_move_dmabuf(struct ttm_buffer_object *ttm_bo,
 	    ttm_bo->sg) {
 		dma_resv_wait_timeout(ttm_bo->base.resv, DMA_RESV_USAGE_BOOKKEEP,
 				      false, MAX_SCHEDULE_TIMEOUT);
-		dma_buf_unmap_attachment(attach, ttm_bo->sg, DMA_BIDIRECTIONAL);
+		dma_buf_sgt_unmap_attachment(attach, ttm_bo->sg,
+					     DMA_BIDIRECTIONAL);
 		ttm_bo->sg = NULL;
 	}
 
@@ -767,7 +768,8 @@ static int xe_bo_move_dmabuf(struct ttm_buffer_object *ttm_bo,
 		goto out;
 
 	if (ttm_bo->sg) {
-		dma_buf_unmap_attachment(attach, ttm_bo->sg, DMA_BIDIRECTIONAL);
+		dma_buf_sgt_unmap_attachment(attach, ttm_bo->sg,
+					     DMA_BIDIRECTIONAL);
 		ttm_bo->sg = NULL;
 	}
 
@@ -1639,9 +1641,9 @@ int xe_bo_dma_unmap_pinned(struct xe_bo *bo)
 		struct xe_ttm_tt *xe_tt = container_of(tt, typeof(*xe_tt), ttm);
 
 		if (ttm_bo->type == ttm_bo_type_sg && ttm_bo->sg) {
-			dma_buf_unmap_attachment(ttm_bo->base.import_attach,
-						 ttm_bo->sg,
-						 DMA_BIDIRECTIONAL);
+			dma_buf_sgt_unmap_attachment(ttm_bo->base.import_attach,
+						     ttm_bo->sg,
+						     DMA_BIDIRECTIONAL);
 			ttm_bo->sg = NULL;
 			xe_tt->sg = NULL;
 		} else if (xe_tt->sg) {
@@ -1756,8 +1758,8 @@ static void xe_ttm_bo_delete_mem_notify(struct ttm_buffer_object *ttm_bo)
 		struct xe_ttm_tt *xe_tt = container_of(ttm_bo->ttm,
 						       struct xe_ttm_tt, ttm);
 
-		dma_buf_unmap_attachment(ttm_bo->base.import_attach, ttm_bo->sg,
-					 DMA_BIDIRECTIONAL);
+		dma_buf_sgt_unmap_attachment(ttm_bo->base.import_attach,
+					     ttm_bo->sg, DMA_BIDIRECTIONAL);
 		ttm_bo->sg = NULL;
 		xe_tt->sg = NULL;
 	}
diff --git a/drivers/iio/industrialio-buffer.c b/drivers/iio/industrialio-buffer.c
index 619181968ff9..f81154642bcd 100644
--- a/drivers/iio/industrialio-buffer.c
+++ b/drivers/iio/industrialio-buffer.c
@@ -1590,7 +1590,7 @@ static void iio_buffer_dmabuf_release(struct kref *ref)
 	struct iio_buffer *buffer = priv->buffer;
 	struct dma_buf *dmabuf = attach->dmabuf;
 
-	dma_buf_unmap_attachment_unlocked(attach, priv->sgt, priv->dir);
+	dma_buf_sgt_unmap_attachment_unlocked(attach, priv->sgt, priv->dir);
 
 	buffer->access->detach_dmabuf(buffer, priv->block);
 
@@ -1778,7 +1778,7 @@ static int iio_buffer_attach_dmabuf(struct iio_dev_buffer_pair *ib,
 	return 0;
 
 err_dmabuf_unmap_attachment:
-	dma_buf_unmap_attachment(attach, priv->sgt, priv->dir);
+	dma_buf_sgt_unmap_attachment(attach, priv->sgt, priv->dir);
 err_resv_unlock:
 	dma_resv_unlock(dmabuf->resv);
 err_dmabuf_detach:
diff --git a/drivers/infiniband/core/umem_dmabuf.c b/drivers/infiniband/core/umem_dmabuf.c
index dd584f8dcd1c..950db165d9c7 100644
--- a/drivers/infiniband/core/umem_dmabuf.c
+++ b/drivers/infiniband/core/umem_dmabuf.c
@@ -106,8 +106,8 @@ void ib_umem_dmabuf_unmap_pages(struct ib_umem_dmabuf *umem_dmabuf)
 		umem_dmabuf->last_sg_trim = 0;
 	}
 
-	dma_buf_unmap_attachment(umem_dmabuf->attach, umem_dmabuf->sgt,
-				 DMA_BIDIRECTIONAL);
+	dma_buf_sgt_unmap_attachment(umem_dmabuf->attach, umem_dmabuf->sgt,
+				     DMA_BIDIRECTIONAL);
 
 	umem_dmabuf->sgt = NULL;
 }
diff --git a/drivers/media/common/videobuf2/videobuf2-dma-contig.c b/drivers/media/common/videobuf2/videobuf2-dma-contig.c
index 0ce643940898..e13521b5c0e8 100644
--- a/drivers/media/common/videobuf2/videobuf2-dma-contig.c
+++ b/drivers/media/common/videobuf2/videobuf2-dma-contig.c
@@ -717,8 +717,8 @@ static int vb2_dc_map_dmabuf(void *mem_priv)
 	if (contig_size < buf->size) {
 		pr_err("contiguous chunk is too small %lu/%lu\n",
 		       contig_size, buf->size);
-		dma_buf_unmap_attachment_unlocked(buf->db_attach, sgt,
-						  buf->dma_dir);
+		dma_buf_sgt_unmap_attachment_unlocked(buf->db_attach, sgt,
+						      buf->dma_dir);
 		return -EFAULT;
 	}
 
@@ -749,7 +749,8 @@ static void vb2_dc_unmap_dmabuf(void *mem_priv)
 		dma_buf_vunmap_unlocked(buf->db_attach->dmabuf, &map);
 		buf->vaddr = NULL;
 	}
-	dma_buf_unmap_attachment_unlocked(buf->db_attach, sgt, buf->dma_dir);
+	dma_buf_sgt_unmap_attachment_unlocked(buf->db_attach, sgt,
+					      buf->dma_dir);
 
 	buf->dma_addr = 0;
 	buf->dma_sgt = NULL;
diff --git a/drivers/media/common/videobuf2/videobuf2-dma-sg.c b/drivers/media/common/videobuf2/videobuf2-dma-sg.c
index 17191373c69c..59e346a5d48b 100644
--- a/drivers/media/common/videobuf2/videobuf2-dma-sg.c
+++ b/drivers/media/common/videobuf2/videobuf2-dma-sg.c
@@ -601,7 +601,8 @@ static void vb2_dma_sg_unmap_dmabuf(void *mem_priv)
 		dma_buf_vunmap_unlocked(buf->db_attach->dmabuf, &map);
 		buf->vaddr = NULL;
 	}
-	dma_buf_unmap_attachment_unlocked(buf->db_attach, sgt, buf->dma_dir);
+	dma_buf_sgt_unmap_attachment_unlocked(buf->db_attach, sgt,
+					      buf->dma_dir);
 
 	buf->dma_sgt = NULL;
 }
diff --git a/drivers/media/platform/nvidia/tegra-vde/dmabuf-cache.c b/drivers/media/platform/nvidia/tegra-vde/dmabuf-cache.c
index 8f3443fa0eb5..55d58a4dbbe2 100644
--- a/drivers/media/platform/nvidia/tegra-vde/dmabuf-cache.c
+++ b/drivers/media/platform/nvidia/tegra-vde/dmabuf-cache.c
@@ -38,7 +38,8 @@ static void tegra_vde_release_entry(struct tegra_vde_cache_entry *entry)
 	if (entry->vde->domain)
 		tegra_vde_iommu_unmap(entry->vde, entry->iova);
 
-	dma_buf_unmap_attachment_unlocked(entry->a, entry->sgt, entry->dma_dir);
+	dma_buf_sgt_unmap_attachment_unlocked(entry->a, entry->sgt,
+					      entry->dma_dir);
 	dma_buf_detach(dmabuf, entry->a);
 	dma_buf_put(dmabuf);
 
@@ -152,7 +153,7 @@ int tegra_vde_dmabuf_cache_map(struct tegra_vde *vde,
 err_free:
 	kfree(entry);
 err_unmap:
-	dma_buf_unmap_attachment_unlocked(attachment, sgt, dma_dir);
+	dma_buf_sgt_unmap_attachment_unlocked(attachment, sgt, dma_dir);
 err_detach:
 	dma_buf_detach(dmabuf, attachment);
 err_unlock:
diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c
index fce849417eb7..375ce39c78c9 100644
--- a/drivers/misc/fastrpc.c
+++ b/drivers/misc/fastrpc.c
@@ -400,8 +400,8 @@ static void fastrpc_free_map(struct kref *ref)
 				return;
 			}
 		}
-		dma_buf_unmap_attachment_unlocked(map->attach, map->table,
-						  DMA_BIDIRECTIONAL);
+		dma_buf_sgt_unmap_attachment_unlocked(map->attach, map->table,
+						      DMA_BIDIRECTIONAL);
 		dma_buf_detach(map->buf, map->attach);
 		dma_buf_put(map->buf);
 	}
diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c
index fe3c43ba72c6..4016edfa4c02 100644
--- a/drivers/usb/gadget/function/f_fs.c
+++ b/drivers/usb/gadget/function/f_fs.c
@@ -1366,7 +1366,7 @@ static void ffs_dmabuf_release(struct kref *ref)
 	struct dma_buf *dmabuf = attach->dmabuf;
 
 	pr_vdebug("FFS DMABUF release\n");
-	dma_buf_unmap_attachment_unlocked(attach, priv->sgt, priv->dir);
+	dma_buf_sgt_unmap_attachment_unlocked(attach, priv->sgt, priv->dir);
 
 	dma_buf_detach(attach->dmabuf, attach);
 	dma_buf_put(dmabuf);
diff --git a/drivers/xen/gntdev-dmabuf.c b/drivers/xen/gntdev-dmabuf.c
index 3bb05596920e..cd851eb04a69 100644
--- a/drivers/xen/gntdev-dmabuf.c
+++ b/drivers/xen/gntdev-dmabuf.c
@@ -651,7 +651,7 @@ dmabuf_imp_to_refs(struct gntdev_dmabuf_priv *priv, struct device *dev,
 fail_end_access:
 	dmabuf_imp_end_foreign_access(gntdev_dmabuf->u.imp.refs, count);
 fail_unmap:
-	dma_buf_unmap_attachment_unlocked(attach, sgt, DMA_BIDIRECTIONAL);
+	dma_buf_sgt_unmap_attachment_unlocked(attach, sgt, DMA_BIDIRECTIONAL);
 fail_detach:
 	dma_buf_detach(dma_buf, attach);
 fail_free_obj:
@@ -701,8 +701,8 @@ static int dmabuf_imp_release(struct gntdev_dmabuf_priv *priv, u32 fd)
 	attach = gntdev_dmabuf->u.imp.attach;
 
 	if (gntdev_dmabuf->u.imp.sgt)
-		dma_buf_unmap_attachment_unlocked(attach, gntdev_dmabuf->u.imp.sgt,
-						  DMA_BIDIRECTIONAL);
+		dma_buf_sgt_unmap_attachment_unlocked(
+			attach, gntdev_dmabuf->u.imp.sgt, DMA_BIDIRECTIONAL);
 	dma_buf = attach->dmabuf;
 	dma_buf_detach(attach->dmabuf, attach);
 	dma_buf_put(dma_buf);
diff --git a/include/linux/dma-buf-mapping.h b/include/linux/dma-buf-mapping.h
index 02d79d5615b5..ffb7503781a8 100644
--- a/include/linux/dma-buf-mapping.h
+++ b/include/linux/dma-buf-mapping.h
@@ -172,7 +172,7 @@ void dma_buf_sgt_type_unmap(struct dma_buf_attachment *attach,
  * When this type is matched the map/unmap functions are:
  *
  *  dma_buf_sgt_map_attachment()
- *  dma_buf_unmap_attachment()
+ *  dma_buf_sgt_unmap_attachment()
  *
  * The struct sg_table returned by those functions has only the DMA portions
  * available. The caller must not try to use the struct page * information.
@@ -264,7 +264,7 @@ struct dma_buf_mapping_sgt_exp_ops {
 	/**
 	 * @unmap_dma_buf:
 	 *
-	 * This is called by dma_buf_unmap_attachment() and should unmap and
+	 * This is called by dma_buf_sgt_unmap_attachment() and should unmap and
 	 * release the &sg_table allocated in @map_dma_buf, and it is mandatory.
 	 * For static dma_buf handling this might also unpin the backing
 	 * storage if this is the last mapping of the DMA buffer.
diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h
index ee6c97a5cecd..b264e1c4a9df 100644
--- a/include/linux/dma-buf.h
+++ b/include/linux/dma-buf.h
@@ -516,7 +516,7 @@ struct dma_buf_attach_ops {
  * An attachment is created by calling dma_buf_attach(), and released again by
  * calling dma_buf_detach(). The DMA mapping itself needed to initiate a
  * transfer is created by dma_buf_sgt_map_attachment() and freed again by calling
- * dma_buf_unmap_attachment().
+ * dma_buf_sgt_unmap_attachment().
  */
 struct dma_buf_attachment {
 	struct dma_buf *dmabuf;
@@ -616,8 +616,8 @@ void dma_buf_put(struct dma_buf *dmabuf);
 
 struct sg_table *dma_buf_sgt_map_attachment(struct dma_buf_attachment *,
 					    enum dma_data_direction);
-void dma_buf_unmap_attachment(struct dma_buf_attachment *, struct sg_table *,
-				enum dma_data_direction);
+void dma_buf_sgt_unmap_attachment(struct dma_buf_attachment *,
+				  struct sg_table *, enum dma_data_direction);
 void dma_buf_invalidate_mappings(struct dma_buf *dma_buf);
 bool dma_buf_attach_revocable(struct dma_buf_attachment *attach);
 int dma_buf_begin_cpu_access(struct dma_buf *dma_buf,
@@ -627,9 +627,9 @@ int dma_buf_end_cpu_access(struct dma_buf *dma_buf,
 struct sg_table *
 dma_buf_sgt_map_attachment_unlocked(struct dma_buf_attachment *attach,
 				    enum dma_data_direction direction);
-void dma_buf_unmap_attachment_unlocked(struct dma_buf_attachment *attach,
-				       struct sg_table *sg_table,
-				       enum dma_data_direction direction);
+void dma_buf_sgt_unmap_attachment_unlocked(struct dma_buf_attachment *attach,
+					   struct sg_table *sg_table,
+					   enum dma_data_direction direction);
 
 int dma_buf_mmap(struct dma_buf *, struct vm_area_struct *,
 		 unsigned long);
diff --git a/io_uring/zcrx.c b/io_uring/zcrx.c
index 3f8be77a50dc..67f74ce4f096 100644
--- a/io_uring/zcrx.c
+++ b/io_uring/zcrx.c
@@ -132,8 +132,8 @@ static void io_unmap_dmabuf(struct io_zcrx_mem *mem)
 	if (!IS_ENABLED(CONFIG_DMA_SHARED_BUFFER))
 		return;
 	if (mem->sgt)
-		dma_buf_unmap_attachment_unlocked(mem->attach, mem->sgt,
-						  DMA_FROM_DEVICE);
+		dma_buf_sgt_unmap_attachment_unlocked(mem->attach, mem->sgt,
+						      DMA_FROM_DEVICE);
 	if (mem->attach)
 		dma_buf_detach(mem->dmabuf, mem->attach);
 	mem->sgt = NULL;
diff --git a/net/core/devmem.c b/net/core/devmem.c
index 86b3c54933bb..f30fa375c9ab 100644
--- a/net/core/devmem.c
+++ b/net/core/devmem.c
@@ -74,8 +74,8 @@ void __net_devmem_dmabuf_binding_free(struct work_struct *wq)
 		  size, avail))
 		gen_pool_destroy(binding->chunk_pool);
 
-	dma_buf_unmap_attachment_unlocked(binding->attachment, binding->sgt,
-					  binding->direction);
+	dma_buf_sgt_unmap_attachment_unlocked(binding->attachment, binding->sgt,
+					      binding->direction);
 	dma_buf_detach(binding->dmabuf, binding->attachment);
 	dma_buf_put(binding->dmabuf);
 	xa_destroy(&binding->bound_rxqs);
@@ -343,8 +343,8 @@ net_devmem_bind_dmabuf(struct net_device *dev, void *vdev,
 err_tx_vec:
 	kvfree(binding->tx_vec);
 err_unmap:
-	dma_buf_unmap_attachment_unlocked(binding->attachment, binding->sgt,
-					  direction);
+	dma_buf_sgt_unmap_attachment_unlocked(binding->attachment, binding->sgt,
+					      direction);
 err_detach:
 	dma_buf_detach(dmabuf, binding->attachment);
 err_exit_ref:
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 71+ messages in thread

* [PATCH 23/26] treewide: Rename dma_buf_attach() to dma_buf_sgt_attach()
  2026-10-26  5:35 [PATCH 00/26] DMA-buf mapping types Alistair Popple
                   ` (21 preceding siblings ...)
  2026-10-26  5:36 ` [PATCH 22/26] treewide: Rename dma_buf_unmap_attachment(_unlocked) to dma_buf_sgt_* Alistair Popple
@ 2026-10-26  5:36 ` Alistair Popple
  2026-10-26 10:01   ` sashiko-bot
                     ` (2 more replies)
  2026-10-26  5:36 ` [PATCH 24/26] treewide: Rename dma_buf_dynamic_attach() to dma_buf_sgt_dynamic_attach() Alistair Popple
                   ` (2 subsequent siblings)
  25 siblings, 3 replies; 71+ messages in thread
From: Alistair Popple @ 2026-10-26  5:36 UTC (permalink / raw)
  To: dri-devel, christian.koenig, sumit.semwal, jgg
  Cc: Alistair Popple, Thomas Hellström, Simona Vetter,
	Matthew Brost, Vivek Kasireddy, Dongwon Kim, Leon Romanovsky,
	Kevin Tian, Xu Yilun, Karl Mehltretter, Baolu Lu, Felix Kuehling,
	Alex Deucher, intel-xe, amd-gfx, linux-media, linaro-mm-sig,
	linux-rdma, iommu, Alexey Kardashevskiy, zhipingz, treding,
	jhubbard

From: Jason Gunthorpe <jgg@nvidia.com>

This attach function always creates a SGT mapping type importer.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 Documentation/gpu/todo.rst                         |  2 +-
 drivers/accel/amdxdna/amdxdna_gem.c                |  2 +-
 drivers/accel/ivpu/ivpu_gem.c                      |  2 +-
 drivers/accel/qaic/qaic_data.c                     |  2 +-
 drivers/dma-buf/dma-buf.c                          | 14 +++++++-------
 drivers/gpu/drm/armada/armada_gem.c                |  2 +-
 drivers/gpu/drm/drm_gem_shmem_helper.c             |  2 +-
 drivers/gpu/drm/drm_prime.c                        |  2 +-
 drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c         |  2 +-
 .../gpu/drm/i915/gem/selftests/i915_gem_dmabuf.c   |  2 +-
 drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c          |  2 +-
 drivers/gpu/drm/tegra/gem.c                        |  4 ++--
 drivers/iio/industrialio-buffer.c                  |  2 +-
 .../media/common/videobuf2/videobuf2-dma-contig.c  |  2 +-
 drivers/media/common/videobuf2/videobuf2-dma-sg.c  |  2 +-
 .../media/platform/nvidia/tegra-vde/dmabuf-cache.c |  2 +-
 drivers/misc/fastrpc.c                             |  2 +-
 drivers/usb/gadget/function/f_fs.c                 |  2 +-
 drivers/xen/gntdev-dmabuf.c                        |  2 +-
 include/linux/dma-buf.h                            | 10 +++++-----
 io_uring/zcrx.c                                    |  2 +-
 net/core/devmem.c                                  |  2 +-
 22 files changed, 33 insertions(+), 33 deletions(-)

diff --git a/Documentation/gpu/todo.rst b/Documentation/gpu/todo.rst
index 14cf37590fc7..be0397c197f1 100644
--- a/Documentation/gpu/todo.rst
+++ b/Documentation/gpu/todo.rst
@@ -633,7 +633,7 @@ Remove automatic page mapping from dma-buf importing
 
 When importing dma-bufs, the dma-buf and PRIME frameworks automatically map
 imported pages into the importer's DMA area. drm_gem_prime_fd_to_handle() and
-drm_gem_prime_handle_to_fd() require that importers call dma_buf_attach()
+drm_gem_prime_handle_to_fd() require that importers call dma_buf_sgt_attach()
 even if they never do actual device DMA, but only CPU access through
 dma_buf_vmap(). This is a problem for USB devices, which do not support DMA
 operations.
diff --git a/drivers/accel/amdxdna/amdxdna_gem.c b/drivers/accel/amdxdna/amdxdna_gem.c
index a7e759bb0460..2b2f1e9fb9ec 100644
--- a/drivers/accel/amdxdna/amdxdna_gem.c
+++ b/drivers/accel/amdxdna/amdxdna_gem.c
@@ -893,7 +893,7 @@ amdxdna_gem_prime_import(struct drm_device *dev, struct dma_buf *dma_buf)
 
 	get_dma_buf(dma_buf);
 
-	attach = dma_buf_attach(dma_buf, dev->dev);
+	attach = dma_buf_sgt_attach(dma_buf, dev->dev);
 	if (IS_ERR(attach)) {
 		ret = PTR_ERR(attach);
 		goto put_buf;
diff --git a/drivers/accel/ivpu/ivpu_gem.c b/drivers/accel/ivpu/ivpu_gem.c
index 8d6ed95ccc7c..d1c99b974a34 100644
--- a/drivers/accel/ivpu/ivpu_gem.c
+++ b/drivers/accel/ivpu/ivpu_gem.c
@@ -219,7 +219,7 @@ struct drm_gem_object *ivpu_gem_prime_import(struct drm_device *dev,
 	struct ivpu_bo *bo;
 	int ret;
 
-	attach = dma_buf_attach(dma_buf, attach_dev);
+	attach = dma_buf_sgt_attach(dma_buf, attach_dev);
 	if (IS_ERR(attach))
 		return ERR_CAST(attach);
 
diff --git a/drivers/accel/qaic/qaic_data.c b/drivers/accel/qaic/qaic_data.c
index 92d49448df72..88331028b7bf 100644
--- a/drivers/accel/qaic/qaic_data.c
+++ b/drivers/accel/qaic/qaic_data.c
@@ -850,7 +850,7 @@ struct drm_gem_object *qaic_gem_prime_import(struct drm_device *dev, struct dma_
 	obj = &bo->base;
 	get_dma_buf(dma_buf);
 
-	attach = dma_buf_attach(dma_buf, dev->dev);
+	attach = dma_buf_sgt_attach(dma_buf, dev->dev);
 	if (IS_ERR(attach)) {
 		ret = PTR_ERR(attach);
 		goto attach_fail;
diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c
index 12604c60122e..06bc25eff079 100644
--- a/drivers/dma-buf/dma-buf.c
+++ b/drivers/dma-buf/dma-buf.c
@@ -671,7 +671,7 @@ static struct file *dma_buf_getfile(size_t size, int flags)
  * 2. Userspace passes this file-descriptors to all drivers it wants this buffer
  *    to share with: First the file descriptor is converted to a &dma_buf using
  *    dma_buf_get(). Then the buffer is attached to the device using
- *    dma_buf_attach().
+ *    dma_buf_sgt_attach().
  *
  *    Up to this stage the exporter is still free to migrate or reallocate the
  *    backing storage.
@@ -966,7 +966,7 @@ dma_buf_pin_on_map(struct dma_buf_attachment *attach)
  * 2. Importers must not hold the dma-buf reservation lock when calling these
  *    functions:
  *
- *     - dma_buf_attach()
+ *     - dma_buf_sgt_attach()
  *     - dma_buf_dynamic_attach()
  *     - dma_buf_detach()
  *     - dma_buf_export()
@@ -1100,15 +1100,15 @@ struct dma_buf_attachment *dma_buf_mapping_attach(
 EXPORT_SYMBOL_NS_GPL(dma_buf_mapping_attach, "DMA_BUF");
 
 /**
- * dma_buf_attach - Wrapper for dma_buf_mapping_attach
+ * dma_buf_sgt_attach - Wrapper for dma_buf_mapping_attach
  * @dmabuf:	[in]	buffer to attach device to.
  * @dev:	[in]	device to be attached.
  *
  * Wrapper to call dma_buf_mapping_attach() for drivers which still use a static
  * mapping.
  */
-struct dma_buf_attachment *dma_buf_attach(struct dma_buf *dmabuf,
-					  struct device *dev)
+struct dma_buf_attachment *dma_buf_sgt_attach(struct dma_buf *dmabuf,
+					      struct device *dev)
 {
 	struct dma_buf_mapping_match sgt_match[] = {
 		DMA_BUF_IMAPPING_SGT(dev, DMA_SGT_NO_P2P),
@@ -1117,7 +1117,7 @@ struct dma_buf_attachment *dma_buf_attach(struct dma_buf *dmabuf,
 	return dma_buf_mapping_attach(dmabuf, sgt_match, ARRAY_SIZE(sgt_match),
 				      NULL, NULL);
 }
-EXPORT_SYMBOL_NS_GPL(dma_buf_attach, "DMA_BUF");
+EXPORT_SYMBOL_NS_GPL(dma_buf_sgt_attach, "DMA_BUF");
 
 /**
  * dma_buf_dynamic_attach - Add the device to dma_buf's attachments list
@@ -1149,7 +1149,7 @@ EXPORT_SYMBOL_NS_GPL(dma_buf_dynamic_attach, "DMA_BUF");
  * @dmabuf:	[in]	buffer to detach from.
  * @attach:	[in]	attachment to be detached; is free'd after this call.
  *
- * Clean up a device attachment obtained by calling dma_buf_attach().
+ * Clean up a device attachment obtained by calling dma_buf_sgt_attach().
  *
  * Optionally this calls &dma_buf_ops.detach for device-specific detach.
  */
diff --git a/drivers/gpu/drm/armada/armada_gem.c b/drivers/gpu/drm/armada/armada_gem.c
index 72c7cd2b3fb9..438f33304eab 100644
--- a/drivers/gpu/drm/armada/armada_gem.c
+++ b/drivers/gpu/drm/armada/armada_gem.c
@@ -518,7 +518,7 @@ armada_gem_prime_import(struct drm_device *dev, struct dma_buf *buf)
 		}
 	}
 
-	attach = dma_buf_attach(buf, dev->dev);
+	attach = dma_buf_sgt_attach(buf, dev->dev);
 	if (IS_ERR(attach))
 		return ERR_CAST(attach);
 
diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c
index d654a22a30de..9e937af2ee73 100644
--- a/drivers/gpu/drm/drm_gem_shmem_helper.c
+++ b/drivers/gpu/drm/drm_gem_shmem_helper.c
@@ -964,7 +964,7 @@ struct drm_gem_object *drm_gem_shmem_prime_import_no_map(struct drm_device *dev,
 		return obj;
 	}
 
-	attach = dma_buf_attach(dma_buf, dev->dev);
+	attach = dma_buf_sgt_attach(dma_buf, dev->dev);
 	if (IS_ERR(attach))
 		return ERR_CAST(attach);
 
diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c
index 3ffbe3d28929..3084e8c28e53 100644
--- a/drivers/gpu/drm/drm_prime.c
+++ b/drivers/gpu/drm/drm_prime.c
@@ -999,7 +999,7 @@ struct drm_gem_object *drm_gem_prime_import_dev(struct drm_device *dev,
 	if (!dev->driver->gem_prime_import_sg_table)
 		return ERR_PTR(-EINVAL);
 
-	attach = dma_buf_attach(dma_buf, attach_dev);
+	attach = dma_buf_sgt_attach(dma_buf, attach_dev);
 	if (IS_ERR(attach))
 		return ERR_CAST(attach);
 
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
index 7f939c281308..9865a7a9ad8f 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
@@ -306,7 +306,7 @@ struct drm_gem_object *i915_gem_prime_import(struct drm_device *dev,
 		return ERR_PTR(-E2BIG);
 
 	/* need to attach */
-	attach = dma_buf_attach(dma_buf, dev->dev);
+	attach = dma_buf_sgt_attach(dma_buf, dev->dev);
 	if (IS_ERR(attach))
 		return ERR_CAST(attach);
 
diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_dmabuf.c b/drivers/gpu/drm/i915/gem/selftests/i915_gem_dmabuf.c
index 6b6d235fd3e9..3c193e6d9d11 100644
--- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_dmabuf.c
+++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_dmabuf.c
@@ -287,7 +287,7 @@ static int igt_dmabuf_import_same_driver(struct drm_i915_private *i915,
 		goto out_import;
 
 	/* Now try a fake an importer */
-	import_attach = dma_buf_attach(dmabuf, obj->base.dev->dev);
+	import_attach = dma_buf_sgt_attach(dmabuf, obj->base.dev->dev);
 	if (IS_ERR(import_attach)) {
 		err = PTR_ERR(import_attach);
 		goto out_import;
diff --git a/drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c b/drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c
index c549b94b2e8a..ca0962a99509 100644
--- a/drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c
+++ b/drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c
@@ -115,7 +115,7 @@ struct drm_gem_object *omap_gem_prime_import(struct drm_device *dev,
 		}
 	}
 
-	attach = dma_buf_attach(dma_buf, dev->dev);
+	attach = dma_buf_sgt_attach(dma_buf, dev->dev);
 	if (IS_ERR(attach))
 		return ERR_CAST(attach);
 
diff --git a/drivers/gpu/drm/tegra/gem.c b/drivers/gpu/drm/tegra/gem.c
index f06826fe8366..803409824711 100644
--- a/drivers/gpu/drm/tegra/gem.c
+++ b/drivers/gpu/drm/tegra/gem.c
@@ -81,7 +81,7 @@ static struct host1x_bo_mapping *tegra_bo_pin(struct device *dev, struct host1x_
 	if (obj->dma_buf) {
 		struct dma_buf *buf = obj->dma_buf;
 
-		map->attach = dma_buf_attach(buf, dev);
+		map->attach = dma_buf_sgt_attach(buf, dev);
 		if (IS_ERR(map->attach)) {
 			err = PTR_ERR(map->attach);
 			goto free;
@@ -475,7 +475,7 @@ static struct tegra_bo *tegra_bo_import(struct drm_device *drm,
 	 * domain, map it first to the DRM device to get an sgt.
 	 */
 	if (tegra->domain) {
-		attach = dma_buf_attach(buf, drm->dev);
+		attach = dma_buf_sgt_attach(buf, drm->dev);
 		if (IS_ERR(attach)) {
 			err = PTR_ERR(attach);
 			goto free;
diff --git a/drivers/iio/industrialio-buffer.c b/drivers/iio/industrialio-buffer.c
index f81154642bcd..abffbcc76c4c 100644
--- a/drivers/iio/industrialio-buffer.c
+++ b/drivers/iio/industrialio-buffer.c
@@ -1717,7 +1717,7 @@ static int iio_buffer_attach_dmabuf(struct iio_dev_buffer_pair *ib,
 		goto err_free_priv;
 	}
 
-	attach = dma_buf_attach(dmabuf, dma_dev);
+	attach = dma_buf_sgt_attach(dmabuf, dma_dev);
 	if (IS_ERR(attach)) {
 		err = PTR_ERR(attach);
 		goto err_dmabuf_put;
diff --git a/drivers/media/common/videobuf2/videobuf2-dma-contig.c b/drivers/media/common/videobuf2/videobuf2-dma-contig.c
index e13521b5c0e8..c7fa86cba8ad 100644
--- a/drivers/media/common/videobuf2/videobuf2-dma-contig.c
+++ b/drivers/media/common/videobuf2/videobuf2-dma-contig.c
@@ -789,7 +789,7 @@ static void *vb2_dc_attach_dmabuf(struct vb2_buffer *vb, struct device *dev,
 	buf->vb = vb;
 
 	/* create attachment for the dmabuf with the user device */
-	dba = dma_buf_attach(dbuf, buf->dev);
+	dba = dma_buf_sgt_attach(dbuf, buf->dev);
 	if (IS_ERR(dba)) {
 		pr_err("failed to attach dmabuf\n");
 		kfree(buf);
diff --git a/drivers/media/common/videobuf2/videobuf2-dma-sg.c b/drivers/media/common/videobuf2/videobuf2-dma-sg.c
index 59e346a5d48b..4c93b7f58e1f 100644
--- a/drivers/media/common/videobuf2/videobuf2-dma-sg.c
+++ b/drivers/media/common/videobuf2/videobuf2-dma-sg.c
@@ -638,7 +638,7 @@ static void *vb2_dma_sg_attach_dmabuf(struct vb2_buffer *vb, struct device *dev,
 
 	buf->dev = dev;
 	/* create attachment for the dmabuf with the user device */
-	dba = dma_buf_attach(dbuf, buf->dev);
+	dba = dma_buf_sgt_attach(dbuf, buf->dev);
 	if (IS_ERR(dba)) {
 		pr_err("failed to attach dmabuf\n");
 		kfree(buf);
diff --git a/drivers/media/platform/nvidia/tegra-vde/dmabuf-cache.c b/drivers/media/platform/nvidia/tegra-vde/dmabuf-cache.c
index 55d58a4dbbe2..d80282ebe4b4 100644
--- a/drivers/media/platform/nvidia/tegra-vde/dmabuf-cache.c
+++ b/drivers/media/platform/nvidia/tegra-vde/dmabuf-cache.c
@@ -96,7 +96,7 @@ int tegra_vde_dmabuf_cache_map(struct tegra_vde *vde,
 		goto ref;
 	}
 
-	attachment = dma_buf_attach(dmabuf, dev);
+	attachment = dma_buf_sgt_attach(dmabuf, dev);
 	if (IS_ERR(attachment)) {
 		dev_err(dev, "Failed to attach dmabuf\n");
 		err = PTR_ERR(attachment);
diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c
index 375ce39c78c9..24ae1038b634 100644
--- a/drivers/misc/fastrpc.c
+++ b/drivers/misc/fastrpc.c
@@ -904,7 +904,7 @@ static int fastrpc_map_attach(struct fastrpc_user *fl, int fd,
 		goto get_err;
 	}
 
-	map->attach = dma_buf_attach(map->buf, sess->dev);
+	map->attach = dma_buf_sgt_attach(map->buf, sess->dev);
 	if (IS_ERR(map->attach)) {
 		dev_err(sess->dev, "Failed to attach dmabuf\n");
 		err = PTR_ERR(map->attach);
diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c
index 4016edfa4c02..bfa24bcfe84c 100644
--- a/drivers/usb/gadget/function/f_fs.c
+++ b/drivers/usb/gadget/function/f_fs.c
@@ -1549,7 +1549,7 @@ static int ffs_dmabuf_attach(struct file *file, int fd)
 	if (IS_ERR(dmabuf))
 		return PTR_ERR(dmabuf);
 
-	attach = dma_buf_attach(dmabuf, gadget->dev.parent);
+	attach = dma_buf_sgt_attach(dmabuf, gadget->dev.parent);
 	if (IS_ERR(attach)) {
 		err = PTR_ERR(attach);
 		goto err_dmabuf_put;
diff --git a/drivers/xen/gntdev-dmabuf.c b/drivers/xen/gntdev-dmabuf.c
index cd851eb04a69..e7ffb546e717 100644
--- a/drivers/xen/gntdev-dmabuf.c
+++ b/drivers/xen/gntdev-dmabuf.c
@@ -580,7 +580,7 @@ dmabuf_imp_to_refs(struct gntdev_dmabuf_priv *priv, struct device *dev,
 	gntdev_dmabuf->priv = priv;
 	gntdev_dmabuf->fd = fd;
 
-	attach = dma_buf_attach(dma_buf, dev);
+	attach = dma_buf_sgt_attach(dma_buf, dev);
 	if (IS_ERR(attach)) {
 		ret = ERR_CAST(attach);
 		goto fail_free_obj;
diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h
index b264e1c4a9df..208752eb93d9 100644
--- a/include/linux/dma-buf.h
+++ b/include/linux/dma-buf.h
@@ -77,7 +77,7 @@ struct dma_buf_ops {
 	/**
 	 * @attach:
 	 *
-	 * This is called from dma_buf_attach() to make sure that a given
+	 * This is called from dma_buf_sgt_attach() to make sure that a given
 	 * &dma_buf_attachment.dev can access the provided &dma_buf. Exporters
 	 * which support buffer objects in special locations like VRAM or
 	 * device-specific carveout areas should check whether the buffer could
@@ -125,7 +125,7 @@ struct dma_buf_ops {
 	 * exclusive with @cache_sgt_mapping.
 	 *
 	 * This is called automatically for non-dynamic importers from
-	 * dma_buf_attach().
+	 * dma_buf_sgt_attach().
 	 *
 	 * Note that similar to non-dynamic exporters in their @map_dma_buf
 	 * callback the driver must guarantee that the memory is available for
@@ -513,7 +513,7 @@ struct dma_buf_attach_ops {
  * and its user device(s). The list contains one attachment struct per device
  * attached to the buffer.
  *
- * An attachment is created by calling dma_buf_attach(), and released again by
+ * An attachment is created by calling dma_buf_sgt_attach(), and released again by
  * calling dma_buf_detach(). The DMA mapping itself needed to initiate a
  * transfer is created by dma_buf_sgt_map_attachment() and freed again by calling
  * dma_buf_sgt_unmap_attachment().
@@ -591,8 +591,8 @@ static inline bool dma_buf_is_dynamic(struct dma_buf *dmabuf)
 	return !!dmabuf->ops->pin;
 }
 
-struct dma_buf_attachment *dma_buf_attach(struct dma_buf *dmabuf,
-					  struct device *dev);
+struct dma_buf_attachment *dma_buf_sgt_attach(struct dma_buf *dmabuf,
+					      struct device *dev);
 struct dma_buf_attachment *
 dma_buf_dynamic_attach(struct dma_buf *dmabuf, struct device *dev,
 		       const struct dma_buf_attach_ops *importer_ops,
diff --git a/io_uring/zcrx.c b/io_uring/zcrx.c
index 67f74ce4f096..2cbf65b29f89 100644
--- a/io_uring/zcrx.c
+++ b/io_uring/zcrx.c
@@ -175,7 +175,7 @@ static int io_import_dmabuf(struct io_zcrx_ifq *ifq,
 		goto err;
 	}
 
-	mem->attach = dma_buf_attach(mem->dmabuf, ifq->dev);
+	mem->attach = dma_buf_sgt_attach(mem->dmabuf, ifq->dev);
 	if (IS_ERR(mem->attach)) {
 		ret = PTR_ERR(mem->attach);
 		mem->attach = NULL;
diff --git a/net/core/devmem.c b/net/core/devmem.c
index f30fa375c9ab..d7c08da306cf 100644
--- a/net/core/devmem.c
+++ b/net/core/devmem.c
@@ -234,7 +234,7 @@ net_devmem_bind_dmabuf(struct net_device *dev, void *vdev,
 	binding->dmabuf = dmabuf;
 	binding->direction = direction;
 
-	binding->attachment = dma_buf_attach(binding->dmabuf, dma_dev);
+	binding->attachment = dma_buf_sgt_attach(binding->dmabuf, dma_dev);
 	if (IS_ERR(binding->attachment)) {
 		err = PTR_ERR(binding->attachment);
 		NL_SET_ERR_MSG(extack, "Failed to bind dmabuf to device");
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 71+ messages in thread

* [PATCH 24/26] treewide: Rename dma_buf_dynamic_attach() to dma_buf_sgt_dynamic_attach()
  2026-10-26  5:35 [PATCH 00/26] DMA-buf mapping types Alistair Popple
                   ` (22 preceding siblings ...)
  2026-10-26  5:36 ` [PATCH 23/26] treewide: Rename dma_buf_attach() to dma_buf_sgt_attach() Alistair Popple
@ 2026-10-26  5:36 ` Alistair Popple
  2026-10-26 10:13   ` sashiko-bot
  2026-10-26  5:36 ` [PATCH 25/26] dma-buf: Add kunit tests for mapping type Alistair Popple
  2026-10-26  5:36 ` [PATCH 26/26] dma-buf: Add kunit tests for mapping type selection Alistair Popple
  25 siblings, 1 reply; 71+ messages in thread
From: Alistair Popple @ 2026-10-26  5:36 UTC (permalink / raw)
  To: dri-devel, christian.koenig, sumit.semwal, jgg
  Cc: Alistair Popple, Thomas Hellström, Simona Vetter,
	Matthew Brost, Vivek Kasireddy, Dongwon Kim, Leon Romanovsky,
	Kevin Tian, Xu Yilun, Karl Mehltretter, Baolu Lu, Felix Kuehling,
	Alex Deucher, intel-xe, amd-gfx, linux-media, linaro-mm-sig,
	linux-rdma, iommu, Alexey Kardashevskiy, zhipingz, treding,
	jhubbard

From: Jason Gunthorpe <jgg@nvidia.com>

This attach function always creates a SGT mapping type importer.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/dma-buf/dma-buf.c                   | 14 +++++++-------
 drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c |  4 ++--
 drivers/gpu/drm/virtio/virtgpu_prime.c      |  4 ++--
 drivers/gpu/drm/xe/xe_dma_buf.c             |  2 +-
 drivers/infiniband/core/umem_dmabuf.c       |  7 ++-----
 drivers/iommu/iommufd/pages.c               |  5 +++--
 include/linux/dma-buf.h                     |  6 +++---
 7 files changed, 20 insertions(+), 22 deletions(-)

diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c
index 06bc25eff079..40301939331f 100644
--- a/drivers/dma-buf/dma-buf.c
+++ b/drivers/dma-buf/dma-buf.c
@@ -967,7 +967,7 @@ dma_buf_pin_on_map(struct dma_buf_attachment *attach)
  *    functions:
  *
  *     - dma_buf_sgt_attach()
- *     - dma_buf_dynamic_attach()
+ *     - dma_buf_sgt_dynamic_attach()
  *     - dma_buf_detach()
  *     - dma_buf_export()
  *     - dma_buf_fd()
@@ -1120,7 +1120,7 @@ struct dma_buf_attachment *dma_buf_sgt_attach(struct dma_buf *dmabuf,
 EXPORT_SYMBOL_NS_GPL(dma_buf_sgt_attach, "DMA_BUF");
 
 /**
- * dma_buf_dynamic_attach - Add the device to dma_buf's attachments list
+ * dma_buf_sgt_dynamic_attach - Add the device to dma_buf's attachments list
  * @dmabuf:		[in]	buffer to attach device to.
  * @dev:		[in]	device to be attached.
  * @importer_ops:	[in]	importer operations for the attachment
@@ -1129,9 +1129,9 @@ EXPORT_SYMBOL_NS_GPL(dma_buf_sgt_attach, "DMA_BUF");
  * Wrapper to call dma_buf_mapping_attach() for drivers which only support SGT.
  */
 struct dma_buf_attachment *
-dma_buf_dynamic_attach(struct dma_buf *dmabuf, struct device *dev,
-		       const struct dma_buf_attach_ops *importer_ops,
-		       void *importer_priv)
+dma_buf_sgt_dynamic_attach(struct dma_buf *dmabuf, struct device *dev,
+			   const struct dma_buf_attach_ops *importer_ops,
+			   void *importer_priv)
 {
 	struct dma_buf_mapping_match sgt_match[] = {
 		DMA_BUF_IMAPPING_SGT(dev, importer_ops->allow_peer2peer ?
@@ -1142,7 +1142,7 @@ dma_buf_dynamic_attach(struct dma_buf *dmabuf, struct device *dev,
 	return dma_buf_mapping_attach(dmabuf, sgt_match, ARRAY_SIZE(sgt_match),
 				      importer_ops, importer_priv);
 }
-EXPORT_SYMBOL_NS_GPL(dma_buf_dynamic_attach, "DMA_BUF");
+EXPORT_SYMBOL_NS_GPL(dma_buf_sgt_dynamic_attach, "DMA_BUF");
 
 /**
  * dma_buf_detach - Remove the given attachment from dmabuf's attachments list
@@ -1177,7 +1177,7 @@ EXPORT_SYMBOL_NS_GPL(dma_buf_detach, "DMA_BUF");
  * dma_buf_pin - Lock down the DMA-buf
  * @attach:	[in]	attachment which should be pinned
  *
- * Only dynamic importers (who set up @attach with dma_buf_dynamic_attach()) may
+ * Only dynamic importers (who set up @attach with dma_buf_sgt_dynamic_attach()) may
  * call this, and only for limited use cases like scanout and not for temporary
  * pin operations. It is not permitted to allow userspace to pin arbitrary
  * amounts of buffers through this interface.
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
index 19ee9f85ff30..45dbf57c7899 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
@@ -653,8 +653,8 @@ struct drm_gem_object *amdgpu_gem_prime_import(struct drm_device *dev,
 	if (IS_ERR(obj))
 		return obj;
 
-	attach = dma_buf_dynamic_attach(dma_buf, dev->dev,
-					&amdgpu_dma_buf_attach_ops, obj);
+	attach = dma_buf_sgt_dynamic_attach(dma_buf, dev->dev,
+					    &amdgpu_dma_buf_attach_ops, obj);
 	if (IS_ERR(attach)) {
 		drm_gem_object_put(obj);
 		return ERR_CAST(attach);
diff --git a/drivers/gpu/drm/virtio/virtgpu_prime.c b/drivers/gpu/drm/virtio/virtgpu_prime.c
index 2faa22875a51..09571e746cfc 100644
--- a/drivers/gpu/drm/virtio/virtgpu_prime.c
+++ b/drivers/gpu/drm/virtio/virtgpu_prime.c
@@ -366,8 +366,8 @@ struct drm_gem_object *virtgpu_gem_prime_import(struct drm_device *dev,
 	obj->funcs = &virtgpu_gem_dma_buf_funcs;
 	drm_gem_private_object_init(dev, obj, buf->size);
 
-	attach = dma_buf_dynamic_attach(buf, dev->dev,
-					&virtgpu_dma_buf_attach_ops, obj);
+	attach = dma_buf_sgt_dynamic_attach(buf, dev->dev,
+					    &virtgpu_dma_buf_attach_ops, obj);
 	if (IS_ERR(attach)) {
 		kfree(bo);
 		return ERR_CAST(attach);
diff --git a/drivers/gpu/drm/xe/xe_dma_buf.c b/drivers/gpu/drm/xe/xe_dma_buf.c
index 3ca198da6ee8..4ed246f8617e 100644
--- a/drivers/gpu/drm/xe/xe_dma_buf.c
+++ b/drivers/gpu/drm/xe/xe_dma_buf.c
@@ -402,7 +402,7 @@ struct drm_gem_object *xe_gem_prime_import(struct drm_device *dev,
 		attach_ops = test->attach_ops;
 #endif
 
-	attach = dma_buf_dynamic_attach(dma_buf, dev->dev, attach_ops, obj);
+	attach = dma_buf_sgt_dynamic_attach(dma_buf, dev->dev, attach_ops, obj);
 	if (IS_ERR(attach)) {
 		xe_bo_put(gem_to_xe_bo(obj));
 		return ERR_CAST(attach);
diff --git a/drivers/infiniband/core/umem_dmabuf.c b/drivers/infiniband/core/umem_dmabuf.c
index 950db165d9c7..5bcf848c8675 100644
--- a/drivers/infiniband/core/umem_dmabuf.c
+++ b/drivers/infiniband/core/umem_dmabuf.c
@@ -152,11 +152,8 @@ ib_umem_dmabuf_get_with_dma_device(struct ib_device *device,
 	if (!ib_umem_num_pages(umem))
 		goto out_free_umem;
 
-	umem_dmabuf->attach = dma_buf_dynamic_attach(
-					dmabuf,
-					dma_device,
-					ops,
-					umem_dmabuf);
+	umem_dmabuf->attach = dma_buf_sgt_dynamic_attach(dmabuf, dma_device,
+							 ops, umem_dmabuf);
 	if (IS_ERR(umem_dmabuf->attach)) {
 		ret = ERR_CAST(umem_dmabuf->attach);
 		goto out_free_umem;
diff --git a/drivers/iommu/iommufd/pages.c b/drivers/iommu/iommufd/pages.c
index 404f31d8f729..82bd6d630ce8 100644
--- a/drivers/iommu/iommufd/pages.c
+++ b/drivers/iommu/iommufd/pages.c
@@ -1487,8 +1487,9 @@ static int iopt_map_dmabuf(struct iommufd_ctx *ictx, struct iopt_pages *pages,
 	struct dma_buf_attachment *attach;
 	int rc;
 
-	attach = dma_buf_dynamic_attach(dmabuf, iommufd_global_device(),
-					&iopt_dmabuf_attach_revoke_ops, pages);
+	attach = dma_buf_sgt_dynamic_attach(dmabuf, iommufd_global_device(),
+					    &iopt_dmabuf_attach_revoke_ops,
+					    pages);
 	if (IS_ERR(attach))
 		return PTR_ERR(attach);
 
diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h
index 208752eb93d9..b2f4cec5e748 100644
--- a/include/linux/dma-buf.h
+++ b/include/linux/dma-buf.h
@@ -594,9 +594,9 @@ static inline bool dma_buf_is_dynamic(struct dma_buf *dmabuf)
 struct dma_buf_attachment *dma_buf_sgt_attach(struct dma_buf *dmabuf,
 					      struct device *dev);
 struct dma_buf_attachment *
-dma_buf_dynamic_attach(struct dma_buf *dmabuf, struct device *dev,
-		       const struct dma_buf_attach_ops *importer_ops,
-		       void *importer_priv);
+dma_buf_sgt_dynamic_attach(struct dma_buf *dmabuf, struct device *dev,
+			   const struct dma_buf_attach_ops *importer_ops,
+			   void *importer_priv);
 struct dma_buf_attachment *dma_buf_mapping_attach(
 	struct dma_buf *dmabuf, struct dma_buf_mapping_match *importer_matches,
 	size_t match_len, const struct dma_buf_attach_ops *importer_ops,
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 71+ messages in thread

* [PATCH 25/26] dma-buf: Add kunit tests for mapping type
  2026-10-26  5:35 [PATCH 00/26] DMA-buf mapping types Alistair Popple
                   ` (23 preceding siblings ...)
  2026-10-26  5:36 ` [PATCH 24/26] treewide: Rename dma_buf_dynamic_attach() to dma_buf_sgt_dynamic_attach() Alistair Popple
@ 2026-10-26  5:36 ` Alistair Popple
  2026-10-26 10:19   ` sashiko-bot
  2026-10-26  5:36 ` [PATCH 26/26] dma-buf: Add kunit tests for mapping type selection Alistair Popple
  25 siblings, 1 reply; 71+ messages in thread
From: Alistair Popple @ 2026-10-26  5:36 UTC (permalink / raw)
  To: dri-devel, christian.koenig, sumit.semwal, jgg
  Cc: Alistair Popple, Thomas Hellström, Simona Vetter,
	Matthew Brost, Vivek Kasireddy, Dongwon Kim, Leon Romanovsky,
	Kevin Tian, Xu Yilun, Karl Mehltretter, Baolu Lu, Felix Kuehling,
	Alex Deucher, intel-xe, amd-gfx, linux-media, linaro-mm-sig,
	linux-rdma, iommu, Alexey Kardashevskiy, zhipingz, treding,
	jhubbard

From: Jason Gunthorpe <jgg@nvidia.com>

Some basic coverage of common flows:
 - Check dma_buf_match_mapping()'s rules. These choices effectively
   become driver facing API and it would be a pain to change them later
 - Test the dma_bug_sgt attachment flow to see that the new wrappers work

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
[ .move_notify renamed to .invalidate_mappings - apopple ]
[ dma_buf_match_mapping() records every compatible pair into the
  attachment instead of stopping at the first, so every test passes an
  attachment and the priority tests assert the recorded match set - apopple ]
Signed-off-by: Alistair Popple <apopple@nvidia.com>
---
 drivers/dma-buf/Makefile         |   1 +
 drivers/dma-buf/st-dma-mapping.c | 385 +++++++++++++++++++++++++++++++
 2 files changed, 386 insertions(+)
 create mode 100644 drivers/dma-buf/st-dma-mapping.c

diff --git a/drivers/dma-buf/Makefile b/drivers/dma-buf/Makefile
index b25d7550bacf..92fce1b5e2e0 100644
--- a/drivers/dma-buf/Makefile
+++ b/drivers/dma-buf/Makefile
@@ -11,6 +11,7 @@ dmabuf_kunit-y := \
 	st-dma-fence.o \
 	st-dma-fence-chain.o \
 	st-dma-fence-unwrap.o \
+	st-dma-mapping.o \
 	st-dma-resv.o
 
 obj-$(CONFIG_DMABUF_KUNIT_TEST) += dmabuf_kunit.o
diff --git a/drivers/dma-buf/st-dma-mapping.c b/drivers/dma-buf/st-dma-mapping.c
new file mode 100644
index 000000000000..9d0f1e389e15
--- /dev/null
+++ b/drivers/dma-buf/st-dma-mapping.c
@@ -0,0 +1,385 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * KUnit tests for dma_buf_match_mapping()
+ */
+
+#include <kunit/device.h>
+#include <kunit/test.h>
+#include <linux/dma-buf.h>
+#include <linux/dma-buf-mapping.h>
+#include <linux/errno.h>
+
+/* Mock tracking state -- reset before each test */
+static bool mock_match_called;
+static const struct dma_buf_mapping_match *mock_match_exp_arg;
+static const struct dma_buf_mapping_match *mock_match_imp_arg;
+static int mock_match_ret;
+
+static bool mock_finish_called;
+static const struct dma_buf_match_args *mock_finish_args_arg;
+static const struct dma_buf_mapping_match *mock_finish_exp_arg;
+static const struct dma_buf_mapping_match *mock_finish_imp_arg;
+
+static int reset_mock_state(struct kunit *test)
+{
+	mock_match_called = false;
+	mock_match_exp_arg = NULL;
+	mock_match_imp_arg = NULL;
+	mock_match_ret = 0;
+	mock_finish_called = false;
+	mock_finish_args_arg = NULL;
+	mock_finish_exp_arg = NULL;
+	mock_finish_imp_arg = NULL;
+	return 0;
+}
+
+static int mock_match(struct dma_buf *dmabuf,
+		      const struct dma_buf_mapping_match *exp,
+		      const struct dma_buf_mapping_match *imp)
+{
+	mock_match_called = true;
+	mock_match_exp_arg = exp;
+	mock_match_imp_arg = imp;
+	return mock_match_ret;
+}
+
+static void mock_finish_match(struct dma_buf_match_args *args,
+			      const struct dma_buf_mapping_match *exp,
+			      const struct dma_buf_mapping_match *imp)
+{
+	mock_finish_called = true;
+	mock_finish_args_arg = args;
+	mock_finish_exp_arg = exp;
+	mock_finish_imp_arg = imp;
+
+	args->attach->map_type = (struct dma_buf_mapping_match){
+		.type = exp->type,
+		.exp_ops = exp->exp_ops,
+	};
+}
+
+/* Type with both match and finish_match callbacks */
+static struct dma_buf_mapping_type mock_type_a = {
+	.name = "mock_type_a",
+	.match = mock_match,
+	.finish_match = mock_finish_match,
+};
+
+/* Second type -- distinct pointer identity from A */
+static struct dma_buf_mapping_type mock_type_b = {
+	.name = "mock_type_b",
+	.match = mock_match,
+	.finish_match = mock_finish_match,
+};
+
+static void test_match_fail(struct kunit *test)
+{
+	struct dma_buf_mapping_match matches[] = { { .type = &mock_type_a } };
+	struct dma_buf_mapping_match exp[] = { { .type = &mock_type_b } };
+	struct dma_buf_attachment attach = {};
+	struct dma_buf_match_args args = {
+		.attach = &attach,
+		.imp_matches = matches,
+		.imp_len = ARRAY_SIZE(matches),
+	};
+
+	/* Zero-length exporter array returns -EINVAL */
+	KUNIT_EXPECT_EQ(test, dma_buf_match_mapping(&args, NULL, 0), -EINVAL);
+	KUNIT_EXPECT_FALSE(test, mock_match_called);
+	KUNIT_EXPECT_FALSE(test, mock_finish_called);
+
+	/* Zero-length importer array returns -EINVAL */
+	args = (struct dma_buf_match_args){ .attach = &attach };
+	KUNIT_EXPECT_EQ(test,
+			dma_buf_match_mapping(&args, matches,
+					      ARRAY_SIZE(matches)),
+			-EINVAL);
+	KUNIT_EXPECT_FALSE(test, mock_match_called);
+	KUNIT_EXPECT_FALSE(test, mock_finish_called);
+
+	/* Different types produce no match */
+	KUNIT_EXPECT_EQ(test,
+			dma_buf_match_mapping(&args, exp, ARRAY_SIZE(exp)),
+			-EINVAL);
+	KUNIT_EXPECT_FALSE(test, mock_match_called);
+	KUNIT_EXPECT_FALSE(test, mock_finish_called);
+}
+
+/* When type->match() is NULL same types always match */
+static void test_match_no_match_callback(struct kunit *test)
+{
+	static struct dma_buf_mapping_type mock_type_no_match = {
+		.name = "mock_type_no_match",
+		.finish_match = mock_finish_match,
+	};
+	struct dma_buf_mapping_match matches[] = {
+		{ .type = &mock_type_no_match }
+	};
+	struct dma_buf_attachment attach = {};
+	struct dma_buf_match_args args = {
+		.attach = &attach,
+		.imp_matches = matches,
+		.imp_len = ARRAY_SIZE(matches),
+	};
+
+	KUNIT_EXPECT_EQ(
+		test,
+		dma_buf_match_mapping(&args, matches, ARRAY_SIZE(matches)), 0);
+	KUNIT_EXPECT_FALSE(test, mock_match_called);
+	KUNIT_EXPECT_TRUE(test, mock_finish_called);
+	KUNIT_EXPECT_PTR_EQ(test, mock_finish_args_arg, &args);
+	KUNIT_EXPECT_PTR_EQ(test, mock_finish_exp_arg, &matches[0]);
+	KUNIT_EXPECT_PTR_EQ(test, mock_finish_imp_arg, &matches[0]);
+}
+
+static void test_match_callback_returns(struct kunit *test)
+{
+	struct dma_buf_mapping_match matches[] = { { .type = &mock_type_a } };
+	struct dma_buf_attachment attach = {};
+	struct dma_buf_match_args args = {
+		.attach = &attach,
+		.imp_matches = matches,
+		.imp_len = ARRAY_SIZE(matches),
+	};
+
+	/* type->match() returns -EOPNOTSUPP. Skips to next */
+	mock_match_ret = -EOPNOTSUPP;
+	KUNIT_EXPECT_EQ(test,
+			dma_buf_match_mapping(&args, matches,
+					      ARRAY_SIZE(matches)),
+			-EINVAL);
+	KUNIT_EXPECT_TRUE(test, mock_match_called);
+	KUNIT_EXPECT_FALSE(test, mock_finish_called);
+
+	/* type->match() returns an error code. Stops immediately, returns code */
+	mock_match_ret = -ENOMEM;
+	KUNIT_EXPECT_EQ(test,
+			dma_buf_match_mapping(&args, matches,
+					      ARRAY_SIZE(matches)),
+			-ENOMEM);
+	KUNIT_EXPECT_TRUE(test, mock_match_called);
+	KUNIT_EXPECT_FALSE(test, mock_finish_called);
+}
+
+/*
+ * The match set records every compatible pair, in the exporter's order. The
+ * first entry is the default selection.
+ */
+static void test_match_exporter_priority(struct kunit *test)
+{
+	struct dma_buf_mapping_match exp1[2] = {
+		{ .type = &mock_type_a },
+		{ .type = &mock_type_b },
+	};
+	struct dma_buf_mapping_match exp2[] = { { .type = &mock_type_b } };
+	struct dma_buf_mapping_match imp[2] = {
+		{ .type = &mock_type_a },
+		{ .type = &mock_type_b },
+	};
+	struct dma_buf_attachment attach = {};
+	struct dma_buf_match_args args = {
+		.attach = &attach,
+		.imp_matches = imp,
+		.imp_len = ARRAY_SIZE(imp),
+	};
+
+	/* Both match, exporter order preserved, first is the default */
+	KUNIT_EXPECT_EQ(
+		test, dma_buf_match_mapping(&args, exp1, ARRAY_SIZE(exp1)), 0);
+	KUNIT_ASSERT_EQ(test, attach.nr_matches, 2);
+	KUNIT_EXPECT_PTR_EQ(test, attach.matches[0].type, &mock_type_a);
+	KUNIT_EXPECT_PTR_EQ(test, attach.matches[1].type, &mock_type_b);
+	KUNIT_EXPECT_PTR_EQ(test, attach.map_type.type, &mock_type_a);
+
+	/* Only the second importer type is offered */
+	KUNIT_EXPECT_EQ(
+		test, dma_buf_match_mapping(&args, exp2, ARRAY_SIZE(exp2)), 0);
+	KUNIT_ASSERT_EQ(test, attach.nr_matches, 1);
+	KUNIT_EXPECT_PTR_EQ(test, attach.matches[0].type, &mock_type_b);
+	KUNIT_EXPECT_PTR_EQ(test, attach.map_type.type, &mock_type_b);
+	KUNIT_EXPECT_PTR_EQ(test, mock_finish_imp_arg, &imp[1]);
+}
+
+/* The exporter's order wins over the importer's */
+static void test_match_importer_priority(struct kunit *test)
+{
+	struct dma_buf_mapping_match exp[] = {
+		{ .type = &mock_type_a },
+		{ .type = &mock_type_b },
+	};
+	struct dma_buf_mapping_match imp1[] = { { .type = &mock_type_b } };
+	struct dma_buf_mapping_match imp2[] = {
+		{ .type = &mock_type_b },
+		{ .type = &mock_type_a },
+	};
+	struct dma_buf_attachment attach = {};
+	struct dma_buf_match_args args = {
+		.attach = &attach,
+		.imp_matches = imp1,
+		.imp_len = ARRAY_SIZE(imp1),
+	};
+
+	/* Single importer type */
+	KUNIT_EXPECT_EQ(test,
+			dma_buf_match_mapping(&args, exp, ARRAY_SIZE(exp)), 0);
+	KUNIT_ASSERT_EQ(test, attach.nr_matches, 1);
+	KUNIT_EXPECT_PTR_EQ(test, attach.matches[0].type, &mock_type_b);
+	KUNIT_EXPECT_PTR_EQ(test, mock_finish_imp_arg, &imp1[0]);
+
+	/* Importer prefers B, exporter prefers A: A is the default */
+	args.imp_matches = imp2;
+	args.imp_len = ARRAY_SIZE(imp2);
+	KUNIT_EXPECT_EQ(test,
+			dma_buf_match_mapping(&args, exp, ARRAY_SIZE(exp)), 0);
+	KUNIT_ASSERT_EQ(test, attach.nr_matches, 2);
+	KUNIT_EXPECT_PTR_EQ(test, attach.matches[0].type, &mock_type_a);
+	KUNIT_EXPECT_PTR_EQ(test, attach.matches[1].type, &mock_type_b);
+	KUNIT_EXPECT_PTR_EQ(test, attach.map_type.type, &mock_type_a);
+}
+
+static void mock_dmabuf_release(struct dma_buf *dmabuf)
+{
+}
+
+static struct sg_table *mock_map_dma_buf(struct dma_buf_attachment *attach,
+					 enum dma_data_direction dir)
+{
+	return ERR_PTR(-ENODEV);
+}
+
+static void mock_unmap_dma_buf(struct dma_buf_attachment *attach,
+			       struct sg_table *sgt,
+			       enum dma_data_direction dir)
+{
+}
+
+static const struct dma_buf_mapping_sgt_exp_ops mock_sgt_ops = {
+	.map_dma_buf = mock_map_dma_buf,
+	.unmap_dma_buf = mock_unmap_dma_buf,
+};
+
+static const struct dma_buf_ops mock_dmabuf_simple_sgt_ops = {
+	.release = mock_dmabuf_release,
+	DMA_BUF_SIMPLE_SGT_EXP_MATCH(mock_map_dma_buf, mock_unmap_dma_buf),
+};
+
+static int mock_dmabuf_match_mapping(struct dma_buf_match_args *args)
+{
+	struct dma_buf_mapping_match sgt_match[2];
+	unsigned int num_match = 0;
+
+	sgt_match[num_match++] =
+		(struct dma_buf_mapping_match){ .type = &mock_type_a };
+
+	sgt_match[num_match++] = DMA_BUF_EMAPPING_SGT(&mock_sgt_ops);
+
+	return dma_buf_match_mapping(args, sgt_match, ARRAY_SIZE(sgt_match));
+}
+
+static const struct dma_buf_ops mock_dmabuf_two_exp_ops = {
+	.release = mock_dmabuf_release,
+	.match_mapping = mock_dmabuf_match_mapping,
+};
+
+struct dma_exporter {
+	const struct dma_buf_ops *ops;
+	const char *desc;
+};
+
+static struct dma_buf *mock_dmabuf_export(const struct dma_buf_ops *ops)
+{
+	DEFINE_DMA_BUF_EXPORT_INFO(exp_info);
+
+	exp_info.ops = ops;
+	exp_info.size = PAGE_SIZE;
+	exp_info.priv = ERR_PTR(-EINVAL);
+	return dma_buf_export(&exp_info);
+}
+
+/*
+ * Check that a simple SGT exporter with single_exporter_match works with
+ * dma_buf_sgt_attach()
+ */
+static void test_sgt_attach(struct kunit *test)
+{
+	const struct dma_exporter *param = test->param_value;
+	struct dma_buf *dmabuf;
+	struct dma_buf_attachment *attach;
+	struct device *dev;
+
+	dev = kunit_device_register(test, "dma-buf-test");
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
+
+	dmabuf = mock_dmabuf_export(param->ops);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dmabuf);
+
+	attach = dma_buf_sgt_attach(dmabuf, dev);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, attach);
+
+	KUNIT_EXPECT_PTR_EQ(test, attach->map_type.type,
+			    &dma_buf_mapping_sgt_type);
+	KUNIT_EXPECT_PTR_EQ(test, dma_buf_sgt_dma_device(attach), dev);
+	KUNIT_EXPECT_FALSE(test, dma_buf_sgt_p2p_allowed(attach));
+
+	dma_buf_detach(dmabuf, attach);
+	dma_buf_put(dmabuf);
+}
+
+static void mock_move_notify(struct dma_buf_attachment *attach)
+{
+}
+
+static const struct dma_buf_attach_ops mock_importer_ops = {
+	.invalidate_mappings = &mock_move_notify,
+};
+
+/* Check a dynamic attach with a non-sgt mapping type */
+static void test_mock_attach(struct kunit *test)
+{
+	struct dma_buf_mapping_match imp[] = { { .type = &mock_type_a } };
+	struct dma_buf *dmabuf;
+	struct dma_buf_attachment *attach;
+	struct device *dev;
+
+	dev = kunit_device_register(test, "dma-buf-test");
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
+
+	dmabuf = mock_dmabuf_export(&mock_dmabuf_two_exp_ops);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dmabuf);
+
+	attach = dma_buf_mapping_attach(dmabuf, imp, ARRAY_SIZE(imp),
+					&mock_importer_ops, NULL);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, attach);
+
+	KUNIT_EXPECT_PTR_EQ(test, attach->map_type.type, &mock_type_a);
+
+	dma_buf_detach(dmabuf, attach);
+	dma_buf_put(dmabuf);
+}
+
+static const struct dma_exporter dma_exporter_params[] = {
+	{ &mock_dmabuf_simple_sgt_ops, "simple_sgt" },
+	{ &mock_dmabuf_two_exp_ops, "two_exp" },
+};
+KUNIT_ARRAY_PARAM_DESC(dma_exporter, dma_exporter_params, desc);
+
+static struct kunit_case dma_mapping_cases[] = {
+	KUNIT_CASE(test_match_fail),
+	KUNIT_CASE(test_match_no_match_callback),
+	KUNIT_CASE(test_match_callback_returns),
+	KUNIT_CASE(test_match_exporter_priority),
+	KUNIT_CASE(test_match_importer_priority),
+	KUNIT_CASE_PARAM(test_sgt_attach, dma_exporter_gen_params),
+	KUNIT_CASE(test_mock_attach),
+	{}
+};
+
+static struct kunit_suite dma_mapping_test_suite = {
+	.name = "dma-buf-mapping",
+	.init = reset_mock_state,
+	.test_cases = dma_mapping_cases,
+};
+
+kunit_test_suite(dma_mapping_test_suite);
+
+MODULE_IMPORT_NS("DMA_BUF");
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 71+ messages in thread

* [PATCH 26/26] dma-buf: Add kunit tests for mapping type selection
  2026-10-26  5:35 [PATCH 00/26] DMA-buf mapping types Alistair Popple
                   ` (24 preceding siblings ...)
  2026-10-26  5:36 ` [PATCH 25/26] dma-buf: Add kunit tests for mapping type Alistair Popple
@ 2026-10-26  5:36 ` Alistair Popple
  2026-10-26 10:22   ` sashiko-bot
  25 siblings, 1 reply; 71+ messages in thread
From: Alistair Popple @ 2026-10-26  5:36 UTC (permalink / raw)
  To: dri-devel, christian.koenig, sumit.semwal, jgg
  Cc: Alistair Popple, Thomas Hellström, Simona Vetter,
	Matthew Brost, Vivek Kasireddy, Dongwon Kim, Leon Romanovsky,
	Kevin Tian, Xu Yilun, Karl Mehltretter, Baolu Lu, Felix Kuehling,
	Alex Deucher, intel-xe, amd-gfx, linux-media, linaro-mm-sig,
	linux-rdma, iommu, Alexey Kardashevskiy, zhipingz, treding,
	jhubbard

Add an offer list and a select_mapping() callback to the mock exporter
along with map/unmap for the two mock types.

Adds tests for the exporter/importer contract.

 - test_match_set_is_final: a later importer attaching, even one the
   exporter answers differently, does not change an existing
   attachment's match set or default. Later attachments influence what
   the exporter selects at pin and map time, not previous attachments.

 - test_select_at_map: the exporter chooses a non-default entry
   at the first map and the result is tagged with it. A pin taken
   under the live mapping inherits the type and the choice survives
   unmap/remap even though the exporter would answer differently. Only
   dma_buf_invalidate_mappings() allows the exporter to make a different
   selection. An -EBUSY from selection leaves nothing established.

 - test_select_at_pin: pin selects, and the choice survives map, unmap
   and unpin so a pinned importer that is never invalidated keeps its
   first type for the life of the import.

Assisted-by: LLM
Signed-off-by: Alistair Popple <apopple@nvidia.com>
---
 drivers/dma-buf/st-dma-mapping.c | 277 +++++++++++++++++++++++++++++++
 1 file changed, 277 insertions(+)

diff --git a/drivers/dma-buf/st-dma-mapping.c b/drivers/dma-buf/st-dma-mapping.c
index 9d0f1e389e15..22c1d73ea087 100644
--- a/drivers/dma-buf/st-dma-mapping.c
+++ b/drivers/dma-buf/st-dma-mapping.c
@@ -7,6 +7,7 @@
 #include <kunit/test.h>
 #include <linux/dma-buf.h>
 #include <linux/dma-buf-mapping.h>
+#include <linux/dma-resv.h>
 #include <linux/errno.h>
 
 /* Mock tracking state -- reset before each test */
@@ -20,6 +21,14 @@ static const struct dma_buf_match_args *mock_finish_args_arg;
 static const struct dma_buf_mapping_match *mock_finish_exp_arg;
 static const struct dma_buf_mapping_match *mock_finish_imp_arg;
 
+/* Mapping types the configurable mock exporter currently offers */
+static const struct dma_buf_mapping_match *mock_exp_offer;
+static size_t mock_exp_offer_len;
+
+/* Which match set entry the selecting mock exporter picks, or an error */
+static int mock_select_idx;
+static int mock_select_err;
+
 static int reset_mock_state(struct kunit *test)
 {
 	mock_match_called = false;
@@ -30,6 +39,10 @@ static int reset_mock_state(struct kunit *test)
 	mock_finish_args_arg = NULL;
 	mock_finish_exp_arg = NULL;
 	mock_finish_imp_arg = NULL;
+	mock_exp_offer = NULL;
+	mock_exp_offer_len = 0;
+	mock_select_idx = 0;
+	mock_select_err = 0;
 	return 0;
 }
 
@@ -357,6 +370,267 @@ static void test_mock_attach(struct kunit *test)
 	dma_buf_put(dmabuf);
 }
 
+static int mock_dmabuf_offer_match_mapping(struct dma_buf_match_args *args)
+{
+	return dma_buf_match_mapping(args, mock_exp_offer, mock_exp_offer_len);
+}
+
+static const struct dma_buf_ops mock_dmabuf_offer_ops = {
+	.release = mock_dmabuf_release,
+	.match_mapping = mock_dmabuf_offer_match_mapping,
+};
+
+/*
+ * The match set is final once attached. A later importer attaching, even one
+ * the exporter answers differently, must not change an existing attachment.
+ *
+ * Later attachments influence what the exporter selects at pin or map time,
+ * not what was previously negotiated.
+ */
+static void test_match_set_is_final(struct kunit *test)
+{
+	static const struct dma_buf_mapping_match offer_ab[] = {
+		{ .type = &mock_type_a },
+		{ .type = &mock_type_b },
+	};
+	static const struct dma_buf_mapping_match offer_b[] = {
+		{ .type = &mock_type_b },
+	};
+	struct dma_buf_mapping_match imp1[] = {
+		{ .type = &mock_type_a },
+		{ .type = &mock_type_b },
+	};
+	struct dma_buf_mapping_match imp2[] = { { .type = &mock_type_b } };
+	struct dma_buf_attachment *attach1, *attach2;
+	struct dma_buf *dmabuf;
+
+	dmabuf = mock_dmabuf_export(&mock_dmabuf_offer_ops);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dmabuf);
+
+	mock_exp_offer = offer_ab;
+	mock_exp_offer_len = ARRAY_SIZE(offer_ab);
+	attach1 = dma_buf_mapping_attach(dmabuf, imp1, ARRAY_SIZE(imp1),
+					 &mock_importer_ops, NULL);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, attach1);
+	KUNIT_ASSERT_EQ(test, attach1->nr_matches, 2);
+	KUNIT_EXPECT_PTR_EQ(test, attach1->map_type.type, &mock_type_a);
+
+	/* Exporter's answer for new importers changes; attach1 does not */
+	mock_exp_offer = offer_b;
+	mock_exp_offer_len = ARRAY_SIZE(offer_b);
+	attach2 = dma_buf_mapping_attach(dmabuf, imp2, ARRAY_SIZE(imp2),
+					 &mock_importer_ops, NULL);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, attach2);
+	KUNIT_ASSERT_EQ(test, attach2->nr_matches, 1);
+	KUNIT_EXPECT_PTR_EQ(test, attach2->map_type.type, &mock_type_b);
+	KUNIT_EXPECT_EQ(test, attach1->nr_matches, 2);
+	KUNIT_EXPECT_PTR_EQ(test, attach1->map_type.type, &mock_type_a);
+
+	dma_buf_detach(dmabuf, attach2);
+	KUNIT_EXPECT_EQ(test, attach1->nr_matches, 2);
+	KUNIT_EXPECT_PTR_EQ(test, attach1->map_type.type, &mock_type_a);
+
+	dma_buf_detach(dmabuf, attach1);
+	dma_buf_put(dmabuf);
+}
+
+/* Mock mapping result for the generic map path */
+struct mock_mapping {
+	struct dma_buf_mapping base;
+	const struct dma_buf_mapping_type *made_by;
+};
+
+static struct dma_buf_mapping *mock_type_map(struct dma_buf_attachment *attach,
+					     enum dma_data_direction dir)
+{
+	struct mock_mapping *m = kzalloc_obj(*m);
+
+	if (!m)
+		return ERR_PTR(-ENOMEM);
+	m->base.type = attach->map_type.type;
+	m->made_by = attach->map_type.type;
+	return &m->base;
+}
+
+static void mock_type_unmap(struct dma_buf_attachment *attach,
+			    struct dma_buf_mapping *mapping,
+			    enum dma_data_direction dir)
+{
+	kfree(container_of(mapping, struct mock_mapping, base));
+}
+
+/* Exporter choosing the match set entry the test asks for */
+static const struct dma_buf_mapping_match *
+mock_dmabuf_select_mapping(struct dma_buf_attachment *attach)
+{
+	if (mock_select_err)
+		return ERR_PTR(mock_select_err);
+	return &attach->matches[mock_select_idx];
+}
+
+static const struct dma_buf_ops mock_dmabuf_select_ops = {
+	.release = mock_dmabuf_release,
+	.match_mapping = mock_dmabuf_offer_match_mapping,
+	.select_mapping = mock_dmabuf_select_mapping,
+};
+
+/*
+ * Exporter decides type at first map from the match set. The result is tagged
+ * with it and the core holds the choice across unmap/remap until the attachment
+ * has been explicitly invalidated.
+ */
+static void test_select_at_map(struct kunit *test)
+{
+	static const struct dma_buf_mapping_match offer_ab[] = {
+		{ .type = &mock_type_a },
+		{ .type = &mock_type_b },
+	};
+	struct dma_buf_mapping_match imp[] = {
+		{ .type = &mock_type_a },
+		{ .type = &mock_type_b },
+	};
+	struct dma_buf_attachment *attach;
+	struct dma_buf_mapping *mapping;
+	struct dma_buf *dmabuf;
+
+	mock_type_a.map = mock_type_map;
+	mock_type_a.unmap = mock_type_unmap;
+	mock_type_b.map = mock_type_map;
+	mock_type_b.unmap = mock_type_unmap;
+
+	dmabuf = mock_dmabuf_export(&mock_dmabuf_select_ops);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dmabuf);
+
+	mock_exp_offer = offer_ab;
+	mock_exp_offer_len = ARRAY_SIZE(offer_ab);
+	attach = dma_buf_mapping_attach(dmabuf, imp, ARRAY_SIZE(imp),
+					&mock_importer_ops, NULL);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, attach);
+	KUNIT_EXPECT_FALSE(test, attach->selected);
+	KUNIT_EXPECT_PTR_EQ(test, attach->map_type.type, &mock_type_a);
+
+	dma_resv_lock(dmabuf->resv, NULL);
+
+	/* Exporter picks the second entry (mock_type_b) */
+	mock_select_idx = 1;
+	mapping = dma_buf_mapping_map(attach, DMA_BIDIRECTIONAL);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, mapping);
+	KUNIT_EXPECT_PTR_EQ(test, mapping->type, &mock_type_b);
+	KUNIT_EXPECT_PTR_EQ(test, attach->map_type.type, &mock_type_b);
+	KUNIT_EXPECT_TRUE(test, attach->selected);
+
+	/* A pin taken whilst mapping is live gets the same type */
+	mock_select_idx = 0;
+	KUNIT_EXPECT_EQ(test, dma_buf_pin(attach), 0);
+	KUNIT_EXPECT_PTR_EQ(test, attach->map_type.type, &mock_type_b);
+	dma_buf_unpin(attach);
+
+	dma_buf_mapping_unmap(attach, mapping, DMA_BIDIRECTIONAL);
+
+	/*
+	 * Unmapped the exporter would now pick A, but no invalidate has
+	 * happened so remap must get B again to avoid ping-ponging.
+	 */
+	KUNIT_EXPECT_TRUE(test, attach->selected);
+	mapping = dma_buf_mapping_map(attach, DMA_BIDIRECTIONAL);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, mapping);
+	KUNIT_EXPECT_PTR_EQ(test, mapping->type, &mock_type_b);
+	dma_buf_mapping_unmap(attach, mapping, DMA_BIDIRECTIONAL);
+
+	/* Only an explicit invalidation allows the type to change */
+	dma_buf_invalidate_mappings(dmabuf);
+	KUNIT_EXPECT_FALSE(test, attach->selected);
+	/* map_type is kept for a pending unmap until the next selection */
+	KUNIT_EXPECT_PTR_EQ(test, attach->map_type.type, &mock_type_b);
+
+	mapping = dma_buf_mapping_map(attach, DMA_BIDIRECTIONAL);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, mapping);
+	KUNIT_EXPECT_PTR_EQ(test, mapping->type, &mock_type_a);
+	dma_buf_mapping_unmap(attach, mapping, DMA_BIDIRECTIONAL);
+
+	/* Exporter cannot serve this importer right now */
+	dma_buf_invalidate_mappings(dmabuf);
+	mock_select_err = -EBUSY;
+	mapping = dma_buf_mapping_map(attach, DMA_BIDIRECTIONAL);
+	KUNIT_EXPECT_EQ(test, PTR_ERR(mapping), -EBUSY);
+	KUNIT_EXPECT_FALSE(test, attach->selected);
+	mock_select_err = 0;
+
+	dma_resv_unlock(dmabuf->resv);
+
+	dma_buf_detach(dmabuf, attach);
+	dma_buf_put(dmabuf);
+
+	mock_type_a.map = NULL;
+	mock_type_a.unmap = NULL;
+	mock_type_b.map = NULL;
+	mock_type_b.unmap = NULL;
+}
+
+/*
+ * Pin selects too and the choice survives map, unmap and unpin. A pinned
+ * importer that is never invalidated keeps its first type for the life of the
+ * attachment.
+ */
+static void test_select_at_pin(struct kunit *test)
+{
+	static const struct dma_buf_mapping_match offer_ab[] = {
+		{ .type = &mock_type_a },
+		{ .type = &mock_type_b },
+	};
+	struct dma_buf_mapping_match imp[] = {
+		{ .type = &mock_type_a },
+		{ .type = &mock_type_b },
+	};
+	struct dma_buf_attachment *attach;
+	struct dma_buf_mapping *mapping;
+	struct dma_buf *dmabuf;
+
+	mock_type_a.map = mock_type_map;
+	mock_type_a.unmap = mock_type_unmap;
+	mock_type_b.map = mock_type_map;
+	mock_type_b.unmap = mock_type_unmap;
+
+	dmabuf = mock_dmabuf_export(&mock_dmabuf_select_ops);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dmabuf);
+
+	mock_exp_offer = offer_ab;
+	mock_exp_offer_len = ARRAY_SIZE(offer_ab);
+	attach = dma_buf_mapping_attach(dmabuf, imp, ARRAY_SIZE(imp),
+					&mock_importer_ops, NULL);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, attach);
+
+	dma_resv_lock(dmabuf->resv, NULL);
+
+	mock_select_idx = 1;
+	KUNIT_EXPECT_EQ(test, dma_buf_pin(attach), 0);
+	KUNIT_EXPECT_TRUE(test, attach->selected);
+	KUNIT_EXPECT_PTR_EQ(test, attach->map_type.type, &mock_type_b);
+
+	/* Map after pin uses the pinned type regardless of the exporter now */
+	mock_select_idx = 0;
+	mapping = dma_buf_mapping_map(attach, DMA_BIDIRECTIONAL);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, mapping);
+	KUNIT_EXPECT_PTR_EQ(test, mapping->type, &mock_type_b);
+	dma_buf_mapping_unmap(attach, mapping, DMA_BIDIRECTIONAL);
+
+	KUNIT_EXPECT_PTR_EQ(test, attach->map_type.type, &mock_type_b);
+
+	dma_buf_unpin(attach);
+	KUNIT_EXPECT_TRUE(test, attach->selected);
+	KUNIT_EXPECT_PTR_EQ(test, attach->map_type.type, &mock_type_b);
+
+	dma_resv_unlock(dmabuf->resv);
+
+	dma_buf_detach(dmabuf, attach);
+	dma_buf_put(dmabuf);
+
+	mock_type_a.map = NULL;
+	mock_type_a.unmap = NULL;
+	mock_type_b.map = NULL;
+	mock_type_b.unmap = NULL;
+}
+
 static const struct dma_exporter dma_exporter_params[] = {
 	{ &mock_dmabuf_simple_sgt_ops, "simple_sgt" },
 	{ &mock_dmabuf_two_exp_ops, "two_exp" },
@@ -371,6 +645,9 @@ static struct kunit_case dma_mapping_cases[] = {
 	KUNIT_CASE(test_match_importer_priority),
 	KUNIT_CASE_PARAM(test_sgt_attach, dma_exporter_gen_params),
 	KUNIT_CASE(test_mock_attach),
+	KUNIT_CASE(test_match_set_is_final),
+	KUNIT_CASE(test_select_at_map),
+	KUNIT_CASE(test_select_at_pin),
 	{}
 };
 
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 71+ messages in thread

* Re: [PATCH 01/26] dma-buf: Introduce DMA-buf mapping types
  2026-10-26  5:35 ` [PATCH 01/26] dma-buf: Introduce " Alistair Popple
@ 2026-10-26  7:00   ` sashiko-bot
  0 siblings, 0 replies; 71+ messages in thread
From: sashiko-bot @ 2026-10-26  7:00 UTC (permalink / raw)
  To: Alistair Popple; +Cc: linux-rdma

> From: Jason Gunthorpe <jgg@nvidia.com>
> 
> DMA-buf mapping types allow the importer and exporter to negotiate the
> format of the map/unmap to be used during the attachment.
> 
> Currently DMA-buf only supports struct scatterlist as the attachment map
> operation.  This is not sufficient for all use cases as dma_addr_t is a
> very specific and limited type.
> 
> With mapping types the importing driver can declare what it supports. For
> example:
> 
> 	struct dma_buf_mapping_match imp_match[] = {
> 		DMA_BUF_IMAPPING_MY_DRIVER(dev, ...),
> 		DMA_BUF_IMAPPING_SGT(dev, false),
> [ ... ]
>   attach->matches instead of stopping at the first match, so that the
>   exporter can choose among the mutually acceptable types later, at pin or
>   map time, rather than the core fixing one type at attach. - apopple ]
> Co-developed-by: Alistair Popple <apopple@nvidia.com>
> Signed-off-by: Alistair Popple <apopple@nvidia.com>

Sashiko has reviewed this patch and found no issues.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261026053623.202642-1-apopple@nvidia.com?part=1


^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH 02/26] dma-buf: Add the SGT DMA mapping type
  2026-10-26  5:35 ` [PATCH 02/26] dma-buf: Add the SGT DMA mapping type Alistair Popple
@ 2026-10-26  7:04   ` sashiko-bot
  0 siblings, 0 replies; 71+ messages in thread
From: sashiko-bot @ 2026-10-26  7:04 UTC (permalink / raw)
  To: Alistair Popple; +Cc: linux-rdma

> From: Jason Gunthorpe <jgg@nvidia.com>
> 
> The SGT (Scatter Gather Table) DMA mapping type represents the existing
> sg_table/scatterlist based DMA mapping. It provides a sg_table based
> map/unmap interface that exactly matches how things work today.
> 
> dma_buf_sgt_exp_compat_match will be used in the next patch to
> transparently wrap an unaware exporter with a mapping type.
> 
> The SGT type handles the allow_peer2peer flag directly through matching
> logic. The importer indicates if it is willing to accept peer2peer and the
> exporter indicates if it requires peer2peer. A required peer2peer exporter
> will not match to an importer that does not accept peer2peer.
> 
> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>

Sashiko has reviewed this patch and found no issues.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261026053623.202642-1-apopple@nvidia.com?part=2


^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH 03/26] dma-buf: Add dma_buf_mapping_attach()
  2026-10-26  5:35 ` [PATCH 03/26] dma-buf: Add dma_buf_mapping_attach() Alistair Popple
@ 2026-10-26  7:20   ` sashiko-bot
  0 siblings, 0 replies; 71+ messages in thread
From: sashiko-bot @ 2026-10-26  7:20 UTC (permalink / raw)
  To: Alistair Popple, dri-devel; +Cc: intel-xe, linux-rdma, media-ci

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] dma-buf: NULL pointer dereference of importer_ops in dma_buf_dynamic_attach()
--

commit 4415ca9de8f7d7c189e76efc4aa022c3564f88f1
Author: Jason Gunthorpe <jgg@ziepe.ca>

dma-buf: Add dma_buf_mapping_attach()

This commit introduces dma_buf_mapping_attach() to match importer-supported
mapping types against exporter-supported mapping types during attachment. It
also converts dma_buf_attach() and dma_buf_dynamic_attach() into wrappers
around dma_buf_mapping_attach().

> diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c
> index 4c9add51f9ef5..16a7fbb8aaabe 100644
> --- a/drivers/dma-buf/dma-buf.c
> +++ b/drivers/dma-buf/dma-buf.c

[ ... ]

> @@ -1025,31 +1035,55 @@ dma_buf_pin_on_map(struct dma_buf_attachment *attach)

[ ... ]

> -	attach->dev = dev;
>  	attach->dmabuf = dmabuf;
> -	if (importer_ops)
> -		attach->peer2peer = importer_ops->allow_peer2peer;
>  	attach->importer_ops = importer_ops;
>  	attach->importer_priv = importer_priv;

[ ... ]

> @@ -1068,23 +1103,53 @@ dma_buf_dynamic_attach(struct dma_buf *dmabuf, struct device *dev,

[ ... ]

> +/**
> + * dma_buf_dynamic_attach - Add the device to dma_buf's attachments list
> + * @dmabuf:		[in]	buffer to attach device to.
> + * @dev:		[in]	device to be attached.
> + * @importer_ops:	[in]	importer operations for the attachment
> + * @importer_priv:	[in]	importer private pointer for the attachment
> + *
> + * Wrapper to call dma_buf_mapping_attach() for drivers which only support SGT.
> + */
> +struct dma_buf_attachment *
> +dma_buf_dynamic_attach(struct dma_buf *dmabuf, struct device *dev,
> +		       const struct dma_buf_attach_ops *importer_ops,
> +		       void *importer_priv)
> +{
> +	struct dma_buf_mapping_match sgt_match[] = {
> +		DMA_BUF_IMAPPING_SGT(dev, importer_ops->allow_peer2peer ?
> +						  DMA_SGT_IMPORTER_ACCEPTS_P2P :
> +						  DMA_SGT_NO_P2P),
> +	};

[Severity: High]
Can importer_ops be NULL when passed to dma_buf_dynamic_attach(), causing a
NULL pointer dereference when evaluating importer_ops->allow_peer2peer?

Previously, dma_buf_dynamic_attach() guarded this dereference with
if (importer_ops). In-tree callers still rely on passing a NULL importer_ops
pointer here, such as xe_gem_prime_import() when running the non-dynamic KUnit
test cases in drivers/gpu/drm/xe/tests/xe_dma_buf.c:

drivers/gpu/drm/xe/xe_dma_buf.c:xe_gem_prime_import() {
	...
	attach_ops = &xe_dma_buf_attach_ops;
#if IS_ENABLED(CONFIG_DRM_XE_KUNIT_TEST)
	if (test)
		attach_ops = test->attach_ops;
#endif

	attach = dma_buf_dynamic_attach(dma_buf, dev->dev, attach_ops, obj);
	...
}

Note that a later commit in the series, 77ea3fee521c ("dma-buf: Rename
dma_buf_dynamic_attach() to dma_buf_sgt_dynamic_attach()"), renames this
function while keeping the unconditional importer_ops->allow_peer2peer
dereference.

Should dma_buf_dynamic_attach() check importer_ops &&
importer_ops->allow_peer2peer before dereferencing importer_ops?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261026053623.202642-1-apopple@nvidia.com?part=3

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH 04/26] dma-buf: Route SGT related actions through attach->map_type
  2026-10-26  5:35 ` [PATCH 04/26] dma-buf: Route SGT related actions through attach->map_type Alistair Popple
@ 2026-10-26  7:29   ` sashiko-bot
  0 siblings, 0 replies; 71+ messages in thread
From: sashiko-bot @ 2026-10-26  7:29 UTC (permalink / raw)
  To: Alistair Popple, dri-devel; +Cc: intel-xe, linux-rdma, media-ci

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] dma-buf: dma_buf_get_sgt_ops() called before !attach NULL check
--

commit b7db1c5ac9aaaa1115dc4420ef21a9d03108a96b
Author: Jason Gunthorpe <jgg@ziepe.ca>

dma-buf: Route SGT related actions through attach->map_type

This commit routes sg_table map, unmap, and debugfs dump operations through
attach->map_type instead of calling attach->dmabuf->ops directly.

> diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c
> index 16a7fbb8aaabe..348b47f266b48 100644
> --- a/drivers/dma-buf/dma-buf.c
> +++ b/drivers/dma-buf/dma-buf.c
> @@ -1253,12 +1253,14 @@ EXPORT_SYMBOL_NS_GPL(dma_buf_unpin, "DMA_BUF");
>  struct sg_table *dma_buf_map_attachment(struct dma_buf_attachment *attach,
>  					enum dma_data_direction direction)
>  {
> +	const struct dma_buf_mapping_sgt_exp_ops *sgt_exp_ops =
> +		dma_buf_get_sgt_ops(attach);
>  	struct sg_table *sg_table;
>  	signed long ret;
>  
>  	might_sleep();
>  
> -	if (WARN_ON(!attach || !attach->dmabuf))
> +	if (WARN_ON(!attach || !attach->dmabuf || !sgt_exp_ops))
>  		return ERR_PTR(-EINVAL);

[ ... ]

> @@ -1366,15 +1368,18 @@ void dma_buf_unmap_attachment(struct dma_buf_attachment *attach,
>  				struct sg_table *sg_table,
>  				enum dma_data_direction direction)
>  {
> +	const struct dma_buf_mapping_sgt_exp_ops *sgt_exp_ops =
> +		dma_buf_get_sgt_ops(attach);
> +
>  	might_sleep();
>  
> -	if (WARN_ON(!attach || !attach->dmabuf || !sg_table))
> +	if (WARN_ON(!attach || !attach->dmabuf || !sg_table || !sgt_exp_ops))
>  		return;

[Severity: Medium]
Can calling dma_buf_get_sgt_ops(attach) in the variable initializers of
dma_buf_map_attachment() and dma_buf_unmap_attachment() cause a null
pointer dereference when attach is null?

In include/linux/dma-buf-mapping.h, dma_buf_get_sgt_ops() unconditionally
dereferences attach:

static inline const struct dma_buf_mapping_sgt_exp_ops *
dma_buf_get_sgt_ops(struct dma_buf_attachment *attach)
{
	if (attach->map_type.type != &dma_buf_mapping_sgt_type)
		return NULL;
	return container_of(attach->map_type.exp_ops,
			    struct dma_buf_mapping_sgt_exp_ops, ops);
}

Because dma_buf_get_sgt_ops(attach) runs before the WARN_ON(!attach || ...)
checks in both functions, passing a null attach will dereference a null
pointer instead of triggering the warning and returning early, and the
compiler may also optimize away the subsequent !attach checks.

Note that while the dma_buf_map_attachment() path is refactored in a later
commit in this series ("dma-buf: Let the exporter select mapping type at
pin/map") when __dma_buf_sgt_map_attachment() is split out after the
WARN_ON(!attach || !attach->dmabuf) check, dma_buf_unmap_attachment()
(later renamed to dma_buf_sgt_unmap_attachment() in "treewide: Rename
dma_buf_unmap_attachment(_unlocked) to dma_buf_sgt_*") keeps the
dma_buf_get_sgt_ops(attach) call before WARN_ON(!attach || ...).

Should sgt_exp_ops be initialized after the !attach check in both
functions?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261026053623.202642-1-apopple@nvidia.com?part=4

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH 05/26] dma-buf: Let the exporter select mapping type at pin/map
  2026-10-26  5:35 ` [PATCH 05/26] dma-buf: Let the exporter select mapping type at pin/map Alistair Popple
@ 2026-10-26  7:39   ` sashiko-bot
  2026-10-26  8:03   ` Karl Mehltretter
  1 sibling, 0 replies; 71+ messages in thread
From: sashiko-bot @ 2026-10-26  7:39 UTC (permalink / raw)
  To: Alistair Popple, dri-devel; +Cc: intel-xe, linux-rdma, media-ci

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] dma-buf: dma_buf_map_attachment() clears preexisting attach->selected on error
- [Medium] dma-buf: dma_buf_pin() leaves attach->selected true when ops->pin() fails
--

commit e1080028468cc11821bdd6c9ecd4fc7204151523
Author: Alistair Popple <apopple@nvidia.com>

dma-buf: Let the exporter select mapping type at pin/map

This commit adds dma_buf_ops.select_mapping() so the exporter can select a
mapping type from attach->matches when an attachment is first pinned or
mapped, recording the choice in attach->selected until mappings are
invalidated via dma_buf_invalidate_mappings().

> diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c
> index 348b47f266b48..03f06c4b957ca 100644
> --- a/drivers/dma-buf/dma-buf.c
> +++ b/drivers/dma-buf/dma-buf.c
> @@ -1201,6 +1201,10 @@ int dma_buf_pin(struct dma_buf_attachment *attach)
>  
>  	dma_resv_assert_held(dmabuf->resv);
>  
> +	ret = dma_buf_mapping_select(attach);
> +	if (ret)
> +		return ret;
> +
>  	if (dmabuf->ops->pin)
>  		ret = dmabuf->ops->pin(attach);
>  

[Severity: Medium]
Should dma_buf_pin() reset attach->selected to false if dmabuf->ops->pin()
fails when attach->selected was false upon entry?

When dma_buf_pin() is called on an unselected attachment,
dma_buf_mapping_select() sets attach->map_type and attach->selected = true:

drivers/dma-buf/dma-buf-mapping.c:dma_buf_mapping_select() {
	...
	attach->map_type = *match;
	attach->selected = true;
	return 0;
}

If dmabuf->ops->pin(attach) subsequently returns an error, dma_buf_pin()
returns that error while leaving attach->selected set to true even though the
pin was not established. Because the attachment is not pinned, the exporter
may migrate the buffer elsewhere without invalidating it (and for attachments
without importer_ops->invalidate_mappings, dma_buf_invalidate_mappings()
skips clearing attach->selected). A later retry of dma_buf_pin() or call to
dma_buf_map_attachment() will see attach->selected == true in
dma_buf_mapping_select() and skip dmabuf->ops->select_mapping(), leaving a
stale attach->map_type in place.

[ ... ]

> @@ -1324,6 +1305,52 @@ struct sg_table *dma_buf_map_attachment(struct dma_buf_attachment *attach,
>  
>  	return sg_table;
>  }
> +

[ ... ]

> +struct sg_table *dma_buf_map_attachment(struct dma_buf_attachment *attach,
> +					enum dma_data_direction direction)
> +{
> +	struct sg_table *sg_table;
> +	int ret;
> +
> +	might_sleep();
> +
> +	if (WARN_ON(!attach || !attach->dmabuf))
> +		return ERR_PTR(-EINVAL);
> +
> +	dma_resv_assert_held(attach->dmabuf->resv);
> +
> +	ret = dma_buf_mapping_select(attach);
> +	if (ret)
> +		return ERR_PTR(ret);
> +
> +	sg_table = __dma_buf_sgt_map_attachment(attach, direction);
> +	if (IS_ERR(sg_table))
> +		/* Nothing was established, so the choice may be made afresh */
> +		attach->selected = false;

[Severity: High]
What happens in dma_buf_map_attachment() if attach->selected was already true
prior to calling dma_buf_mapping_select() and __dma_buf_sgt_map_attachment()
fails?

An importer can enter dma_buf_map_attachment() with attach->selected == true
because the attachment was previously pinned via dma_buf_pin(), because it is
remapping after a prior map/unmap cycle without an intervening
dma_buf_invalidate_mappings(), or because another mapping on the same
attachment is already active. In that case, dma_buf_mapping_select() returns 0
immediately without making a new selection:

drivers/dma-buf/dma-buf-mapping.c:dma_buf_mapping_select() {
	...
	if (attach->selected)
		return 0;
	...
}

If __dma_buf_sgt_map_attachment() then fails (for example, sgt_exp_ops is
NULL, map_dma_buf() or dma_buf_wrap_sg_table() returns -ENOMEM, or
dma_resv_wait_timeout() is interrupted), dma_buf_map_attachment()
unconditionally clears attach->selected = false.

A subsequent dma_buf_map_attachment() or dma_buf_pin() call will then invoke
dmabuf->ops->select_mapping(attach) again without
dma_buf_invalidate_mappings() having been delivered, which can overwrite
attach->map_type while the attachment is still pinned or while an earlier
mapping is still active. When that earlier mapping is later unmapped in
dma_buf_unmap_attachment():

drivers/dma-buf/dma-buf.c:dma_buf_unmap_attachment() {
	const struct dma_buf_mapping_sgt_exp_ops *sgt_exp_ops =
		dma_buf_get_sgt_ops(attach);
	...
	if (WARN_ON(!attach || !attach->dmabuf || !sg_table || !sgt_exp_ops))
		return;
	...
	dma_buf_unwrap_sg_table(&sg_table);
	sgt_exp_ops->unmap_dma_buf(attach, sg_table, direction);
}

 wouldn't dma_buf_get_sgt_ops(attach) read the overwritten attach->map_type
and either call the wrong unmap_dma_buf() callback or hit
WARN_ON(!sgt_exp_ops) and leak the mapping?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261026053623.202642-1-apopple@nvidia.com?part=5

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH 06/26] dma-buf: Add match set queries for exporter placement decisions
  2026-10-26  5:35 ` [PATCH 06/26] dma-buf: Add match set queries for exporter placement decisions Alistair Popple
@ 2026-10-26  7:42   ` sashiko-bot
  0 siblings, 0 replies; 71+ messages in thread
From: sashiko-bot @ 2026-10-26  7:42 UTC (permalink / raw)
  To: Alistair Popple; +Cc: linux-rdma

> Exporters deciding placement in their pin path walk every attachment
> to determine whether it can take P2P. With selection deferred to pin or
> map an unmapped attachment only holds the exporter's default. Therefore
> determining what is possible requires walking attachments.
> 
> Add dma_buf_attach_accepts() and dma_buf_attach_accepts_sgt_p2p() to
> walk the match set and determine if an attachment is possible with P2P.
> A future series will convert P2P into a distinct match type.
> 
> Assisted-by: LLM
> Signed-off-by: Alistair Popple <apopple@nvidia.com>

Sashiko has reviewed this patch and found no issues.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261026053623.202642-1-apopple@nvidia.com?part=6


^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH 07/26] dma-buf: Add dma_buf_mapping_map() returning a type-tagged mapping
  2026-10-26  5:35 ` [PATCH 07/26] dma-buf: Add dma_buf_mapping_map() returning a type-tagged mapping Alistair Popple
@ 2026-10-26  7:56   ` sashiko-bot
  0 siblings, 0 replies; 71+ messages in thread
From: sashiko-bot @ 2026-10-26  7:56 UTC (permalink / raw)
  To: Alistair Popple, dri-devel; +Cc: intel-xe, linux-rdma, media-ci

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] dma-buf: do not clear prior attach->selected on error in dma_buf_mapping_map()
--

commit 03dc2c734a4965633dec9f21493634bacf3d9de7
Author: Alistair Popple <apopple@nvidia.com>

dma-buf: Add dma_buf_mapping_map() returning a type-tagged mapping

This commit introduces dma_buf_mapping_map() and dma_buf_mapping_unmap() so
importers supporting multiple mapping types can let the exporter select the
mapping type at map time and receive a type-tagged struct dma_buf_mapping. It
also wires up the SGT mapping type to these new operations via struct
dma_buf_sgt_mapping and dma_buf_sgt_mapping_table().

> diff --git a/drivers/dma-buf/dma-buf-mapping.c b/drivers/dma-buf/dma-buf-mapping.c
> index dbcd83b6dcff7..7a5a379a372e7 100644
> --- a/drivers/dma-buf/dma-buf-mapping.c
> +++ b/drivers/dma-buf/dma-buf-mapping.c
> @@ -366,6 +366,79 @@ int dma_buf_mapping_select(struct dma_buf_attachment *attach)
>  	return 0;
>  }
>  
> +/**
> + * dma_buf_mapping_map - Map an attachment with whichever type the exporter
> + *                       selects
> + * @attach: the attachment
> + * @dir: DMA direction
> + *
> + * For importers that listed more than one mapping type. The exporter picks the
> + * type from the possible matches and the result's &dma_buf_mapping.type records
> + * which was used. Must be called with the dma_resv lock held, and the lock must
> + * be held until the result has been acted on. Importers that listed a single
> + * type keep using that type's map function.
> + *
> + * Returns: a &struct dma_buf_mapping to pass to dma_buf_mapping_unmap(), or
> + * an ERR_PTR.
> + */
> +struct dma_buf_mapping *dma_buf_mapping_map(struct dma_buf_attachment *attach,
> +					    enum dma_data_direction dir)
> +{
> +	struct dma_buf_mapping *mapping;
> +	int ret;
> +
> +	might_sleep();
> +
> +	if (WARN_ON(!attach || !attach->dmabuf))
> +		return ERR_PTR(-EINVAL);
> +
> +	dma_resv_assert_held(attach->dmabuf->resv);
> +
> +	ret = dma_buf_mapping_select(attach);
> +	if (ret)
> +		return ERR_PTR(ret);
> +
> +	if (!attach->map_type.type->map) {
> +		ret = -EOPNOTSUPP;
> +		goto err_release;
> +	}
> +
> +	mapping = attach->map_type.type->map(attach, dir);
> +	if (IS_ERR(mapping)) {
> +		ret = PTR_ERR(mapping);
> +		goto err_release;
> +	}
> +
> +	return mapping;
> +
> +err_release:
> +	/* Nothing was established, so the choice may be made afresh */
> +	attach->selected = false;
> +	return ERR_PTR(ret);
> +}

[Severity: Medium]
Can jumping to err_release in dma_buf_mapping_map() corrupt an already
established selection state on attach?

If attach->selected is already true when dma_buf_mapping_map() is entered
(for instance, after dma_buf_pin(), after a prior map/unmap cycle without an
intervening dma_buf_invalidate_mappings(), or while another mapping on the
same attachment is still active), dma_buf_mapping_select() returns 0 without
making a new choice:

drivers/dma-buf/dma-buf-mapping.c:dma_buf_mapping_select() {
	if (attach->selected)
		return 0;
	...
	attach->map_type = *match;
	attach->selected = true;
	return 0;
}

If the subsequent map operation fails (such as kzalloc_obj() returning NULL
in dma_buf_sgt_type_map(), or sgt_exp_ops->map_dma_buf() failing in
__dma_buf_sgt_map_attachment()), err_release unconditionally sets
attach->selected = false.

A later call to dma_buf_mapping_select() can then invoke
dmabuf->ops->select_mapping(attach) again and overwrite attach->map_type
while the buffer is still pinned or has an active mapping. If an earlier SGT
mapping is still active and attach->map_type is changed to a non-SGT type,
unmapping that earlier mapping via:

dma_buf_mapping_unmap()
  -> dma_buf_sgt_type_unmap()
    -> dma_buf_unmap_attachment()

will find dma_buf_get_sgt_ops(attach) == NULL, trigger WARN_ON(!sgt_exp_ops),
and return early without unmapping or freeing mapping->sgt.

Additionally, when attach->selected was false on entry and
dma_buf_mapping_select() picked a match other than attach->matches[0],
clearing attach->selected on error leaves attach->map_type overwritten rather
than restored to attach->matches[0].

Should dma_buf_mapping_map() remember whether attach->selected was already
true before calling dma_buf_mapping_select(), and only reset attach->selected
(and restore attach->map_type) if this call actually performed the selection?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261026053623.202642-1-apopple@nvidia.com?part=7

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH 08/26] dma-buf: Allow single exporter drivers to avoid the match_mapping function
  2026-10-26  5:35 ` [PATCH 08/26] dma-buf: Allow single exporter drivers to avoid the match_mapping function Alistair Popple
@ 2026-10-26  7:58   ` sashiko-bot
  0 siblings, 0 replies; 71+ messages in thread
From: sashiko-bot @ 2026-10-26  7:58 UTC (permalink / raw)
  To: Alistair Popple; +Cc: linux-rdma

> From: Jason Gunthorpe <jgg@nvidia.com>
> 
> Introduce single_exporter_match into the dma_buf_ops so that single
> exporter drivers can simply set it using a static initializer to use the
> mapping type APIs. Provide a helper macro DMA_BUF_SIMPLE_SGT_EXP_MATCH()
> that generates the initializer for simple drivers that don't use P2P.
> 
> More complex exporters, especially those with P2P, need to implement the
> match_mapping call back to extract things like their DMA struct device
> from the dma_buf in order to do the P2P calculations.
> 
> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>

Sashiko has reviewed this patch and found no issues.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261026053623.202642-1-apopple@nvidia.com?part=8


^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH 09/26] drm: Check the SGT ops for drm_gem_map_dma_buf()
  2026-10-26  5:36 ` [PATCH 09/26] drm: Check the SGT ops for drm_gem_map_dma_buf() Alistair Popple
@ 2026-10-26  8:02   ` sashiko-bot
  0 siblings, 0 replies; 71+ messages in thread
From: sashiko-bot @ 2026-10-26  8:02 UTC (permalink / raw)
  To: Alistair Popple; +Cc: linux-rdma

> From: Jason Gunthorpe <jgg@nvidia.com>
> 
> When the next patch converts exporters to use SGT natively, the
> dma_buf->ops->map_dma_buf will become NULL. Additionally check
> sgt_exp_ops to see the new location.
> 
> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>

Sashiko has reviewed this patch and found no issues.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261026053623.202642-1-apopple@nvidia.com?part=9


^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH 05/26] dma-buf: Let the exporter select mapping type at pin/map
  2026-10-26  5:35 ` [PATCH 05/26] dma-buf: Let the exporter select mapping type at pin/map Alistair Popple
  2026-10-26  7:39   ` sashiko-bot
@ 2026-10-26  8:03   ` Karl Mehltretter
  2026-10-27  5:46     ` Alistair Popple
  1 sibling, 1 reply; 71+ messages in thread
From: Karl Mehltretter @ 2026-10-26  8:03 UTC (permalink / raw)
  To: Alistair Popple
  Cc: dri-devel, christian.koenig, sumit.semwal, jgg,
	Thomas Hellström, Simona Vetter, Matthew Brost,
	Vivek Kasireddy, Dongwon Kim, Leon Romanovsky, Kevin Tian,
	Xu Yilun, Baolu Lu, Felix Kuehling, Alex Deucher, intel-xe,
	amd-gfx, linux-media, linaro-mm-sig, linux-rdma, iommu,
	Alexey Kardashevskiy, zhipingz, treding, jhubbard

On Mon, Oct 26, 2026 at 04:35:56PM +0100, Alistair Popple wrote:
> +struct sg_table *dma_buf_map_attachment(struct dma_buf_attachment *attach,
> +					enum dma_data_direction direction)
> +{
> +	struct sg_table *sg_table;
> +	int ret;
> +
> +	might_sleep();
> +
> +	if (WARN_ON(!attach || !attach->dmabuf))
> +		return ERR_PTR(-EINVAL);
> +
> +	dma_resv_assert_held(attach->dmabuf->resv);
> +
> +	ret = dma_buf_mapping_select(attach);
> +	if (ret)
> +		return ERR_PTR(ret);
> +
> +	sg_table = __dma_buf_sgt_map_attachment(attach, direction);
> +	if (IS_ERR(sg_table))
> +		/* Nothing was established, so the choice may be made afresh */
> +		attach->selected = false;
> +
> +	return sg_table;
> +}

The map-failure report from Sashiko [1] reproduces with a KUnit test
against the full series:

  pin selects B -> map returns -EIO -> selected is cleared
                -> retry selects A, with the original pin still held

The exporter pin count stays at 1. Preserving selected when it was true
on entry makes the test pass. Patch 7 needs the same fix.

Could dma_buf_mapping_select() report whether it made a new selection?
Then the error path could undo only that choice, without dropping one
established by an earlier pin or map.

On the Sashiko failed-pin report:
("Because the attachment is not pinned, the exporter may migrate the
buffer elsewhere without invalidating it")

I don't think this follows from the documented contract.
select_mapping() requires the exporter to keep the recorded type
servable and invalidate before an incompatible move. That obligation
still applies if ops->pin() fails.

Is retaining the selection after a failed pin intentional? If so, this
can be added as a test documenting that alongside the map-failure
regression test.

Thanks,
Karl

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH 10/26] dma-buf: Convert all the simple exporters to use SGT mapping type
  2026-10-26  5:36 ` [PATCH 10/26] dma-buf: Convert all the simple exporters to use SGT mapping type Alistair Popple
@ 2026-10-26  8:12   ` sashiko-bot
  0 siblings, 0 replies; 71+ messages in thread
From: sashiko-bot @ 2026-10-26  8:12 UTC (permalink / raw)
  To: Alistair Popple; +Cc: linux-rdma

> From: Jason Gunthorpe <jgg@nvidia.com>
> 
> Update the exporters to use a SGT mapping type and the new style mapping
> type API. None of these exporters do anything with attach->peer2peer or
> importer_ops->allow_peer2peer and they all follow the same pattern.
> 
> Change all the places that need to get the SGT's DMA device for DMA API
> use to use dma_buf_sgt_dma_device().
> 
> This is all a mechanical change of moving the map_dma_buf/unmap_dma_buf
> into DMA_BUF_SIMPLE_SGT_EXP_MATCH() arguments and switching
> attach->dev to dma_buf_sgt_dma_device(attach).
> 
> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
> [ added converters for newly added amdxdna, panfrost and panthor exporters - apopple ]
> Signed-off-by: Alistair Popple <apopple@nvidia.com>

Sashiko has reviewed this patch and found no issues.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261026053623.202642-1-apopple@nvidia.com?part=10


^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH 11/26] drm/vmwgfx: Use match_mapping instead of dummy calls
  2026-10-26  5:36 ` [PATCH 11/26] drm/vmwgfx: Use match_mapping instead of dummy calls Alistair Popple
@ 2026-10-26  8:13   ` sashiko-bot
  0 siblings, 0 replies; 71+ messages in thread
From: sashiko-bot @ 2026-10-26  8:13 UTC (permalink / raw)
  To: Alistair Popple; +Cc: linux-rdma

> From: Jason Gunthorpe <jgg@nvidia.com>
> 
> vmwgfx is creating a DMA-buf that cannot be attached by providing
> always fail functions for dma_buf_ops.
> 
> The attach/detach callbacks are already optional inside DMA-buf, but
> dma_buf_export() is checking for non-null map/unmap callbacks.
> 
> Instead use the mapping type interface and provide an always fail
> match_mapping(). Remove the unused SGT and attach/detach functions, they
> can never be called if match_mapping() fails.
> 
> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>

Sashiko has reviewed this patch and found no issues.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261026053623.202642-1-apopple@nvidia.com?part=11


^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH 12/26] accel/habanalabs: Use the SGT_P2P mapping type
  2026-10-26  5:36 ` [PATCH 12/26] accel/habanalabs: Use the SGT_P2P mapping type Alistair Popple
@ 2026-10-26  8:18   ` sashiko-bot
  0 siblings, 0 replies; 71+ messages in thread
From: sashiko-bot @ 2026-10-26  8:18 UTC (permalink / raw)
  To: Alistair Popple; +Cc: linux-rdma

> From: Jason Gunthorpe <jgg@nvidia.com>
> 
> habana has special code to check pci_p2pdma_distance() and rejects any
> importer that cannot do P2P DMA to its MMIO.
> 
> Convert this directly to a SGT_P2P match which does the same check
> inside the matching logic.
> 
> Someday this should be converted to use dma_buf_phys_vec_to_sgt() which
> does the P2P checking correctly, for both direct and IOMMU based cases,
> instead of this hack.
> 
> Remove the now empty attach function.
> 
> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>

Sashiko has reviewed this patch and found no issues.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261026053623.202642-1-apopple@nvidia.com?part=12


^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH 13/26] drm/xe/dma-buf: Use the SGT mapping type
  2026-10-26  5:36 ` [PATCH 13/26] drm/xe/dma-buf: Use the SGT " Alistair Popple
@ 2026-10-26  8:34   ` sashiko-bot
  0 siblings, 0 replies; 71+ messages in thread
From: sashiko-bot @ 2026-10-26  8:34 UTC (permalink / raw)
  To: Alistair Popple, dri-devel; +Cc: intel-xe, linux-rdma, media-ci

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [Medium] drm/xe/dma-buf: xe_dma_buf_match_mapping() changes attach error to -EINVAL
- [Medium] drm/xe: verbose pci_p2pdma_distance() check in xe_dma_buf_match_mapping()
--

commit d3c9a19b80db02efc0ef1143d9205eb0a3c2194e
Author: Jason Gunthorpe <jgg@ziepe.ca>

drm/xe/dma-buf: Use the SGT mapping type

This commit converts the Xe dma-buf exporter to use the new SGT mapping type
infrastructure by providing P2P and non-P2P SGT exporter matches in
xe_dma_buf_match_mapping() and querying attachment mapping helpers during pin,
map, and unmap.

> diff --git a/drivers/gpu/drm/xe/xe_dma_buf.c b/drivers/gpu/drm/xe/xe_dma_buf.c
> index bf0728838ead5..3ca198da6ee87 100644
> --- a/drivers/gpu/drm/xe/xe_dma_buf.c
> +++ b/drivers/gpu/drm/xe/xe_dma_buf.c
> @@ -27,13 +27,6 @@ static int xe_dma_buf_attach(struct dma_buf *dmabuf,
>  {
>  	struct drm_gem_object *obj = attach->dmabuf->priv;
>  
> -	if (attach->peer2peer &&
> -	    pci_p2pdma_distance(to_pci_dev(obj->dev->dev), attach->dev, false) < 0)
> -		attach->peer2peer = false;
> -
> -	if (!attach->peer2peer && !xe_bo_can_migrate(gem_to_xe_bo(obj), XE_PL_TT))
> -		return -EOPNOTSUPP;
> -
>  	xe_pm_runtime_get(to_xe_device(obj->dev));
>  	return 0;
>  }

[ ... ]

> @@ -205,18 +205,38 @@ static void xe_dma_buf_release(struct dma_buf *dmabuf)
>  	drm_gem_dmabuf_release(dmabuf);
>  }
>  
> +static const struct dma_buf_mapping_sgt_exp_ops xe_dma_buf_sgt_ops = {
> +	.map_dma_buf = xe_dma_buf_map,
> +	.unmap_dma_buf = xe_dma_buf_unmap,
> +};
> +
> +static int xe_dma_buf_match_mapping(struct dma_buf_match_args *args)
> +{
> +	struct drm_gem_object *obj = args->dmabuf->priv;
> +	struct dma_buf_mapping_match sgt_match[2];
> +	unsigned int num_match = 0;
> +
> +	sgt_match[num_match++] = DMA_BUF_EMAPPING_SGT_P2P(
> +		&xe_dma_buf_sgt_ops, to_pci_dev(obj->dev->dev));

[Severity: Medium]
Will offering DMA_BUF_EMAPPING_SGT_P2P() unconditionally first cause spurious
pci_warn() and dev_warn() messages in dmesg when attaching migratable or
system-memory-only BOs on systems without PCIe P2P support?

Previously, xe_dma_buf_attach() called pci_p2pdma_distance() with verbose set
to false because P2P is optional when a BO resides in or can migrate to
XE_PL_TT (similar to commit d0fa84f17477 ("drm/amdgpu: Disable verbose for p2p
dist calc")).

With this change, dma_buf_match_mapping() evaluates sgt_match[0] first via
dma_buf_sgt_match(), which calls pci_p2pdma_distance() with verbose set to
true:

drivers/dma-buf/dma-buf-mapping.c:dma_buf_sgt_match() {
	if (exp->sgt_data.exporter_requires_p2p ==
	    DMA_SGT_EXPORTER_REQUIRES_P2P_DISTANCE) {
		if (!imp->sgt_data.importer_allows_p2p)
			return -EOPNOTSUPP;
		if (pci_p2pdma_distance(exp->sgt_data.exporting_p2p_device,
					imp->sgt_data.importing_dma_device,
					true) < 0)
			return -EOPNOTSUPP;
	}
}

Whenever a P2P-capable importer attaches to an exported Xe dma-buf on a
platform where P2P is unavailable (such as a non-PCI importer, non-whitelisted
host bridge, or ACS redirect on PCIe switches), calc_map_type_and_dist() will
log a warning even though sgt_match[1] (DMA_BUF_EMAPPING_SGT) immediately
succeeds using system memory, or even when the BO was created as
system-memory-only.

> +
> +	if (xe_bo_can_migrate(gem_to_xe_bo(obj), XE_PL_TT))
> +		sgt_match[num_match++] =
> +			DMA_BUF_EMAPPING_SGT(&xe_dma_buf_sgt_ops);
> +
> +	return dma_buf_match_mapping(args, sgt_match, num_match);
> +}

[Severity: Medium]
Does replacing the check in xe_dma_buf_attach() with dma_buf_match_mapping()
change the attach error code from -EOPNOTSUPP to -EINVAL and break the Xe
dma-buf KUnit test suite?

When exporting a non-migratable VRAM-only BO (where xe_bo_can_migrate(bo,
XE_PL_TT) is false) and attaching or importing it from an importer that does
not support P2P (or where pci_p2pdma_distance() < 0), xe_dma_buf_attach()
previously returned -EOPNOTSUPP.

Now, xe_dma_buf_match_mapping() only populates sgt_match[0] with
DMA_BUF_EMAPPING_SGT_P2P() and calls dma_buf_match_mapping(). In
drivers/dma-buf/dma-buf-mapping.c:dma_buf_match_mapping(), -EOPNOTSUPP from
exp->type->match() is skipped, and -EINVAL is returned when no matches remain:

drivers/dma-buf/dma-buf-mapping.c:dma_buf_match_mapping() {
			if (exp->type->match) {
				ret = exp->type->match(args->dmabuf, exp, imp);
				if (ret == -EOPNOTSUPP)
					continue;
				if (ret != 0)
					return ret;
			}
...
	if (!nr)
		return -EINVAL;
}

In drivers/gpu/drm/xe/tests/xe_dma_buf.c:xe_test_dmabuf_import_same_driver(),
the KUnit test explicitly checks for -EOPNOTSUPP on import failure of a
non-migratable VRAM BO without P2P:

	} else if (PTR_ERR(import) != -EOPNOTSUPP) {
		/* Unexpected error code. */
		KUNIT_FAIL(test,
			   "xe_gem_prime_import failed with the wrong err=%ld\n",
			   PTR_ERR(import));

Should this path still return -EOPNOTSUPP when no mapping matches?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261026053623.202642-1-apopple@nvidia.com?part=13

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH 14/26] drm/amdgpu: Use the SGT mapping type
  2026-10-26  5:36 ` [PATCH 14/26] drm/amdgpu: " Alistair Popple
@ 2026-10-26  8:46   ` sashiko-bot
  0 siblings, 0 replies; 71+ messages in thread
From: sashiko-bot @ 2026-10-26  8:46 UTC (permalink / raw)
  To: Alistair Popple; +Cc: linux-rdma

> From: Jason Gunthorpe <jgg@nvidia.com>
> 
> Similar to xe, amdgpu wants to check pci_p2pdma_distance(), and
> only needs that if peer2peer can be supported by the GPU. It can migrate to
> system memory and support non-p2p DMA as well.
> 
> Further it supports a private non-PCI XGMI path. For now hack this on top
> of a SGT type, but eventually this is likely better off as its own mapping
> type.
> 
> Add two exporter SGT mapping types, one that matches P2P and one that
> matches all of the non-p2p. The pin and map code will force migrate if
> the non-p2p one is matched.
> 
> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
> [ the match set is recorded in attach->matches and the type
>   selected from it at pin or map, so the pin walk, detach and the attach
>   error path ask dma_buf_attach_accepts_sgt_p2p() whether an attachment
>   could take P2P at all, and the XGMI override rewrites the recorded match
>   set entry rather than only attach->map_type. The map path keeps using
>   dma_buf_sgt_p2p_allowed() for the attachment being mapped, which has just
>   been selected. The runtime PM reference follows the same question: held
>   while P2P is in the match set, dropped in detach. - apopple ]
> Signed-off-by: Alistair Popple <apopple@nvidia.com>

Sashiko has reviewed this patch and found no issues.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261026053623.202642-1-apopple@nvidia.com?part=14


^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH 15/26] vfio/pci: Change the DMA-buf exporter to use mapping_type
  2026-10-26  5:36 ` [PATCH 15/26] vfio/pci: Change the DMA-buf exporter to use mapping_type Alistair Popple
@ 2026-10-26  9:00   ` sashiko-bot
  0 siblings, 0 replies; 71+ messages in thread
From: sashiko-bot @ 2026-10-26  9:00 UTC (permalink / raw)
  To: Alistair Popple, dri-devel; +Cc: intel-xe, linux-rdma, media-ci

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] vfio/pci: vfio_pci_dma_buf_match_mapping() breaks iopt_map_dmabuf() attach
- [High] vfio/pci: UAF on pdev->p2pdma in vfio_pci_dma_buf_match_mapping()
--

commit 9770a3eb805c4984c35cbfef83d18657c914f9b0
Author: Jason Gunthorpe <jgg@ziepe.ca>

vfio/pci: Change the DMA-buf exporter to use mapping_type

This commit converts the VFIO PCI DMA-buf exporter to implement a
match_mapping() callback offering an SGT P2P mapping type and replaces the
attachment->peer2peer check in vfio_pci_dma_buf_attach(). It also holds a
pci_dev reference in struct vfio_pci_dma_buf for the lifetime of the
dma-buf to pass to DMA_BUF_EMAPPING_SGT_P2P().

> diff --git a/drivers/vfio/pci/vfio_pci_dmabuf.c b/drivers/vfio/pci/vfio_pci_dmabuf.c
> index c16f460c01d68..58e771309c5f6 100644
> --- a/drivers/vfio/pci/vfio_pci_dmabuf.c
> +++ b/drivers/vfio/pci/vfio_pci_dmabuf.c

[ ... ]

> @@ -95,15 +93,31 @@ static void vfio_pci_dma_buf_release(struct dma_buf *dmabuf)
>  		up_write(&priv->vdev->memory_lock);
>  		vfio_device_put_registration(&priv->vdev->vdev);
>  	}
> +	pci_dev_put(priv->pdev);
>  	kfree(priv->phys_vec);
>  	kfree(priv);
>  }
>  
> -static const struct dma_buf_ops vfio_pci_dmabuf_ops = {
> -	.attach = vfio_pci_dma_buf_attach,
> +static const struct dma_buf_mapping_sgt_exp_ops vfio_pci_dma_buf_sgt_ops = {
>  	.map_dma_buf = vfio_pci_dma_buf_map,
>  	.unmap_dma_buf = vfio_pci_dma_buf_unmap,
> +};
> +
> +static int vfio_pci_dma_buf_match_mapping(struct dma_buf_match_args *args)
> +{
> +	struct vfio_pci_dma_buf *priv = args->dmabuf->priv;
> +	struct dma_buf_mapping_match sgt_match[1];
> +
> +	sgt_match[0] = DMA_BUF_EMAPPING_SGT_P2P(&vfio_pci_dma_buf_sgt_ops,
> +						priv->pdev);

[Severity: High]
Does offering only DMA_BUF_EMAPPING_SGT_P2P() here break iommufd mapping of
VFIO PCI dma-bufs via iopt_map_dmabuf()?

When userspace maps a VFIO PCI dma-buf through iommufd, iopt_map_dmabuf()
in drivers/iommu/iommufd/pages.c attaches using iommufd_global_device()
before calling sym_vfio_pci_dma_buf_iommufd_map():

drivers/iommu/iommufd/pages.c:iopt_map_dmabuf()
	attach = dma_buf_dynamic_attach(dmabuf, iommufd_global_device(),
					&iopt_dmabuf_attach_revoke_ops, pages);
	if (IS_ERR(attach))
		return PTR_ERR(attach);
	...
	rc = sym_vfio_pci_dma_buf_iommufd_map(attach, &pages->dmabuf.phys);

where iommufd_global_device() in drivers/iommu/iommufd/main.c returns
iommu_misc_dev.this_device, a miscdevice with no parent pci_dev.

With DMA_BUF_EMAPPING_SGT_P2P(), dma_buf_dynamic_attach() runs:

  dma_buf_mapping_attach()
    -> vfio_pci_dma_buf_match_mapping()
      -> dma_buf_match_mapping()
        -> dma_buf_sgt_match()
          -> pci_p2pdma_distance(priv->pdev, iommufd_global_device(), true)
            -> pci_p2pdma_distance_many()

In drivers/pci/p2pdma.c:pci_p2pdma_distance_many(), find_parent_pci_dev()
returns NULL for iommufd_global_device():

	for (i = 0; i < num_clients; i++) {
		pci_client = find_parent_pci_dev(clients[i]);
		if (!pci_client) {
			if (verbose)
				dev_warn(clients[i],
					 "cannot be used for peer-to-peer DMA as it is not a PCI device\n");
			return -1;
		}

This emits a dev_warn() and returns -1, causing dma_buf_sgt_match() to
return -EOPNOTSUPP and dma_buf_match_mapping() to fail with -EINVAL before
sym_vfio_pci_dma_buf_iommufd_map() can be reached.

> +
> +	return dma_buf_match_mapping(args, sgt_match, ARRAY_SIZE(sgt_match));
> +}

[Severity: High]
Can passing priv->pdev to DMA_BUF_EMAPPING_SGT_P2P() in
vfio_pci_dma_buf_match_mapping() race with driver unbind and trigger a
use-after-free on pdev->p2pdma?

When the VFIO device is closed while the exported dma-buf fd remains open,
vfio_pci_dma_buf_cleanup() revokes the dma-buf and drops the vfio_device
registration reference:

drivers/vfio/pci/vfio_pci_dmabuf.c:vfio_pci_dma_buf_cleanup()
	list_for_each_entry_safe(priv, tmp, &vdev->dmabufs, dmabufs_elm) {
		if (!get_file_active(&priv->dmabuf->file))
			continue;

		list_del_init(&priv->dmabufs_elm);
		priv->vdev = NULL;
		vfio_device_put_registration(&vdev->vdev);
		fput(priv->dmabuf->file);
	}

Once vfio_device_put_registration() drops that reference, nothing pins the
driver binding on priv->pdev (pci_dev_get() only pins struct pci_dev, not
devres). Unbinding vfio-pci runs devres_release_all(), which invokes
pci_p2pdma_release() and frees the devm_kzalloc()-allocated struct
pci_p2pdma:

drivers/pci/p2pdma.c:pci_p2pdma_release()
	/* Flush and disable pci_alloc_p2p_mem() */
	pdev->p2pdma = NULL;
	if (p2pdma->pool)
		synchronize_rcu();
	xa_destroy(&p2pdma->map_types);

Because vfio_pci_core_init_dev() only calls pcim_p2pdma_init() and never
allocates p2pdma->pool via pci_p2pdma_add_resource(), p2pdma->pool is NULL.
As a result, pci_p2pdma_release() skips synchronize_rcu(), immediately
calls xa_destroy(&p2pdma->map_types), and devres frees p2pdma.

Concurrently, if an importer attaches to the open dma-buf fd,
dma_buf_mapping_attach() calls vfio_pci_dma_buf_match_mapping() before
vfio_pci_dma_buf_attach() checks priv->revoked:

  dma_buf_mapping_attach()
    -> vfio_pci_dma_buf_match_mapping()
      -> dma_buf_match_mapping()
        -> dma_buf_sgt_match()
          -> pci_p2pdma_distance()
            -> pci_p2pdma_distance_many()
              -> calc_map_type_and_dist()

In drivers/pci/p2pdma.c:calc_map_type_and_dist():

	rcu_read_lock();
	p2pdma = rcu_dereference(provider->p2pdma);
	if (p2pdma)
		xa_store(&p2pdma->map_types, map_types_idx(client),
			 xa_mk_value(map_type), GFP_ATOMIC);
	rcu_read_unlock();

Without synchronize_rcu() in pci_p2pdma_release(), calc_map_type_and_dist()
can load a non-NULL p2pdma pointer just before pdev->p2pdma is cleared and
call xa_store(&p2pdma->map_types, ...) concurrently with xa_destroy() and
after p2pdma has been freed by devres.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261026053623.202642-1-apopple@nvidia.com?part=15

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH 16/26] RDMA/uverbs: Use the SGT_P2P mapping type
  2026-10-26  5:36 ` [PATCH 16/26] RDMA/uverbs: Use the SGT_P2P mapping type Alistair Popple
@ 2026-10-26  9:16   ` sashiko-bot
  0 siblings, 0 replies; 71+ messages in thread
From: sashiko-bot @ 2026-10-26  9:16 UTC (permalink / raw)
  To: Alistair Popple, dri-devel; +Cc: intel-xe, linux-rdma, media-ci

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] RDMA/uverbs: use-after-free in uverbs_dmabuf_match_mapping() after unbind
--

commit 573a52ef0d548646c203780dd26bd3aa8dbc3284
Author: Jason Gunthorpe <jgg@ziepe.ca>

RDMA/uverbs: Use the SGT_P2P mapping type

This commit converts the RDMA uverbs dma-buf exporter to use the SGT_P2P
mapping type via uverbs_dmabuf_match_mapping() and removes the
uverbs_dmabuf_attach() callback.

> diff --git a/drivers/infiniband/core/uverbs_std_types_dmabuf.c b/drivers/infiniband/core/uverbs_std_types_dmabuf.c
> index 2411ebee69e2d..3c5c3ea2cf556 100644
> --- a/drivers/infiniband/core/uverbs_std_types_dmabuf.c
> +++ b/drivers/infiniband/core/uverbs_std_types_dmabuf.c

[ ... ]

> @@ -76,13 +67,30 @@ static void uverbs_dmabuf_release(struct dma_buf *dmabuf)
>  	uverbs_uobject_release(&priv->uobj);
>  }
>  
> -static const struct dma_buf_ops uverbs_dmabuf_ops = {
> -	.attach = uverbs_dmabuf_attach,
> +static const struct dma_buf_mapping_sgt_exp_ops uverbs_dma_buf_sgt_ops = {
>  	.map_dma_buf = uverbs_dmabuf_map,
>  	.unmap_dma_buf = uverbs_dmabuf_unmap,
> +};
> +
> +static int uverbs_dmabuf_match_mapping(struct dma_buf_match_args *args)
> +{
> +	struct ib_uverbs_dmabuf_file *priv = args->dmabuf->priv;
> +	struct dma_buf_mapping_match sgt_match[1];
> +
> +	if (WARN_ON(!dev_is_pci(priv->provider->owner)))
> +		return -EINVAL;
> +
> +	sgt_match[0] = DMA_BUF_EMAPPING_SGT_P2P(
> +		&uverbs_dma_buf_sgt_ops, to_pci_dev(priv->provider->owner));
> +
> +	return dma_buf_match_mapping(args, sgt_match, ARRAY_SIZE(sgt_match));
> +}

[Severity: High]
Can uverbs_dmabuf_match_mapping() cause a use-after-free of priv->provider
and priv->provider->owner if an importer attaches to the dma-buf after the
exporting PCI/RDMA driver unbinds or the PCI device is removed?

During UVERBS_METHOD_DMABUF_ALLOC, priv->provider is populated via
ib_dev->ops.mmap_get_pfns() -> mlx5_ib_mmap_get_pfns() ->
pcim_p2pdma_provider():

drivers/pci/p2pdma.c:pcim_p2pdma_provider() {
	...
	p2p = rcu_dereference_protected(pdev->p2pdma, 1);
	if (WARN_ON(!p2p))
		/* Someone forgot to call to pcim_p2pdma_init() before */
		return NULL;

	return &p2p->mem[bar];
}

Because struct pci_p2pdma is allocated with devm_kzalloc(&pdev->dev, ...) in
pcim_p2pdma_init(), its lifetime is tied to the PCI driver binding rather
than the exported dma-buf file.

When the driver is unbound or hot-unplugged while userspace still holds the
dma-buf fd open, ib_uverbs_remove_one() calls ib_uverbs_free_hw_resources()
-> uverbs_destroy_ufile_hw() -> uverbs_dmabuf_fd_destroy_uobj():

drivers/infiniband/core/uverbs_std_types_dmabuf.c:uverbs_dmabuf_fd_destroy_uobj() {
	...
	dma_resv_lock(uverbs_dmabuf->dmabuf->resv, NULL);
	if (!uverbs_dmabuf->revoked) {
		uverbs_dmabuf->revoked = true;
		list_del(&uverbs_dmabuf->dmabufs_elm);
		dma_buf_invalidate_mappings(uverbs_dmabuf->dmabuf);
		dma_resv_wait_timeout(uverbs_dmabuf->dmabuf->resv,
				      DMA_RESV_USAGE_BOOKKEEP, false,
				      MAX_SCHEDULE_TIMEOUT);
		wait_for_comp = true;
	}
	dma_resv_unlock(uverbs_dmabuf->dmabuf->resv);
	...
}

After revoking and waiting for active mappings to unmap,
ib_uverbs_remove_one() sets wait_clients = 0 and returns without waiting for
open dma-buf fds to close. Once the PCI driver remove completes, devres frees
struct pci_p2pdma (leaving priv->provider dangling), and if the PCI device is
removed, struct pci_dev (priv->provider->owner) can also be freed since
struct ib_uverbs_dmabuf_file does not hold a pci_dev_get() reference.

Previously, uverbs_dmabuf_attach() only checked attachment->peer2peer, and
priv->provider was only accessed inside uverbs_dmabuf_map() under
dma_resv_lock() after checking !priv->revoked.

With this change, dma_buf_mapping_attach() invokes
uverbs_dmabuf_match_mapping() without holding dmabuf->resv or checking
priv->revoked, and unconditionally dereferences priv->provider->owner and
passes the pci_dev to dma_buf_match_mapping() -> dma_buf_sgt_match() ->
pci_p2pdma_distance().

Notice that commit 9770a3eb805c ("vfio/pci: Change the DMA-buf exporter to
use mapping_type") earlier in this series avoided this same issue in
vfio_pci_dmabuf.c by storing a reference-counted struct pci_dev pointer in
priv->pdev for the lifetime of the dma-buf and passing priv->pdev in
match_mapping(). Should uverbs_std_types_dmabuf.c similarly hold a reference
or synchronize against revocation here?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261026053623.202642-1-apopple@nvidia.com?part=16

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH 17/26] dma-buf: Update dma_buf_phys_vec_to_sgt() to use the SGT mapping type
  2026-10-26  5:36 ` [PATCH 17/26] dma-buf: Update dma_buf_phys_vec_to_sgt() to use the SGT " Alistair Popple
@ 2026-10-26  9:26   ` sashiko-bot
  0 siblings, 0 replies; 71+ messages in thread
From: sashiko-bot @ 2026-10-26  9:26 UTC (permalink / raw)
  To: Alistair Popple; +Cc: linux-rdma

> From: Jason Gunthorpe <jgg@nvidia.com>
> 
> These helpers only work when matched to a SGT mapping type, call
> dma_buf_sgt_dma_device() to get the DMA device.
> 
> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>

Sashiko has reviewed this patch and found no issues.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261026053623.202642-1-apopple@nvidia.com?part=17


^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH 18/26] iio: buffer: convert to use the SGT mapping type
  2026-10-26  5:36 ` [PATCH 18/26] iio: buffer: convert " Alistair Popple
@ 2026-10-26  9:28   ` sashiko-bot
  0 siblings, 0 replies; 71+ messages in thread
From: sashiko-bot @ 2026-10-26  9:28 UTC (permalink / raw)
  To: Alistair Popple; +Cc: linux-rdma

> From: Jason Gunthorpe <jgg@nvidia.com>
> 
> These importer helper functions should call dma_buf_sgt_dma_device() as
> they are always working with SGTs.
> 
> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>

Sashiko has reviewed this patch and found no issues.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261026053623.202642-1-apopple@nvidia.com?part=18


^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH 19/26] functionfs: convert to use the SGT mapping type
  2026-10-26  5:36 ` [PATCH 19/26] functionfs: " Alistair Popple
@ 2026-10-26  9:35   ` sashiko-bot
  0 siblings, 0 replies; 71+ messages in thread
From: sashiko-bot @ 2026-10-26  9:35 UTC (permalink / raw)
  To: Alistair Popple; +Cc: linux-rdma

> From: Jason Gunthorpe <jgg@nvidia.com>
> 
> These importer helper functions should call dma_buf_sgt_dma_device() as
> they are always working with SGTs.
> 
> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>

Sashiko has reviewed this patch and found no issues.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261026053623.202642-1-apopple@nvidia.com?part=19


^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH 20/26] dma-buf: Remove unused SGT stuff from the common structures
  2026-10-26  5:36 ` [PATCH 20/26] dma-buf: Remove unused SGT stuff from the common structures Alistair Popple
@ 2026-10-26  9:39   ` sashiko-bot
  0 siblings, 0 replies; 71+ messages in thread
From: sashiko-bot @ 2026-10-26  9:39 UTC (permalink / raw)
  To: Alistair Popple; +Cc: linux-rdma

> From: Jason Gunthorpe <jgg@nvidia.com>
> 
> Now that all exporters are converted these compatibility things can be
> removed:
> 
> dma_buf_ops: map_dma_buf/unmap_dma_buf
>              Moved to dma_buf_mapping_sgt_exp_ops
> 
> dma_buf_attachment: dev
> 		    Moved to attach->map_type.importing_dma_device
> 
> dma_buf_attachment: peer2peer
> 		    Moved to attach->map_type.exporter_requires_p2p
>                     accessed via dma_buf_sgt_p2p_allowed()
> 
> dma_buf_sgt_exp_compat_match: No compatibility exporters anymore
> 
> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
> [ use dma_buf_sgt_dma_device(attach) in dma_buf_detach trace point instead of attach->dev - apopple ]
> Signed-off-by: Alistair Popple <apopple@nvidia.com>

Sashiko has reviewed this patch and found no issues.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261026053623.202642-1-apopple@nvidia.com?part=20


^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH 21/26] treewide: Rename dma_buf_map_attachment(_unlocked) to dma_buf_sgt_
  2026-10-26  5:36 ` [PATCH 21/26] treewide: Rename dma_buf_map_attachment(_unlocked) to dma_buf_sgt_ Alistair Popple
@ 2026-10-26  9:49   ` sashiko-bot
  2026-10-27 12:05   ` Christian König
  1 sibling, 0 replies; 71+ messages in thread
From: sashiko-bot @ 2026-10-26  9:49 UTC (permalink / raw)
  To: Alistair Popple; +Cc: linux-rdma

> From: Jason Gunthorpe <jgg@nvidia.com>
> 
> This map function only works with SGT importers.
> 
> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
> [ also rename the io_uring zcrx caller, which the unmap rename
>   used to pick up, so that this commit builds with CONFIG_IO_URING_ZCRX - apopple ]
> Signed-off-by: Alistair Popple <apopple@nvidia.com>

Sashiko has reviewed this patch and found no issues.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261026053623.202642-1-apopple@nvidia.com?part=21


^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH 22/26] treewide: Rename dma_buf_unmap_attachment(_unlocked) to dma_buf_sgt_*
  2026-10-26  5:36 ` [PATCH 22/26] treewide: Rename dma_buf_unmap_attachment(_unlocked) to dma_buf_sgt_* Alistair Popple
@ 2026-10-26  9:56   ` sashiko-bot
  0 siblings, 0 replies; 71+ messages in thread
From: sashiko-bot @ 2026-10-26  9:56 UTC (permalink / raw)
  To: Alistair Popple; +Cc: linux-rdma

> From: Jason Gunthorpe <jgg@nvidia.com>
> 
> This unmap function only works with SGT importers.
> 
> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>

Sashiko has reviewed this patch and found no issues.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261026053623.202642-1-apopple@nvidia.com?part=22


^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH 23/26] treewide: Rename dma_buf_attach() to dma_buf_sgt_attach()
  2026-10-26  5:36 ` [PATCH 23/26] treewide: Rename dma_buf_attach() to dma_buf_sgt_attach() Alistair Popple
@ 2026-10-26 10:01   ` sashiko-bot
  2026-10-27  2:15   ` Karl Mehltretter
  2026-10-27 12:07   ` Christian König
  2 siblings, 0 replies; 71+ messages in thread
From: sashiko-bot @ 2026-10-26 10:01 UTC (permalink / raw)
  To: Alistair Popple; +Cc: linux-rdma

> From: Jason Gunthorpe <jgg@nvidia.com>
> 
> This attach function always creates a SGT mapping type importer.
> 
> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>

Sashiko has reviewed this patch and found no issues.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261026053623.202642-1-apopple@nvidia.com?part=23


^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH 24/26] treewide: Rename dma_buf_dynamic_attach() to dma_buf_sgt_dynamic_attach()
  2026-10-26  5:36 ` [PATCH 24/26] treewide: Rename dma_buf_dynamic_attach() to dma_buf_sgt_dynamic_attach() Alistair Popple
@ 2026-10-26 10:13   ` sashiko-bot
  0 siblings, 0 replies; 71+ messages in thread
From: sashiko-bot @ 2026-10-26 10:13 UTC (permalink / raw)
  To: Alistair Popple; +Cc: linux-rdma

> From: Jason Gunthorpe <jgg@nvidia.com>
> 
> This attach function always creates a SGT mapping type importer.
> 
> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>

Sashiko has reviewed this patch and found no issues.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261026053623.202642-1-apopple@nvidia.com?part=24


^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH 25/26] dma-buf: Add kunit tests for mapping type
  2026-10-26  5:36 ` [PATCH 25/26] dma-buf: Add kunit tests for mapping type Alistair Popple
@ 2026-10-26 10:19   ` sashiko-bot
  0 siblings, 0 replies; 71+ messages in thread
From: sashiko-bot @ 2026-10-26 10:19 UTC (permalink / raw)
  To: Alistair Popple, dri-devel; +Cc: intel-xe, linux-rdma, media-ci

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] dma-buf: kunit: test_match_fail() overwrites args before type mismatch check
--

commit 4b902f505b8acdddc13e192c921c70bcac60644c
Author: Jason Gunthorpe <jgg@ziepe.ca>

dma-buf: Add kunit tests for mapping type

This commit adds KUnit tests in drivers/dma-buf/st-dma-mapping.c to test
dma_buf_match_mapping() matching and priority rules as well as SGT and
dynamic attachment flows.

> diff --git a/drivers/dma-buf/st-dma-mapping.c b/drivers/dma-buf/st-dma-mapping.c
> new file mode 100644
> index 0000000000000..9d0f1e389e15e
> --- /dev/null
> +++ b/drivers/dma-buf/st-dma-mapping.c
> @@ -0,0 +1,385 @@

[ ... ]

> +static void test_match_fail(struct kunit *test)
> +{
> +	struct dma_buf_mapping_match matches[] = { { .type = &mock_type_a } };
> +	struct dma_buf_mapping_match exp[] = { { .type = &mock_type_b } };
> +	struct dma_buf_attachment attach = {};
> +	struct dma_buf_match_args args = {
> +		.attach = &attach,
> +		.imp_matches = matches,
> +		.imp_len = ARRAY_SIZE(matches),
> +	};
> +
> +	/* Zero-length exporter array returns -EINVAL */
> +	KUNIT_EXPECT_EQ(test, dma_buf_match_mapping(&args, NULL, 0), -EINVAL);
> +	KUNIT_EXPECT_FALSE(test, mock_match_called);
> +	KUNIT_EXPECT_FALSE(test, mock_finish_called);
> +
> +	/* Zero-length importer array returns -EINVAL */
> +	args = (struct dma_buf_match_args){ .attach = &attach };
> +	KUNIT_EXPECT_EQ(test,
> +			dma_buf_match_mapping(&args, matches,
> +					      ARRAY_SIZE(matches)),
> +			-EINVAL);
> +	KUNIT_EXPECT_FALSE(test, mock_match_called);
> +	KUNIT_EXPECT_FALSE(test, mock_finish_called);
> +
> +	/* Different types produce no match */
> +	KUNIT_EXPECT_EQ(test,
> +			dma_buf_match_mapping(&args, exp, ARRAY_SIZE(exp)),
> +			-EINVAL);
> +	KUNIT_EXPECT_FALSE(test, mock_match_called);
> +	KUNIT_EXPECT_FALSE(test, mock_finish_called);
> +}

[Severity: Medium]
In drivers/dma-buf/st-dma-mapping.c, test_match_fail() overwrites args with:

	args = (struct dma_buf_match_args){ .attach = &attach };

for the zero-length importer array check, which zeroes args.imp_matches and
args.imp_len.

When the subsequent "Different types produce no match" check calls
dma_buf_match_mapping(&args, exp, ARRAY_SIZE(exp)), args.imp_matches is still
NULL and args.imp_len is still 0. In drivers/dma-buf/dma-buf-mapping.c,
dma_buf_match_mapping() computes imp_end = args->imp_matches + args->imp_len,
so imp == imp_end on entry to the inner loop:

	for (; exp != exp_end; exp++) {
		const struct dma_buf_mapping_match *imp = args->imp_matches;

		for (; imp != imp_end; imp++) {
			if (exp->type != imp->type)
				continue;

Doesn't this bypass the exp->type != imp->type comparison and just re-test a
zero-length importer array instead of testing mismatched types? Should
args.imp_matches and args.imp_len be restored to matches and
ARRAY_SIZE(matches) before the third dma_buf_match_mapping() call?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261026053623.202642-1-apopple@nvidia.com?part=25

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH 26/26] dma-buf: Add kunit tests for mapping type selection
  2026-10-26  5:36 ` [PATCH 26/26] dma-buf: Add kunit tests for mapping type selection Alistair Popple
@ 2026-10-26 10:22   ` sashiko-bot
  0 siblings, 0 replies; 71+ messages in thread
From: sashiko-bot @ 2026-10-26 10:22 UTC (permalink / raw)
  To: Alistair Popple; +Cc: linux-rdma

> Add an offer list and a select_mapping() callback to the mock exporter
> along with map/unmap for the two mock types.
> 
> Adds tests for the exporter/importer contract.
> 
>  - test_match_set_is_final: a later importer attaching, even one the
>    exporter answers differently, does not change an existing
>    attachment's match set or default. Later attachments influence what
>    the exporter selects at pin and map time, not previous attachments.
> 
>  - test_select_at_map: the exporter chooses a non-default entry
>    at the first map and the result is tagged with it. A pin taken
>    under the live mapping inherits the type and the choice survives
>    unmap/remap even though the exporter would answer differently. Only
>    dma_buf_invalidate_mappings() allows the exporter to make a different
>    selection. An -EBUSY from selection leaves nothing established.
> 
>  - test_select_at_pin: pin selects, and the choice survives map, unmap
>    and unpin so a pinned importer that is never invalidated keeps its
>    first type for the life of the import.
> 
> Assisted-by: LLM
> Signed-off-by: Alistair Popple <apopple@nvidia.com>

Sashiko has reviewed this patch and found no issues.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261026053623.202642-1-apopple@nvidia.com?part=26


^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH 23/26] treewide: Rename dma_buf_attach() to dma_buf_sgt_attach()
  2026-10-26  5:36 ` [PATCH 23/26] treewide: Rename dma_buf_attach() to dma_buf_sgt_attach() Alistair Popple
  2026-10-26 10:01   ` sashiko-bot
@ 2026-10-27  2:15   ` Karl Mehltretter
  2026-10-27  3:42     ` Mikko Perttunen
                       ` (2 more replies)
  2026-10-27 12:07   ` Christian König
  2 siblings, 3 replies; 71+ messages in thread
From: Karl Mehltretter @ 2026-10-27  2:15 UTC (permalink / raw)
  To: Alistair Popple
  Cc: dri-devel, christian.koenig, sumit.semwal, jgg,
	Thomas Hellström, Simona Vetter, Matthew Brost,
	Vivek Kasireddy, Dongwon Kim, Leon Romanovsky, Kevin Tian,
	Xu Yilun, Baolu Lu, Felix Kuehling, Alex Deucher, intel-xe,
	amd-gfx, linux-media, linaro-mm-sig, linux-rdma, iommu,
	Alexey Kardashevskiy, zhipingz, treding, jhubbard

On Mon, Oct 26, 2026 at 04:36:14PM +0100, Alistair Popple wrote:

Testing the series on a Jetson Nano exposed this path. A 3 MiB system-heap
buffer was imported into Tegra DRM and scanned out over HDMI. With
CONFIG_DMABUF_DEBUG=y the PRIME import succeeded, but scanout immediately
produced display SMMU faults starting at 0x300000.

Tracing the fault led here:

> @@ -475,7 +475,7 @@ static struct tegra_bo *tegra_bo_import(struct drm_device *drm,
>  	 * domain, map it first to the DRM device to get an sgt.
>  	 */
>  	if (tegra->domain) {
> -		attach = dma_buf_attach(buf, drm->dev);
> +		attach = dma_buf_sgt_attach(buf, drm->dev);

tegra_bo_import() passes the attachment SGT to iommu_map_sgtable(), which
uses sg_phys() and sg->length. The SGT mapping contract only guarantees the
DMA address and length fields. The debug wrapper clears the page-side fields,
so iommu_map_sgtable() maps zero bytes. 

Tegra only treats negative returns as errors and keeps the reserved
IOVA, which scanout then faults on.

This page-side use predates the series, so the fault is not itself a v2
regression. Is dma_buf_sgt_attach() valid for this call site, or does Tegra
need a page/physical mapping type first?

Karl

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH 23/26] treewide: Rename dma_buf_attach() to dma_buf_sgt_attach()
  2026-10-27  2:15   ` Karl Mehltretter
@ 2026-10-27  3:42     ` Mikko Perttunen
  2026-10-27 12:33       ` Jason Gunthorpe
  2026-10-27 12:11     ` Christian König
  2026-10-27 12:31     ` Jason Gunthorpe
  2 siblings, 1 reply; 71+ messages in thread
From: Mikko Perttunen @ 2026-10-27  3:42 UTC (permalink / raw)
  To: Alistair Popple, linux-rdma
  Cc: dri-devel, christian.koenig, sumit.semwal, jgg,
	Thomas Hellström, Simona Vetter, Matthew Brost,
	Vivek Kasireddy, Dongwon Kim, Leon Romanovsky, Kevin Tian,
	Xu Yilun, Baolu Lu, Felix Kuehling, Alex Deucher, intel-xe,
	amd-gfx, linux-media, linaro-mm-sig, linux-rdma, iommu,
	Alexey Kardashevskiy, zhipingz, treding, jhubbard,
	Karl Mehltretter

On Tuesday, October 27, 2026 11:15 AM Karl Mehltretter wrote:
> On Mon, Oct 26, 2026 at 04:36:14PM +0100, Alistair Popple wrote:
> 
> Testing the series on a Jetson Nano exposed this path. A 3 MiB system-heap
> buffer was imported into Tegra DRM and scanned out over HDMI. With
> CONFIG_DMABUF_DEBUG=y the PRIME import succeeded, but scanout immediately
> produced display SMMU faults starting at 0x300000.
> 
> Tracing the fault led here:
> 
> > @@ -475,7 +475,7 @@ static struct tegra_bo *tegra_bo_import(struct drm_device *drm,
> >  	 * domain, map it first to the DRM device to get an sgt.
> >  	 */
> >  	if (tegra->domain) {
> > -		attach = dma_buf_attach(buf, drm->dev);
> > +		attach = dma_buf_sgt_attach(buf, drm->dev);
> 
> tegra_bo_import() passes the attachment SGT to iommu_map_sgtable(), which
> uses sg_phys() and sg->length. The SGT mapping contract only guarantees the
> DMA address and length fields. The debug wrapper clears the page-side fields,
> so iommu_map_sgtable() maps zero bytes. 
> 
> Tegra only treats negative returns as errors and keeps the reserved
> IOVA, which scanout then faults on.
> 
> This page-side use predates the series, so the fault is not itself a v2
> regression. Is dma_buf_sgt_attach() valid for this call site, or does Tegra
> need a page/physical mapping type first?
> 
> Karl
> 

Sounds like a bug in TegraDRM; we should be using the DMA addr/length 
for the explicit IOMMU mapping as the sgt attachment is for the dummy 
DRM device explicitly intended to give us physical addresses.

I'm currently in the process of removing the whole explicit IOMMU path 
so if this only occurs with CONFIG_DMABUF_DEBUG enabled, I don't think 
there's a pressing need to fix this before then.

Thanks for the bug report!
Mikko




^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH 05/26] dma-buf: Let the exporter select mapping type at pin/map
  2026-10-26  8:03   ` Karl Mehltretter
@ 2026-10-27  5:46     ` Alistair Popple
  0 siblings, 0 replies; 71+ messages in thread
From: Alistair Popple @ 2026-10-27  5:46 UTC (permalink / raw)
  To: Karl Mehltretter
  Cc: dri-devel, christian.koenig, sumit.semwal, jgg,
	Thomas Hellström, Simona Vetter, Matthew Brost,
	Vivek Kasireddy, Dongwon Kim, Leon Romanovsky, Kevin Tian,
	Xu Yilun, Baolu Lu, Felix Kuehling, Alex Deucher, intel-xe,
	amd-gfx, linux-media, linaro-mm-sig, linux-rdma, iommu,
	Alexey Kardashevskiy, zhipingz, treding, jhubbard

On 2026-10-26 at 19:03 +1100, Karl Mehltretter <kmehltretter@gmail.com> wrote...
> On Mon, Oct 26, 2026 at 04:35:56PM +0100, Alistair Popple wrote:
> > +struct sg_table *dma_buf_map_attachment(struct dma_buf_attachment *attach,
> > +					enum dma_data_direction direction)
> > +{
> > +	struct sg_table *sg_table;
> > +	int ret;
> > +
> > +	might_sleep();
> > +
> > +	if (WARN_ON(!attach || !attach->dmabuf))
> > +		return ERR_PTR(-EINVAL);
> > +
> > +	dma_resv_assert_held(attach->dmabuf->resv);
> > +
> > +	ret = dma_buf_mapping_select(attach);
> > +	if (ret)
> > +		return ERR_PTR(ret);
> > +
> > +	sg_table = __dma_buf_sgt_map_attachment(attach, direction);
> > +	if (IS_ERR(sg_table))
> > +		/* Nothing was established, so the choice may be made afresh */
> > +		attach->selected = false;
> > +
> > +	return sg_table;
> > +}
> 
> The map-failure report from Sashiko [1] reproduces with a KUnit test
> against the full series:
> 
>   pin selects B -> map returns -EIO -> selected is cleared
>                 -> retry selects A, with the original pin still held
> 
> The exporter pin count stays at 1. Preserving selected when it was true
> on entry makes the test pass. Patch 7 needs the same fix.

Agreed, thanks for looking. A failed map shouldn't undo a previous selection.

> Could dma_buf_mapping_select() report whether it made a new selection?
> Then the error path could undo only that choice, without dropping one
> established by an earlier pin or map.

We could do. At one stage I had a prototype of this returning the old match, but
that got complicated. We do need to undo in the error path though, so will fix
this for v2.

> On the Sashiko failed-pin report:
> ("Because the attachment is not pinned, the exporter may migrate the
> buffer elsewhere without invalidating it")
> 
> I don't think this follows from the documented contract.
> select_mapping() requires the exporter to keep the recorded type
> servable and invalidate before an incompatible move. That obligation
> still applies if ops->pin() fails.

Yes, I think that statement is correct.

> Is retaining the selection after a failed pin intentional? If so, this
> can be added as a test documenting that alongside the map-failure
> regression test.

No, that was not intentional. As noted about I think if the first pin/map of an
attachment failed it should effectively go back to the selected = false state.

 - Alistair

> Thanks,
> Karl

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH 21/26] treewide: Rename dma_buf_map_attachment(_unlocked) to dma_buf_sgt_
  2026-10-26  5:36 ` [PATCH 21/26] treewide: Rename dma_buf_map_attachment(_unlocked) to dma_buf_sgt_ Alistair Popple
  2026-10-26  9:49   ` sashiko-bot
@ 2026-10-27 12:05   ` Christian König
  2026-10-27 12:35     ` Jason Gunthorpe
  1 sibling, 1 reply; 71+ messages in thread
From: Christian König @ 2026-10-27 12:05 UTC (permalink / raw)
  To: Alistair Popple, dri-devel, sumit.semwal, jgg
  Cc: Thomas Hellström, Simona Vetter, Matthew Brost,
	Vivek Kasireddy, Dongwon Kim, Leon Romanovsky, Kevin Tian,
	Xu Yilun, Karl Mehltretter, Baolu Lu, Felix Kuehling,
	Alex Deucher, intel-xe, amd-gfx, linux-media, linaro-mm-sig,
	linux-rdma, iommu, Alexey Kardashevskiy, zhipingz, treding,
	jhubbard

On 10/26/26 06:36, Alistair Popple wrote:
> From: Jason Gunthorpe <jgg@nvidia.com>
> 
> This map function only works with SGT importers.
> 
> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
> [ also rename the io_uring zcrx caller, which the unmap rename
>   used to pick up, so that this commit builds with CONFIG_IO_URING_ZCRX - apopple ]
> Signed-off-by: Alistair Popple <apopple@nvidia.com>

I would make that the first patch in the set since dropping sgt from the interface is probably something everybody can agree on.

And sqash that together with renaming dma_buf_unmap_attachment().

Regarding the new name I think dma_buf_sgt_(un)map_attachment() is a bit long and has the sgt at the wrong location.

I would name the functions dma_buf_map_sgt() and dma_buf_unmap_sgt().

Regards,
Christian.

> ---
>  drivers/accel/amdxdna/amdxdna_gem.c           |  2 +-
>  drivers/accel/ivpu/ivpu_gem.c                 |  3 +-
>  drivers/accel/qaic/qaic_data.c                |  4 +--
>  drivers/dma-buf/dma-buf.c                     | 28 +++++++++----------
>  drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c       |  3 +-
>  drivers/gpu/drm/armada/armada_gem.c           | 14 ++++++----
>  drivers/gpu/drm/drm_prime.c                   |  2 +-
>  drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c    |  4 +--
>  .../drm/i915/gem/selftests/i915_gem_dmabuf.c  |  3 +-
>  drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c     |  2 +-
>  drivers/gpu/drm/tegra/gem.c                   |  6 ++--
>  drivers/gpu/drm/virtio/virtgpu_prime.c        |  2 +-
>  drivers/gpu/drm/xe/xe_bo.c                    |  2 +-
>  drivers/iio/industrialio-buffer.c             |  2 +-
>  drivers/infiniband/core/umem_dmabuf.c         |  4 +--
>  .../media/common/videobuf2/videobuf2-core.c   |  2 +-
>  .../common/videobuf2/videobuf2-dma-contig.c   |  2 +-
>  .../media/common/videobuf2/videobuf2-dma-sg.c |  2 +-
>  .../platform/nvidia/tegra-vde/dmabuf-cache.c  |  2 +-
>  drivers/misc/fastrpc.c                        |  3 +-
>  drivers/usb/gadget/function/f_fs.c            |  2 +-
>  drivers/xen/gntdev-dmabuf.c                   |  2 +-
>  include/linux/dma-buf-mapping.h               |  4 +--
>  include/linux/dma-buf.h                       | 10 +++----
>  io_uring/zcrx.c                               |  3 +-
>  net/core/devmem.c                             |  4 +--
>  26 files changed, 63 insertions(+), 54 deletions(-)
> 
> diff --git a/drivers/accel/amdxdna/amdxdna_gem.c b/drivers/accel/amdxdna/amdxdna_gem.c
> index 6253a720cc22..c679ec8230ff 100644
> --- a/drivers/accel/amdxdna/amdxdna_gem.c
> +++ b/drivers/accel/amdxdna/amdxdna_gem.c
> @@ -898,7 +898,7 @@ amdxdna_gem_prime_import(struct drm_device *dev, struct dma_buf *dma_buf)
>  		goto put_buf;
>  	}
>  
> -	sgt = dma_buf_map_attachment_unlocked(attach, DMA_BIDIRECTIONAL);
> +	sgt = dma_buf_sgt_map_attachment_unlocked(attach, DMA_BIDIRECTIONAL);
>  	if (IS_ERR(sgt)) {
>  		ret = PTR_ERR(sgt);
>  		goto fail_detach;
> diff --git a/drivers/accel/ivpu/ivpu_gem.c b/drivers/accel/ivpu/ivpu_gem.c
> index 4f2005a8d496..0342a3fc9185 100644
> --- a/drivers/accel/ivpu/ivpu_gem.c
> +++ b/drivers/accel/ivpu/ivpu_gem.c
> @@ -54,7 +54,8 @@ static struct sg_table *ivpu_bo_map_attachment(struct ivpu_device *vdev, struct
>  
>  	sgt = bo->base.sgt;
>  	if (!sgt) {
> -		sgt = dma_buf_map_attachment(bo->base.base.import_attach, DMA_BIDIRECTIONAL);
> +		sgt = dma_buf_sgt_map_attachment(bo->base.base.import_attach,
> +						 DMA_BIDIRECTIONAL);
>  		if (IS_ERR(sgt))
>  			ivpu_err(vdev, "Failed to map BO in IOMMU: %ld\n", PTR_ERR(sgt));
>  		else
> diff --git a/drivers/accel/qaic/qaic_data.c b/drivers/accel/qaic/qaic_data.c
> index ef0351b6dc9b..b8de1a1e2ab9 100644
> --- a/drivers/accel/qaic/qaic_data.c
> +++ b/drivers/accel/qaic/qaic_data.c
> @@ -863,7 +863,7 @@ struct drm_gem_object *qaic_gem_prime_import(struct drm_device *dev, struct dma_
>  
>  	drm_gem_private_object_init(dev, obj, attach->dmabuf->size);
>  	/*
> -	 * skipping dma_buf_map_attachment() as we do not know the direction
> +	 * skipping dma_buf_sgt_map_attachment() as we do not know the direction
>  	 * just yet. Once the direction is known in the subsequent IOCTL to
>  	 * attach slicing, we can do it then.
>  	 */
> @@ -889,7 +889,7 @@ static int qaic_prepare_import_bo(struct qaic_bo *bo, struct qaic_attach_slice_h
>  	struct sg_table *sgt;
>  	int ret;
>  
> -	sgt = dma_buf_map_attachment(obj->import_attach, hdr->dir);
> +	sgt = dma_buf_sgt_map_attachment(obj->import_attach, hdr->dir);
>  	if (IS_ERR(sgt)) {
>  		ret = PTR_ERR(sgt);
>  		return ret;
> diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c
> index dc65752fb0fa..209a1dca19d0 100644
> --- a/drivers/dma-buf/dma-buf.c
> +++ b/drivers/dma-buf/dma-buf.c
> @@ -678,7 +678,7 @@ static struct file *dma_buf_getfile(size_t size, int flags)
>   *
>   * 3. Once the buffer is attached to all devices userspace can initiate DMA
>   *    access to the shared buffer. In the kernel this is done by calling
> - *    dma_buf_map_attachment() and dma_buf_unmap_attachment().
> + *    dma_buf_sgt_map_attachment() and dma_buf_unmap_attachment().
>   *
>   * 4. Once a driver is done with a shared buffer it needs to call
>   *    dma_buf_detach() (after cleaning up any mappings) and then release the
> @@ -958,7 +958,7 @@ dma_buf_pin_on_map(struct dma_buf_attachment *attach)
>   *
>   *     - dma_buf_pin()
>   *     - dma_buf_unpin()
> - *     - dma_buf_map_attachment()
> + *     - dma_buf_sgt_map_attachment()
>   *     - dma_buf_unmap_attachment()
>   *     - dma_buf_vmap()
>   *     - dma_buf_vunmap()
> @@ -976,7 +976,7 @@ dma_buf_pin_on_map(struct dma_buf_attachment *attach)
>   *     - dma_buf_mmap()
>   *     - dma_buf_begin_cpu_access()
>   *     - dma_buf_end_cpu_access()
> - *     - dma_buf_map_attachment_unlocked()
> + *     - dma_buf_sgt_map_attachment_unlocked()
>   *     - dma_buf_unmap_attachment_unlocked()
>   *     - dma_buf_vmap_unlocked()
>   *     - dma_buf_vunmap_unlocked()
> @@ -1302,7 +1302,7 @@ __dma_buf_sgt_map_attachment(struct dma_buf_attachment *attach,
>  }
>  
>  /**
> - * dma_buf_map_attachment - Returns the scatterlist table of the attachment;
> + * dma_buf_sgt_map_attachment - Returns the scatterlist table of the attachment;
>   * mapped into _device_ address space. Is a wrapper for map_dma_buf() of the
>   * dma_buf_ops.
>   * @attach:	[in]	attachment whose scatterlist is to be returned
> @@ -1322,8 +1322,8 @@ __dma_buf_sgt_map_attachment(struct dma_buf_attachment *attach,
>   * Important: Dynamic importers must wait for the exclusive fence of the struct
>   * dma_resv attached to the DMA-BUF first.
>   */
> -struct sg_table *dma_buf_map_attachment(struct dma_buf_attachment *attach,
> -					enum dma_data_direction direction)
> +struct sg_table *dma_buf_sgt_map_attachment(struct dma_buf_attachment *attach,
> +					    enum dma_data_direction direction)
>  {
>  	struct sg_table *sg_table;
>  	int ret;
> @@ -1346,7 +1346,7 @@ struct sg_table *dma_buf_map_attachment(struct dma_buf_attachment *attach,
>  
>  	return sg_table;
>  }
> -EXPORT_SYMBOL_NS_GPL(dma_buf_map_attachment, "DMA_BUF");
> +EXPORT_SYMBOL_NS_GPL(dma_buf_sgt_map_attachment, "DMA_BUF");
>  
>  /* &dma_buf_mapping_type.map / .unmap for the SGT type */
>  struct dma_buf_mapping *dma_buf_sgt_type_map(struct dma_buf_attachment *attach,
> @@ -1382,17 +1382,17 @@ void dma_buf_sgt_type_unmap(struct dma_buf_attachment *attach,
>  }
>  
>  /**
> - * dma_buf_map_attachment_unlocked - Returns the scatterlist table of the attachment;
> + * dma_buf_sgt_map_attachment_unlocked - Returns the scatterlist table of the attachment;
>   * mapped into _device_ address space. Is a wrapper for map_dma_buf() of the
>   * dma_buf_ops.
>   * @attach:	[in]	attachment whose scatterlist is to be returned
>   * @direction:	[in]	direction of DMA transfer
>   *
> - * Unlocked variant of dma_buf_map_attachment().
> + * Unlocked variant of dma_buf_sgt_map_attachment().
>   */
>  struct sg_table *
> -dma_buf_map_attachment_unlocked(struct dma_buf_attachment *attach,
> -				enum dma_data_direction direction)
> +dma_buf_sgt_map_attachment_unlocked(struct dma_buf_attachment *attach,
> +				    enum dma_data_direction direction)
>  {
>  	struct sg_table *sg_table;
>  
> @@ -1402,12 +1402,12 @@ dma_buf_map_attachment_unlocked(struct dma_buf_attachment *attach,
>  		return ERR_PTR(-EINVAL);
>  
>  	dma_resv_lock(attach->dmabuf->resv, NULL);
> -	sg_table = dma_buf_map_attachment(attach, direction);
> +	sg_table = dma_buf_sgt_map_attachment(attach, direction);
>  	dma_resv_unlock(attach->dmabuf->resv);
>  
>  	return sg_table;
>  }
> -EXPORT_SYMBOL_NS_GPL(dma_buf_map_attachment_unlocked, "DMA_BUF");
> +EXPORT_SYMBOL_NS_GPL(dma_buf_sgt_map_attachment_unlocked, "DMA_BUF");
>  
>  /**
>   * dma_buf_unmap_attachment - unmaps and decreases usecount of the buffer;might
> @@ -1417,7 +1417,7 @@ EXPORT_SYMBOL_NS_GPL(dma_buf_map_attachment_unlocked, "DMA_BUF");
>   * @sg_table:	[in]	scatterlist info of the buffer to unmap
>   * @direction:  [in]    direction of DMA transfer
>   *
> - * This unmaps a DMA mapping for @attached obtained by dma_buf_map_attachment().
> + * This unmaps a DMA mapping for @attached obtained by dma_buf_sgt_map_attachment().
>   */
>  void dma_buf_unmap_attachment(struct dma_buf_attachment *attach,
>  				struct sg_table *sg_table,
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> index 016957cac1f2..169e1b27ff8e 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> @@ -954,7 +954,8 @@ static int amdgpu_ttm_backend_bind(struct ttm_device *bdev,
>  			struct sg_table *sgt;
>  
>  			attach = gtt->gobj->import_attach;
> -			sgt = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL);
> +			sgt = dma_buf_sgt_map_attachment(attach,
> +							 DMA_BIDIRECTIONAL);
>  			if (IS_ERR(sgt))
>  				return PTR_ERR(sgt);
>  
> diff --git a/drivers/gpu/drm/armada/armada_gem.c b/drivers/gpu/drm/armada/armada_gem.c
> index 5cea1eab6e5c..506bc82f20d6 100644
> --- a/drivers/gpu/drm/armada/armada_gem.c
> +++ b/drivers/gpu/drm/armada/armada_gem.c
> @@ -531,7 +531,7 @@ armada_gem_prime_import(struct drm_device *dev, struct dma_buf *buf)
>  	get_dma_buf(buf);
>  
>  	/*
> -	 * Don't call dma_buf_map_attachment() here - it maps the
> +	 * Don't call dma_buf_sgt_map_attachment() here - it maps the
>  	 * scatterlist immediately for DMA, and this is not always
>  	 * an appropriate thing to do.
>  	 */
> @@ -542,20 +542,22 @@ int armada_gem_map_import(struct armada_gem_object *dobj)
>  {
>  	int ret;
>  
> -	dobj->sgt = dma_buf_map_attachment_unlocked(dobj->obj.import_attach,
> -						    DMA_TO_DEVICE);
> +	dobj->sgt = dma_buf_sgt_map_attachment_unlocked(dobj->obj.import_attach,
> +							DMA_TO_DEVICE);
>  	if (IS_ERR(dobj->sgt)) {
>  		ret = PTR_ERR(dobj->sgt);
>  		dobj->sgt = NULL;
> -		DRM_ERROR("dma_buf_map_attachment() error: %d\n", ret);
> +		DRM_ERROR("dma_buf_sgt_map_attachment() error: %d\n", ret);
>  		return ret;
>  	}
>  	if (dobj->sgt->nents > 1) {
> -		DRM_ERROR("dma_buf_map_attachment() returned an (unsupported) scattered list\n");
> +		DRM_ERROR(
> +			"dma_buf_sgt_map_attachment() returned an (unsupported) scattered list\n");
>  		return -EINVAL;
>  	}
>  	if (sg_dma_len(dobj->sgt->sgl) < dobj->obj.size) {
> -		DRM_ERROR("dma_buf_map_attachment() returned a small buffer\n");
> +		DRM_ERROR(
> +			"dma_buf_sgt_map_attachment() returned a small buffer\n");
>  		return -EINVAL;
>  	}
>  	dobj->dev_addr = sg_dma_address(dobj->sgt->sgl);
> diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c
> index 7792caf87883..330b64b3324a 100644
> --- a/drivers/gpu/drm/drm_prime.c
> +++ b/drivers/gpu/drm/drm_prime.c
> @@ -1005,7 +1005,7 @@ struct drm_gem_object *drm_gem_prime_import_dev(struct drm_device *dev,
>  
>  	get_dma_buf(dma_buf);
>  
> -	sgt = dma_buf_map_attachment_unlocked(attach, DMA_BIDIRECTIONAL);
> +	sgt = dma_buf_sgt_map_attachment_unlocked(attach, DMA_BIDIRECTIONAL);
>  	if (IS_ERR(sgt)) {
>  		ret = PTR_ERR(sgt);
>  		goto fail_detach;
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
> index 5333e77e62e0..04c7b9a97681 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
> @@ -242,8 +242,8 @@ static int i915_gem_object_get_pages_dmabuf(struct drm_i915_gem_object *obj)
>  
>  	assert_object_held(obj);
>  
> -	sgt = dma_buf_map_attachment(obj->base.import_attach,
> -				     DMA_BIDIRECTIONAL);
> +	sgt = dma_buf_sgt_map_attachment(obj->base.import_attach,
> +					 DMA_BIDIRECTIONAL);
>  	if (IS_ERR(sgt))
>  		return PTR_ERR(sgt);
>  
> diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_dmabuf.c b/drivers/gpu/drm/i915/gem/selftests/i915_gem_dmabuf.c
> index 2fda549dd82d..fcfa819caa38 100644
> --- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_dmabuf.c
> +++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_dmabuf.c
> @@ -293,7 +293,8 @@ static int igt_dmabuf_import_same_driver(struct drm_i915_private *i915,
>  		goto out_import;
>  	}
>  
> -	st = dma_buf_map_attachment_unlocked(import_attach, DMA_BIDIRECTIONAL);
> +	st = dma_buf_sgt_map_attachment_unlocked(import_attach,
> +						 DMA_BIDIRECTIONAL);
>  	if (IS_ERR(st)) {
>  		err = PTR_ERR(st);
>  		goto out_detach;
> diff --git a/drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c b/drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c
> index 23beaeefab67..569ee2d3ab6f 100644
> --- a/drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c
> +++ b/drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c
> @@ -121,7 +121,7 @@ struct drm_gem_object *omap_gem_prime_import(struct drm_device *dev,
>  
>  	get_dma_buf(dma_buf);
>  
> -	sgt = dma_buf_map_attachment_unlocked(attach, DMA_TO_DEVICE);
> +	sgt = dma_buf_sgt_map_attachment_unlocked(attach, DMA_TO_DEVICE);
>  	if (IS_ERR(sgt)) {
>  		ret = PTR_ERR(sgt);
>  		goto fail_detach;
> diff --git a/drivers/gpu/drm/tegra/gem.c b/drivers/gpu/drm/tegra/gem.c
> index feb783ceb0d1..fcb9308f49f0 100644
> --- a/drivers/gpu/drm/tegra/gem.c
> +++ b/drivers/gpu/drm/tegra/gem.c
> @@ -87,7 +87,8 @@ static struct host1x_bo_mapping *tegra_bo_pin(struct device *dev, struct host1x_
>  			goto free;
>  		}
>  
> -		map->sgt = dma_buf_map_attachment_unlocked(map->attach, direction);
> +		map->sgt = dma_buf_sgt_map_attachment_unlocked(map->attach,
> +							       direction);
>  		if (IS_ERR(map->sgt)) {
>  			dma_buf_detach(buf, map->attach);
>  			err = PTR_ERR(map->sgt);
> @@ -480,7 +481,8 @@ static struct tegra_bo *tegra_bo_import(struct drm_device *drm,
>  			goto free;
>  		}
>  
> -		bo->sgt = dma_buf_map_attachment_unlocked(attach, DMA_TO_DEVICE);
> +		bo->sgt = dma_buf_sgt_map_attachment_unlocked(attach,
> +							      DMA_TO_DEVICE);
>  		if (IS_ERR(bo->sgt)) {
>  			err = PTR_ERR(bo->sgt);
>  			goto detach;
> diff --git a/drivers/gpu/drm/virtio/virtgpu_prime.c b/drivers/gpu/drm/virtio/virtgpu_prime.c
> index 3d5203ac19b6..de69590b5076 100644
> --- a/drivers/gpu/drm/virtio/virtgpu_prime.c
> +++ b/drivers/gpu/drm/virtio/virtgpu_prime.c
> @@ -164,7 +164,7 @@ int virtgpu_dma_buf_import_sgt(struct virtio_gpu_mem_entry **ents,
>  	if (ret <= 0)
>  		return ret < 0 ? ret : -ETIMEDOUT;
>  
> -	sgt = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL);
> +	sgt = dma_buf_sgt_map_attachment(attach, DMA_BIDIRECTIONAL);
>  	if (IS_ERR(sgt))
>  		return PTR_ERR(sgt);
>  
> diff --git a/drivers/gpu/drm/xe/xe_bo.c b/drivers/gpu/drm/xe/xe_bo.c
> index b4921a627ff3..4d93b8926ed6 100644
> --- a/drivers/gpu/drm/xe/xe_bo.c
> +++ b/drivers/gpu/drm/xe/xe_bo.c
> @@ -771,7 +771,7 @@ static int xe_bo_move_dmabuf(struct ttm_buffer_object *ttm_bo,
>  		ttm_bo->sg = NULL;
>  	}
>  
> -	sg = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL);
> +	sg = dma_buf_sgt_map_attachment(attach, DMA_BIDIRECTIONAL);
>  	if (IS_ERR(sg))
>  		return PTR_ERR(sg);
>  
> diff --git a/drivers/iio/industrialio-buffer.c b/drivers/iio/industrialio-buffer.c
> index a00985c92251..619181968ff9 100644
> --- a/drivers/iio/industrialio-buffer.c
> +++ b/drivers/iio/industrialio-buffer.c
> @@ -1730,7 +1730,7 @@ static int iio_buffer_attach_dmabuf(struct iio_dev_buffer_pair *ib,
>  	priv->dir = buffer->direction == IIO_BUFFER_DIRECTION_IN
>  		? DMA_FROM_DEVICE : DMA_TO_DEVICE;
>  
> -	priv->sgt = dma_buf_map_attachment(attach, priv->dir);
> +	priv->sgt = dma_buf_sgt_map_attachment(attach, priv->dir);
>  	if (IS_ERR(priv->sgt)) {
>  		err = PTR_ERR(priv->sgt);
>  		dev_err(&indio_dev->dev, "Unable to map attachment: %d\n", err);
> diff --git a/drivers/infiniband/core/umem_dmabuf.c b/drivers/infiniband/core/umem_dmabuf.c
> index 39b5564a4c35..dd584f8dcd1c 100644
> --- a/drivers/infiniband/core/umem_dmabuf.c
> +++ b/drivers/infiniband/core/umem_dmabuf.c
> @@ -29,8 +29,8 @@ int ib_umem_dmabuf_map_pages(struct ib_umem_dmabuf *umem_dmabuf)
>  	if (umem_dmabuf->sgt)
>  		goto wait_fence;
>  
> -	sgt = dma_buf_map_attachment(umem_dmabuf->attach,
> -				     DMA_BIDIRECTIONAL);
> +	sgt = dma_buf_sgt_map_attachment(umem_dmabuf->attach,
> +					 DMA_BIDIRECTIONAL);
>  	if (IS_ERR(sgt))
>  		return PTR_ERR(sgt);
>  
> diff --git a/drivers/media/common/videobuf2/videobuf2-core.c b/drivers/media/common/videobuf2/videobuf2-core.c
> index b0a6084f1757..5cd53e06da0b 100644
> --- a/drivers/media/common/videobuf2/videobuf2-core.c
> +++ b/drivers/media/common/videobuf2/videobuf2-core.c
> @@ -1464,7 +1464,7 @@ static int __prepare_dmabuf(struct vb2_buffer *vb)
>  			vb->planes[plane].mem_priv = mem_priv;
>  
>  			/*
> -			 * This pins the buffer(s) with dma_buf_map_attachment()). It's done
> +			 * This pins the buffer(s) with dma_buf_sgt_map_attachment()). It's done
>  			 * here instead just before the DMA, while queueing the buffer(s) so
>  			 * userspace knows sooner rather than later if the dma-buf map fails.
>  			 */
> diff --git a/drivers/media/common/videobuf2/videobuf2-dma-contig.c b/drivers/media/common/videobuf2/videobuf2-dma-contig.c
> index 536f839258c6..0ce643940898 100644
> --- a/drivers/media/common/videobuf2/videobuf2-dma-contig.c
> +++ b/drivers/media/common/videobuf2/videobuf2-dma-contig.c
> @@ -706,7 +706,7 @@ static int vb2_dc_map_dmabuf(void *mem_priv)
>  	}
>  
>  	/* get the associated scatterlist for this buffer */
> -	sgt = dma_buf_map_attachment_unlocked(buf->db_attach, buf->dma_dir);
> +	sgt = dma_buf_sgt_map_attachment_unlocked(buf->db_attach, buf->dma_dir);
>  	if (IS_ERR(sgt)) {
>  		pr_err("Error getting dmabuf scatterlist\n");
>  		return -EINVAL;
> diff --git a/drivers/media/common/videobuf2/videobuf2-dma-sg.c b/drivers/media/common/videobuf2/videobuf2-dma-sg.c
> index fba2027e6e8d..17191373c69c 100644
> --- a/drivers/media/common/videobuf2/videobuf2-dma-sg.c
> +++ b/drivers/media/common/videobuf2/videobuf2-dma-sg.c
> @@ -569,7 +569,7 @@ static int vb2_dma_sg_map_dmabuf(void *mem_priv)
>  	}
>  
>  	/* get the associated scatterlist for this buffer */
> -	sgt = dma_buf_map_attachment_unlocked(buf->db_attach, buf->dma_dir);
> +	sgt = dma_buf_sgt_map_attachment_unlocked(buf->db_attach, buf->dma_dir);
>  	if (IS_ERR(sgt)) {
>  		pr_err("Error getting dmabuf scatterlist\n");
>  		return -EINVAL;
> diff --git a/drivers/media/platform/nvidia/tegra-vde/dmabuf-cache.c b/drivers/media/platform/nvidia/tegra-vde/dmabuf-cache.c
> index 7752064be783..8f3443fa0eb5 100644
> --- a/drivers/media/platform/nvidia/tegra-vde/dmabuf-cache.c
> +++ b/drivers/media/platform/nvidia/tegra-vde/dmabuf-cache.c
> @@ -102,7 +102,7 @@ int tegra_vde_dmabuf_cache_map(struct tegra_vde *vde,
>  		goto err_unlock;
>  	}
>  
> -	sgt = dma_buf_map_attachment_unlocked(attachment, dma_dir);
> +	sgt = dma_buf_sgt_map_attachment_unlocked(attachment, dma_dir);
>  	if (IS_ERR(sgt)) {
>  		dev_err(dev, "Failed to get dmabufs sg_table\n");
>  		err = PTR_ERR(sgt);
> diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c
> index 85fed3a12f9c..fce849417eb7 100644
> --- a/drivers/misc/fastrpc.c
> +++ b/drivers/misc/fastrpc.c
> @@ -911,7 +911,8 @@ static int fastrpc_map_attach(struct fastrpc_user *fl, int fd,
>  		goto attach_err;
>  	}
>  
> -	table = dma_buf_map_attachment_unlocked(map->attach, DMA_BIDIRECTIONAL);
> +	table = dma_buf_sgt_map_attachment_unlocked(map->attach,
> +						    DMA_BIDIRECTIONAL);
>  	if (IS_ERR(table)) {
>  		err = PTR_ERR(table);
>  		goto map_err;
> diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c
> index 09680534623e..fe3c43ba72c6 100644
> --- a/drivers/usb/gadget/function/f_fs.c
> +++ b/drivers/usb/gadget/function/f_fs.c
> @@ -1567,7 +1567,7 @@ static int ffs_dmabuf_attach(struct file *file, int fd)
>  	if (err)
>  		goto err_free_priv;
>  
> -	sg_table = dma_buf_map_attachment(attach, dir);
> +	sg_table = dma_buf_sgt_map_attachment(attach, dir);
>  	dma_resv_unlock(dmabuf->resv);
>  
>  	if (IS_ERR(sg_table)) {
> diff --git a/drivers/xen/gntdev-dmabuf.c b/drivers/xen/gntdev-dmabuf.c
> index 028cd7295fd7..3bb05596920e 100644
> --- a/drivers/xen/gntdev-dmabuf.c
> +++ b/drivers/xen/gntdev-dmabuf.c
> @@ -588,7 +588,7 @@ dmabuf_imp_to_refs(struct gntdev_dmabuf_priv *priv, struct device *dev,
>  
>  	gntdev_dmabuf->u.imp.attach = attach;
>  
> -	sgt = dma_buf_map_attachment_unlocked(attach, DMA_BIDIRECTIONAL);
> +	sgt = dma_buf_sgt_map_attachment_unlocked(attach, DMA_BIDIRECTIONAL);
>  	if (IS_ERR(sgt)) {
>  		ret = ERR_CAST(sgt);
>  		goto fail_detach;
> diff --git a/include/linux/dma-buf-mapping.h b/include/linux/dma-buf-mapping.h
> index 91a55cbe0bb4..02d79d5615b5 100644
> --- a/include/linux/dma-buf-mapping.h
> +++ b/include/linux/dma-buf-mapping.h
> @@ -171,7 +171,7 @@ void dma_buf_sgt_type_unmap(struct dma_buf_attachment *attach,
>   *
>   * When this type is matched the map/unmap functions are:
>   *
> - *  dma_buf_map_attachment()
> + *  dma_buf_sgt_map_attachment()
>   *  dma_buf_unmap_attachment()
>   *
>   * The struct sg_table returned by those functions has only the DMA portions
> @@ -206,7 +206,7 @@ struct dma_buf_mapping_sgt_exp_ops {
>  	/**
>  	 * @map_dma_buf:
>  	 *
> -	 * This is called by dma_buf_map_attachment() and is used to map a
> +	 * This is called by dma_buf_sgt_map_attachment() and is used to map a
>  	 * shared &dma_buf into device address space, and it is mandatory. It
>  	 * can only be called if @attach has been called successfully.
>  	 *
> diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h
> index 77a18b9817ac..ee6c97a5cecd 100644
> --- a/include/linux/dma-buf.h
> +++ b/include/linux/dma-buf.h
> @@ -515,7 +515,7 @@ struct dma_buf_attach_ops {
>   *
>   * An attachment is created by calling dma_buf_attach(), and released again by
>   * calling dma_buf_detach(). The DMA mapping itself needed to initiate a
> - * transfer is created by dma_buf_map_attachment() and freed again by calling
> + * transfer is created by dma_buf_sgt_map_attachment() and freed again by calling
>   * dma_buf_unmap_attachment().
>   */
>  struct dma_buf_attachment {
> @@ -614,8 +614,8 @@ void dma_buf_fd_install(struct dma_buf *dmabuf, int fd);
>  struct dma_buf *dma_buf_get(int fd);
>  void dma_buf_put(struct dma_buf *dmabuf);
>  
> -struct sg_table *dma_buf_map_attachment(struct dma_buf_attachment *,
> -					enum dma_data_direction);
> +struct sg_table *dma_buf_sgt_map_attachment(struct dma_buf_attachment *,
> +					    enum dma_data_direction);
>  void dma_buf_unmap_attachment(struct dma_buf_attachment *, struct sg_table *,
>  				enum dma_data_direction);
>  void dma_buf_invalidate_mappings(struct dma_buf *dma_buf);
> @@ -625,8 +625,8 @@ int dma_buf_begin_cpu_access(struct dma_buf *dma_buf,
>  int dma_buf_end_cpu_access(struct dma_buf *dma_buf,
>  			   enum dma_data_direction dir);
>  struct sg_table *
> -dma_buf_map_attachment_unlocked(struct dma_buf_attachment *attach,
> -				enum dma_data_direction direction);
> +dma_buf_sgt_map_attachment_unlocked(struct dma_buf_attachment *attach,
> +				    enum dma_data_direction direction);
>  void dma_buf_unmap_attachment_unlocked(struct dma_buf_attachment *attach,
>  				       struct sg_table *sg_table,
>  				       enum dma_data_direction direction);
> diff --git a/io_uring/zcrx.c b/io_uring/zcrx.c
> index 86d580d4410d..3f8be77a50dc 100644
> --- a/io_uring/zcrx.c
> +++ b/io_uring/zcrx.c
> @@ -182,7 +182,8 @@ static int io_import_dmabuf(struct io_zcrx_ifq *ifq,
>  		goto err;
>  	}
>  
> -	mem->sgt = dma_buf_map_attachment_unlocked(mem->attach, DMA_FROM_DEVICE);
> +	mem->sgt = dma_buf_sgt_map_attachment_unlocked(mem->attach,
> +						       DMA_FROM_DEVICE);
>  	if (IS_ERR(mem->sgt)) {
>  		ret = PTR_ERR(mem->sgt);
>  		mem->sgt = NULL;
> diff --git a/net/core/devmem.c b/net/core/devmem.c
> index f4d60654ce7f..86b3c54933bb 100644
> --- a/net/core/devmem.c
> +++ b/net/core/devmem.c
> @@ -241,8 +241,8 @@ net_devmem_bind_dmabuf(struct net_device *dev, void *vdev,
>  		goto err_exit_ref;
>  	}
>  
> -	binding->sgt = dma_buf_map_attachment_unlocked(binding->attachment,
> -						       direction);
> +	binding->sgt = dma_buf_sgt_map_attachment_unlocked(binding->attachment,
> +							   direction);
>  	if (IS_ERR(binding->sgt)) {
>  		err = PTR_ERR(binding->sgt);
>  		NL_SET_ERR_MSG(extack, "Failed to map dmabuf attachment");


^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH 23/26] treewide: Rename dma_buf_attach() to dma_buf_sgt_attach()
  2026-10-26  5:36 ` [PATCH 23/26] treewide: Rename dma_buf_attach() to dma_buf_sgt_attach() Alistair Popple
  2026-10-26 10:01   ` sashiko-bot
  2026-10-27  2:15   ` Karl Mehltretter
@ 2026-10-27 12:07   ` Christian König
  2026-10-27 12:38     ` Jason Gunthorpe
  2 siblings, 1 reply; 71+ messages in thread
From: Christian König @ 2026-10-27 12:07 UTC (permalink / raw)
  To: Alistair Popple, dri-devel, sumit.semwal, jgg
  Cc: Thomas Hellström, Simona Vetter, Matthew Brost,
	Vivek Kasireddy, Dongwon Kim, Leon Romanovsky, Kevin Tian,
	Xu Yilun, Karl Mehltretter, Baolu Lu, Felix Kuehling,
	Alex Deucher, intel-xe, amd-gfx, linux-media, linaro-mm-sig,
	linux-rdma, iommu, Alexey Kardashevskiy, zhipingz, treding,
	jhubbard

On 10/26/26 06:36, Alistair Popple wrote:
> From: Jason Gunthorpe <jgg@nvidia.com>
> 
> This attach function always creates a SGT mapping type importer.

Yeah that is a clear NO-GO. The attachment should be the same for the new interface as well.

Regards,
Christian.

> 
> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
> ---
>  Documentation/gpu/todo.rst                         |  2 +-
>  drivers/accel/amdxdna/amdxdna_gem.c                |  2 +-
>  drivers/accel/ivpu/ivpu_gem.c                      |  2 +-
>  drivers/accel/qaic/qaic_data.c                     |  2 +-
>  drivers/dma-buf/dma-buf.c                          | 14 +++++++-------
>  drivers/gpu/drm/armada/armada_gem.c                |  2 +-
>  drivers/gpu/drm/drm_gem_shmem_helper.c             |  2 +-
>  drivers/gpu/drm/drm_prime.c                        |  2 +-
>  drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c         |  2 +-
>  .../gpu/drm/i915/gem/selftests/i915_gem_dmabuf.c   |  2 +-
>  drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c          |  2 +-
>  drivers/gpu/drm/tegra/gem.c                        |  4 ++--
>  drivers/iio/industrialio-buffer.c                  |  2 +-
>  .../media/common/videobuf2/videobuf2-dma-contig.c  |  2 +-
>  drivers/media/common/videobuf2/videobuf2-dma-sg.c  |  2 +-
>  .../media/platform/nvidia/tegra-vde/dmabuf-cache.c |  2 +-
>  drivers/misc/fastrpc.c                             |  2 +-
>  drivers/usb/gadget/function/f_fs.c                 |  2 +-
>  drivers/xen/gntdev-dmabuf.c                        |  2 +-
>  include/linux/dma-buf.h                            | 10 +++++-----
>  io_uring/zcrx.c                                    |  2 +-
>  net/core/devmem.c                                  |  2 +-
>  22 files changed, 33 insertions(+), 33 deletions(-)
> 
> diff --git a/Documentation/gpu/todo.rst b/Documentation/gpu/todo.rst
> index 14cf37590fc7..be0397c197f1 100644
> --- a/Documentation/gpu/todo.rst
> +++ b/Documentation/gpu/todo.rst
> @@ -633,7 +633,7 @@ Remove automatic page mapping from dma-buf importing
>  
>  When importing dma-bufs, the dma-buf and PRIME frameworks automatically map
>  imported pages into the importer's DMA area. drm_gem_prime_fd_to_handle() and
> -drm_gem_prime_handle_to_fd() require that importers call dma_buf_attach()
> +drm_gem_prime_handle_to_fd() require that importers call dma_buf_sgt_attach()
>  even if they never do actual device DMA, but only CPU access through
>  dma_buf_vmap(). This is a problem for USB devices, which do not support DMA
>  operations.
> diff --git a/drivers/accel/amdxdna/amdxdna_gem.c b/drivers/accel/amdxdna/amdxdna_gem.c
> index a7e759bb0460..2b2f1e9fb9ec 100644
> --- a/drivers/accel/amdxdna/amdxdna_gem.c
> +++ b/drivers/accel/amdxdna/amdxdna_gem.c
> @@ -893,7 +893,7 @@ amdxdna_gem_prime_import(struct drm_device *dev, struct dma_buf *dma_buf)
>  
>  	get_dma_buf(dma_buf);
>  
> -	attach = dma_buf_attach(dma_buf, dev->dev);
> +	attach = dma_buf_sgt_attach(dma_buf, dev->dev);
>  	if (IS_ERR(attach)) {
>  		ret = PTR_ERR(attach);
>  		goto put_buf;
> diff --git a/drivers/accel/ivpu/ivpu_gem.c b/drivers/accel/ivpu/ivpu_gem.c
> index 8d6ed95ccc7c..d1c99b974a34 100644
> --- a/drivers/accel/ivpu/ivpu_gem.c
> +++ b/drivers/accel/ivpu/ivpu_gem.c
> @@ -219,7 +219,7 @@ struct drm_gem_object *ivpu_gem_prime_import(struct drm_device *dev,
>  	struct ivpu_bo *bo;
>  	int ret;
>  
> -	attach = dma_buf_attach(dma_buf, attach_dev);
> +	attach = dma_buf_sgt_attach(dma_buf, attach_dev);
>  	if (IS_ERR(attach))
>  		return ERR_CAST(attach);
>  
> diff --git a/drivers/accel/qaic/qaic_data.c b/drivers/accel/qaic/qaic_data.c
> index 92d49448df72..88331028b7bf 100644
> --- a/drivers/accel/qaic/qaic_data.c
> +++ b/drivers/accel/qaic/qaic_data.c
> @@ -850,7 +850,7 @@ struct drm_gem_object *qaic_gem_prime_import(struct drm_device *dev, struct dma_
>  	obj = &bo->base;
>  	get_dma_buf(dma_buf);
>  
> -	attach = dma_buf_attach(dma_buf, dev->dev);
> +	attach = dma_buf_sgt_attach(dma_buf, dev->dev);
>  	if (IS_ERR(attach)) {
>  		ret = PTR_ERR(attach);
>  		goto attach_fail;
> diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c
> index 12604c60122e..06bc25eff079 100644
> --- a/drivers/dma-buf/dma-buf.c
> +++ b/drivers/dma-buf/dma-buf.c
> @@ -671,7 +671,7 @@ static struct file *dma_buf_getfile(size_t size, int flags)
>   * 2. Userspace passes this file-descriptors to all drivers it wants this buffer
>   *    to share with: First the file descriptor is converted to a &dma_buf using
>   *    dma_buf_get(). Then the buffer is attached to the device using
> - *    dma_buf_attach().
> + *    dma_buf_sgt_attach().
>   *
>   *    Up to this stage the exporter is still free to migrate or reallocate the
>   *    backing storage.
> @@ -966,7 +966,7 @@ dma_buf_pin_on_map(struct dma_buf_attachment *attach)
>   * 2. Importers must not hold the dma-buf reservation lock when calling these
>   *    functions:
>   *
> - *     - dma_buf_attach()
> + *     - dma_buf_sgt_attach()
>   *     - dma_buf_dynamic_attach()
>   *     - dma_buf_detach()
>   *     - dma_buf_export()
> @@ -1100,15 +1100,15 @@ struct dma_buf_attachment *dma_buf_mapping_attach(
>  EXPORT_SYMBOL_NS_GPL(dma_buf_mapping_attach, "DMA_BUF");
>  
>  /**
> - * dma_buf_attach - Wrapper for dma_buf_mapping_attach
> + * dma_buf_sgt_attach - Wrapper for dma_buf_mapping_attach
>   * @dmabuf:	[in]	buffer to attach device to.
>   * @dev:	[in]	device to be attached.
>   *
>   * Wrapper to call dma_buf_mapping_attach() for drivers which still use a static
>   * mapping.
>   */
> -struct dma_buf_attachment *dma_buf_attach(struct dma_buf *dmabuf,
> -					  struct device *dev)
> +struct dma_buf_attachment *dma_buf_sgt_attach(struct dma_buf *dmabuf,
> +					      struct device *dev)
>  {
>  	struct dma_buf_mapping_match sgt_match[] = {
>  		DMA_BUF_IMAPPING_SGT(dev, DMA_SGT_NO_P2P),
> @@ -1117,7 +1117,7 @@ struct dma_buf_attachment *dma_buf_attach(struct dma_buf *dmabuf,
>  	return dma_buf_mapping_attach(dmabuf, sgt_match, ARRAY_SIZE(sgt_match),
>  				      NULL, NULL);
>  }
> -EXPORT_SYMBOL_NS_GPL(dma_buf_attach, "DMA_BUF");
> +EXPORT_SYMBOL_NS_GPL(dma_buf_sgt_attach, "DMA_BUF");
>  
>  /**
>   * dma_buf_dynamic_attach - Add the device to dma_buf's attachments list
> @@ -1149,7 +1149,7 @@ EXPORT_SYMBOL_NS_GPL(dma_buf_dynamic_attach, "DMA_BUF");
>   * @dmabuf:	[in]	buffer to detach from.
>   * @attach:	[in]	attachment to be detached; is free'd after this call.
>   *
> - * Clean up a device attachment obtained by calling dma_buf_attach().
> + * Clean up a device attachment obtained by calling dma_buf_sgt_attach().
>   *
>   * Optionally this calls &dma_buf_ops.detach for device-specific detach.
>   */
> diff --git a/drivers/gpu/drm/armada/armada_gem.c b/drivers/gpu/drm/armada/armada_gem.c
> index 72c7cd2b3fb9..438f33304eab 100644
> --- a/drivers/gpu/drm/armada/armada_gem.c
> +++ b/drivers/gpu/drm/armada/armada_gem.c
> @@ -518,7 +518,7 @@ armada_gem_prime_import(struct drm_device *dev, struct dma_buf *buf)
>  		}
>  	}
>  
> -	attach = dma_buf_attach(buf, dev->dev);
> +	attach = dma_buf_sgt_attach(buf, dev->dev);
>  	if (IS_ERR(attach))
>  		return ERR_CAST(attach);
>  
> diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c
> index d654a22a30de..9e937af2ee73 100644
> --- a/drivers/gpu/drm/drm_gem_shmem_helper.c
> +++ b/drivers/gpu/drm/drm_gem_shmem_helper.c
> @@ -964,7 +964,7 @@ struct drm_gem_object *drm_gem_shmem_prime_import_no_map(struct drm_device *dev,
>  		return obj;
>  	}
>  
> -	attach = dma_buf_attach(dma_buf, dev->dev);
> +	attach = dma_buf_sgt_attach(dma_buf, dev->dev);
>  	if (IS_ERR(attach))
>  		return ERR_CAST(attach);
>  
> diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c
> index 3ffbe3d28929..3084e8c28e53 100644
> --- a/drivers/gpu/drm/drm_prime.c
> +++ b/drivers/gpu/drm/drm_prime.c
> @@ -999,7 +999,7 @@ struct drm_gem_object *drm_gem_prime_import_dev(struct drm_device *dev,
>  	if (!dev->driver->gem_prime_import_sg_table)
>  		return ERR_PTR(-EINVAL);
>  
> -	attach = dma_buf_attach(dma_buf, attach_dev);
> +	attach = dma_buf_sgt_attach(dma_buf, attach_dev);
>  	if (IS_ERR(attach))
>  		return ERR_CAST(attach);
>  
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
> index 7f939c281308..9865a7a9ad8f 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
> @@ -306,7 +306,7 @@ struct drm_gem_object *i915_gem_prime_import(struct drm_device *dev,
>  		return ERR_PTR(-E2BIG);
>  
>  	/* need to attach */
> -	attach = dma_buf_attach(dma_buf, dev->dev);
> +	attach = dma_buf_sgt_attach(dma_buf, dev->dev);
>  	if (IS_ERR(attach))
>  		return ERR_CAST(attach);
>  
> diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_dmabuf.c b/drivers/gpu/drm/i915/gem/selftests/i915_gem_dmabuf.c
> index 6b6d235fd3e9..3c193e6d9d11 100644
> --- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_dmabuf.c
> +++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_dmabuf.c
> @@ -287,7 +287,7 @@ static int igt_dmabuf_import_same_driver(struct drm_i915_private *i915,
>  		goto out_import;
>  
>  	/* Now try a fake an importer */
> -	import_attach = dma_buf_attach(dmabuf, obj->base.dev->dev);
> +	import_attach = dma_buf_sgt_attach(dmabuf, obj->base.dev->dev);
>  	if (IS_ERR(import_attach)) {
>  		err = PTR_ERR(import_attach);
>  		goto out_import;
> diff --git a/drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c b/drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c
> index c549b94b2e8a..ca0962a99509 100644
> --- a/drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c
> +++ b/drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c
> @@ -115,7 +115,7 @@ struct drm_gem_object *omap_gem_prime_import(struct drm_device *dev,
>  		}
>  	}
>  
> -	attach = dma_buf_attach(dma_buf, dev->dev);
> +	attach = dma_buf_sgt_attach(dma_buf, dev->dev);
>  	if (IS_ERR(attach))
>  		return ERR_CAST(attach);
>  
> diff --git a/drivers/gpu/drm/tegra/gem.c b/drivers/gpu/drm/tegra/gem.c
> index f06826fe8366..803409824711 100644
> --- a/drivers/gpu/drm/tegra/gem.c
> +++ b/drivers/gpu/drm/tegra/gem.c
> @@ -81,7 +81,7 @@ static struct host1x_bo_mapping *tegra_bo_pin(struct device *dev, struct host1x_
>  	if (obj->dma_buf) {
>  		struct dma_buf *buf = obj->dma_buf;
>  
> -		map->attach = dma_buf_attach(buf, dev);
> +		map->attach = dma_buf_sgt_attach(buf, dev);
>  		if (IS_ERR(map->attach)) {
>  			err = PTR_ERR(map->attach);
>  			goto free;
> @@ -475,7 +475,7 @@ static struct tegra_bo *tegra_bo_import(struct drm_device *drm,
>  	 * domain, map it first to the DRM device to get an sgt.
>  	 */
>  	if (tegra->domain) {
> -		attach = dma_buf_attach(buf, drm->dev);
> +		attach = dma_buf_sgt_attach(buf, drm->dev);
>  		if (IS_ERR(attach)) {
>  			err = PTR_ERR(attach);
>  			goto free;
> diff --git a/drivers/iio/industrialio-buffer.c b/drivers/iio/industrialio-buffer.c
> index f81154642bcd..abffbcc76c4c 100644
> --- a/drivers/iio/industrialio-buffer.c
> +++ b/drivers/iio/industrialio-buffer.c
> @@ -1717,7 +1717,7 @@ static int iio_buffer_attach_dmabuf(struct iio_dev_buffer_pair *ib,
>  		goto err_free_priv;
>  	}
>  
> -	attach = dma_buf_attach(dmabuf, dma_dev);
> +	attach = dma_buf_sgt_attach(dmabuf, dma_dev);
>  	if (IS_ERR(attach)) {
>  		err = PTR_ERR(attach);
>  		goto err_dmabuf_put;
> diff --git a/drivers/media/common/videobuf2/videobuf2-dma-contig.c b/drivers/media/common/videobuf2/videobuf2-dma-contig.c
> index e13521b5c0e8..c7fa86cba8ad 100644
> --- a/drivers/media/common/videobuf2/videobuf2-dma-contig.c
> +++ b/drivers/media/common/videobuf2/videobuf2-dma-contig.c
> @@ -789,7 +789,7 @@ static void *vb2_dc_attach_dmabuf(struct vb2_buffer *vb, struct device *dev,
>  	buf->vb = vb;
>  
>  	/* create attachment for the dmabuf with the user device */
> -	dba = dma_buf_attach(dbuf, buf->dev);
> +	dba = dma_buf_sgt_attach(dbuf, buf->dev);
>  	if (IS_ERR(dba)) {
>  		pr_err("failed to attach dmabuf\n");
>  		kfree(buf);
> diff --git a/drivers/media/common/videobuf2/videobuf2-dma-sg.c b/drivers/media/common/videobuf2/videobuf2-dma-sg.c
> index 59e346a5d48b..4c93b7f58e1f 100644
> --- a/drivers/media/common/videobuf2/videobuf2-dma-sg.c
> +++ b/drivers/media/common/videobuf2/videobuf2-dma-sg.c
> @@ -638,7 +638,7 @@ static void *vb2_dma_sg_attach_dmabuf(struct vb2_buffer *vb, struct device *dev,
>  
>  	buf->dev = dev;
>  	/* create attachment for the dmabuf with the user device */
> -	dba = dma_buf_attach(dbuf, buf->dev);
> +	dba = dma_buf_sgt_attach(dbuf, buf->dev);
>  	if (IS_ERR(dba)) {
>  		pr_err("failed to attach dmabuf\n");
>  		kfree(buf);
> diff --git a/drivers/media/platform/nvidia/tegra-vde/dmabuf-cache.c b/drivers/media/platform/nvidia/tegra-vde/dmabuf-cache.c
> index 55d58a4dbbe2..d80282ebe4b4 100644
> --- a/drivers/media/platform/nvidia/tegra-vde/dmabuf-cache.c
> +++ b/drivers/media/platform/nvidia/tegra-vde/dmabuf-cache.c
> @@ -96,7 +96,7 @@ int tegra_vde_dmabuf_cache_map(struct tegra_vde *vde,
>  		goto ref;
>  	}
>  
> -	attachment = dma_buf_attach(dmabuf, dev);
> +	attachment = dma_buf_sgt_attach(dmabuf, dev);
>  	if (IS_ERR(attachment)) {
>  		dev_err(dev, "Failed to attach dmabuf\n");
>  		err = PTR_ERR(attachment);
> diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c
> index 375ce39c78c9..24ae1038b634 100644
> --- a/drivers/misc/fastrpc.c
> +++ b/drivers/misc/fastrpc.c
> @@ -904,7 +904,7 @@ static int fastrpc_map_attach(struct fastrpc_user *fl, int fd,
>  		goto get_err;
>  	}
>  
> -	map->attach = dma_buf_attach(map->buf, sess->dev);
> +	map->attach = dma_buf_sgt_attach(map->buf, sess->dev);
>  	if (IS_ERR(map->attach)) {
>  		dev_err(sess->dev, "Failed to attach dmabuf\n");
>  		err = PTR_ERR(map->attach);
> diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c
> index 4016edfa4c02..bfa24bcfe84c 100644
> --- a/drivers/usb/gadget/function/f_fs.c
> +++ b/drivers/usb/gadget/function/f_fs.c
> @@ -1549,7 +1549,7 @@ static int ffs_dmabuf_attach(struct file *file, int fd)
>  	if (IS_ERR(dmabuf))
>  		return PTR_ERR(dmabuf);
>  
> -	attach = dma_buf_attach(dmabuf, gadget->dev.parent);
> +	attach = dma_buf_sgt_attach(dmabuf, gadget->dev.parent);
>  	if (IS_ERR(attach)) {
>  		err = PTR_ERR(attach);
>  		goto err_dmabuf_put;
> diff --git a/drivers/xen/gntdev-dmabuf.c b/drivers/xen/gntdev-dmabuf.c
> index cd851eb04a69..e7ffb546e717 100644
> --- a/drivers/xen/gntdev-dmabuf.c
> +++ b/drivers/xen/gntdev-dmabuf.c
> @@ -580,7 +580,7 @@ dmabuf_imp_to_refs(struct gntdev_dmabuf_priv *priv, struct device *dev,
>  	gntdev_dmabuf->priv = priv;
>  	gntdev_dmabuf->fd = fd;
>  
> -	attach = dma_buf_attach(dma_buf, dev);
> +	attach = dma_buf_sgt_attach(dma_buf, dev);
>  	if (IS_ERR(attach)) {
>  		ret = ERR_CAST(attach);
>  		goto fail_free_obj;
> diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h
> index b264e1c4a9df..208752eb93d9 100644
> --- a/include/linux/dma-buf.h
> +++ b/include/linux/dma-buf.h
> @@ -77,7 +77,7 @@ struct dma_buf_ops {
>  	/**
>  	 * @attach:
>  	 *
> -	 * This is called from dma_buf_attach() to make sure that a given
> +	 * This is called from dma_buf_sgt_attach() to make sure that a given
>  	 * &dma_buf_attachment.dev can access the provided &dma_buf. Exporters
>  	 * which support buffer objects in special locations like VRAM or
>  	 * device-specific carveout areas should check whether the buffer could
> @@ -125,7 +125,7 @@ struct dma_buf_ops {
>  	 * exclusive with @cache_sgt_mapping.
>  	 *
>  	 * This is called automatically for non-dynamic importers from
> -	 * dma_buf_attach().
> +	 * dma_buf_sgt_attach().
>  	 *
>  	 * Note that similar to non-dynamic exporters in their @map_dma_buf
>  	 * callback the driver must guarantee that the memory is available for
> @@ -513,7 +513,7 @@ struct dma_buf_attach_ops {
>   * and its user device(s). The list contains one attachment struct per device
>   * attached to the buffer.
>   *
> - * An attachment is created by calling dma_buf_attach(), and released again by
> + * An attachment is created by calling dma_buf_sgt_attach(), and released again by
>   * calling dma_buf_detach(). The DMA mapping itself needed to initiate a
>   * transfer is created by dma_buf_sgt_map_attachment() and freed again by calling
>   * dma_buf_sgt_unmap_attachment().
> @@ -591,8 +591,8 @@ static inline bool dma_buf_is_dynamic(struct dma_buf *dmabuf)
>  	return !!dmabuf->ops->pin;
>  }
>  
> -struct dma_buf_attachment *dma_buf_attach(struct dma_buf *dmabuf,
> -					  struct device *dev);
> +struct dma_buf_attachment *dma_buf_sgt_attach(struct dma_buf *dmabuf,
> +					      struct device *dev);
>  struct dma_buf_attachment *
>  dma_buf_dynamic_attach(struct dma_buf *dmabuf, struct device *dev,
>  		       const struct dma_buf_attach_ops *importer_ops,
> diff --git a/io_uring/zcrx.c b/io_uring/zcrx.c
> index 67f74ce4f096..2cbf65b29f89 100644
> --- a/io_uring/zcrx.c
> +++ b/io_uring/zcrx.c
> @@ -175,7 +175,7 @@ static int io_import_dmabuf(struct io_zcrx_ifq *ifq,
>  		goto err;
>  	}
>  
> -	mem->attach = dma_buf_attach(mem->dmabuf, ifq->dev);
> +	mem->attach = dma_buf_sgt_attach(mem->dmabuf, ifq->dev);
>  	if (IS_ERR(mem->attach)) {
>  		ret = PTR_ERR(mem->attach);
>  		mem->attach = NULL;
> diff --git a/net/core/devmem.c b/net/core/devmem.c
> index f30fa375c9ab..d7c08da306cf 100644
> --- a/net/core/devmem.c
> +++ b/net/core/devmem.c
> @@ -234,7 +234,7 @@ net_devmem_bind_dmabuf(struct net_device *dev, void *vdev,
>  	binding->dmabuf = dmabuf;
>  	binding->direction = direction;
>  
> -	binding->attachment = dma_buf_attach(binding->dmabuf, dma_dev);
> +	binding->attachment = dma_buf_sgt_attach(binding->dmabuf, dma_dev);
>  	if (IS_ERR(binding->attachment)) {
>  		err = PTR_ERR(binding->attachment);
>  		NL_SET_ERR_MSG(extack, "Failed to bind dmabuf to device");


^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH 23/26] treewide: Rename dma_buf_attach() to dma_buf_sgt_attach()
  2026-10-27  2:15   ` Karl Mehltretter
  2026-10-27  3:42     ` Mikko Perttunen
@ 2026-10-27 12:11     ` Christian König
  2026-10-27 12:31     ` Jason Gunthorpe
  2 siblings, 0 replies; 71+ messages in thread
From: Christian König @ 2026-10-27 12:11 UTC (permalink / raw)
  To: Karl Mehltretter, Alistair Popple
  Cc: dri-devel, sumit.semwal, jgg, Thomas Hellström,
	Simona Vetter, Matthew Brost, Vivek Kasireddy, Dongwon Kim,
	Leon Romanovsky, Kevin Tian, Xu Yilun, Baolu Lu, Felix Kuehling,
	Alex Deucher, intel-xe, amd-gfx, linux-media, linaro-mm-sig,
	linux-rdma, iommu, Alexey Kardashevskiy, zhipingz, treding,
	jhubbard

On 10/27/26 03:15, Karl Mehltretter wrote:
> On Mon, Oct 26, 2026 at 04:36:14PM +0100, Alistair Popple wrote:
> 
> Testing the series on a Jetson Nano exposed this path. A 3 MiB system-heap
> buffer was imported into Tegra DRM and scanned out over HDMI. With
> CONFIG_DMABUF_DEBUG=y the PRIME import succeeded, but scanout immediately
> produced display SMMU faults starting at 0x300000.
> 
> Tracing the fault led here:
> 
>> @@ -475,7 +475,7 @@ static struct tegra_bo *tegra_bo_import(struct drm_device *drm,
>>  	 * domain, map it first to the DRM device to get an sgt.
>>  	 */
>>  	if (tegra->domain) {
>> -		attach = dma_buf_attach(buf, drm->dev);
>> +		attach = dma_buf_sgt_attach(buf, drm->dev);
> 
> tegra_bo_import() passes the attachment SGT to iommu_map_sgtable(), which
> uses sg_phys() and sg->length. The SGT mapping contract only guarantees the
> DMA address and length fields. The debug wrapper clears the page-side fields,
> so iommu_map_sgtable() maps zero bytes. 
> 
> Tegra only treats negative returns as errors and keeps the reserved
> IOVA, which scanout then faults on.
> 
> This page-side use predates the series, so the fault is not itself a v2
> regression. Is dma_buf_sgt_attach() valid for this call site, or does Tegra
> need a page/physical mapping type first?

Sharing page/physical to be used with the IOMMU functions through DMA-buf is an absolutely hard NAK from my side.

We still need to figure out how to do this between KVM, IOMMUFD and virtio so that it is limited to only those three.

Regards,
Christian.

> 
> Karl


^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH 23/26] treewide: Rename dma_buf_attach() to dma_buf_sgt_attach()
  2026-10-27  2:15   ` Karl Mehltretter
  2026-10-27  3:42     ` Mikko Perttunen
  2026-10-27 12:11     ` Christian König
@ 2026-10-27 12:31     ` Jason Gunthorpe
  2 siblings, 0 replies; 71+ messages in thread
From: Jason Gunthorpe @ 2026-10-27 12:31 UTC (permalink / raw)
  To: Karl Mehltretter
  Cc: Alistair Popple, dri-devel, christian.koenig, sumit.semwal,
	Thomas Hellström, Simona Vetter, Matthew Brost,
	Vivek Kasireddy, Dongwon Kim, Leon Romanovsky, Kevin Tian,
	Xu Yilun, Baolu Lu, Felix Kuehling, Alex Deucher, intel-xe,
	amd-gfx, linux-media, linaro-mm-sig, linux-rdma, iommu,
	Alexey Kardashevskiy, zhipingz, treding, jhubbard

On Tue, Oct 27, 2026 at 03:15:34AM +0100, Karl Mehltretter wrote:
> On Mon, Oct 26, 2026 at 04:36:14PM +0100, Alistair Popple wrote:
> 
> Testing the series on a Jetson Nano exposed this path. A 3 MiB system-heap
> buffer was imported into Tegra DRM and scanned out over HDMI. With
> CONFIG_DMABUF_DEBUG=y the PRIME import succeeded, but scanout immediately
> produced display SMMU faults starting at 0x300000.

Why is this being reported here? Shouldn't CONFIG_DMABUF_DEBUG=y have
always caused tegra to fail?

> > @@ -475,7 +475,7 @@ static struct tegra_bo *tegra_bo_import(struct drm_device *drm,
> >  	 * domain, map it first to the DRM device to get an sgt.
> >  	 */
> >  	if (tegra->domain) {
> > -		attach = dma_buf_attach(buf, drm->dev);
> > +		attach = dma_buf_sgt_attach(buf, drm->dev);
> 
> tegra_bo_import() passes the attachment SGT to iommu_map_sgtable(),
> which

This is illegal use of dmabuf, this was discussed in some other driver
recently.

All DRM drivers trying to use custom iommu domains are busted this
way. AFAIK there is no solution besides "don't do that".

> This page-side use predates the series, so the fault is not itself a v2
> regression. Is dma_buf_sgt_attach() valid for this call site, or does Tegra
> need a page/physical mapping type first?

Tegra is broken.

Jason

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH 23/26] treewide: Rename dma_buf_attach() to dma_buf_sgt_attach()
  2026-10-27  3:42     ` Mikko Perttunen
@ 2026-10-27 12:33       ` Jason Gunthorpe
  2026-10-27 13:34         ` Mikko Perttunen
  0 siblings, 1 reply; 71+ messages in thread
From: Jason Gunthorpe @ 2026-10-27 12:33 UTC (permalink / raw)
  To: Mikko Perttunen
  Cc: Alistair Popple, linux-rdma, dri-devel, christian.koenig,
	sumit.semwal, Thomas Hellström, Simona Vetter, Matthew Brost,
	Vivek Kasireddy, Dongwon Kim, Leon Romanovsky, Kevin Tian,
	Xu Yilun, Baolu Lu, Felix Kuehling, Alex Deucher, intel-xe,
	amd-gfx, linux-media, linaro-mm-sig, iommu, Alexey Kardashevskiy,
	zhipingz, treding, jhubbard, Karl Mehltretter

On Tue, Oct 27, 2026 at 12:42:32PM +0900, Mikko Perttunen wrote:

> > This page-side use predates the series, so the fault is not itself a v2
> > regression. Is dma_buf_sgt_attach() valid for this call site, or does Tegra
> > need a page/physical mapping type first?
> 
> Sounds like a bug in TegraDRM; we should be using the DMA addr/length 
> for the explicit IOMMU mapping as the sgt attachment is for the dummy 
> DRM device explicitly intended to give us physical addresses.

No, you cannot connect dmabuf to an iommu_domain. It is 100% always
illegal. DMABUF does not support this. Do not pass sg_dma to iommu
functions either.

> I'm currently in the process of removing the whole explicit IOMMU path 
> so if this only occurs with CONFIG_DMABUF_DEBUG enabled, I don't think 
> there's a pressing need to fix this before then.

Yes I think this is probably the only way to fix it :| You have to
always use the DMA API

Jason

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH 21/26] treewide: Rename dma_buf_map_attachment(_unlocked) to dma_buf_sgt_
  2026-10-27 12:05   ` Christian König
@ 2026-10-27 12:35     ` Jason Gunthorpe
  0 siblings, 0 replies; 71+ messages in thread
From: Jason Gunthorpe @ 2026-10-27 12:35 UTC (permalink / raw)
  To: Christian König
  Cc: Alistair Popple, dri-devel, sumit.semwal, Thomas Hellström,
	Simona Vetter, Matthew Brost, Vivek Kasireddy, Dongwon Kim,
	Leon Romanovsky, Kevin Tian, Xu Yilun, Karl Mehltretter, Baolu Lu,
	Felix Kuehling, Alex Deucher, intel-xe, amd-gfx, linux-media,
	linaro-mm-sig, linux-rdma, iommu, Alexey Kardashevskiy, zhipingz,
	treding, jhubbard

On Tue, Oct 27, 2026 at 01:05:55PM +0100, Christian König wrote:
> On 10/26/26 06:36, Alistair Popple wrote:
> > From: Jason Gunthorpe <jgg@nvidia.com>
> > 
> > This map function only works with SGT importers.
> > 
> > Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
> > [ also rename the io_uring zcrx caller, which the unmap rename
> >   used to pick up, so that this commit builds with CONFIG_IO_URING_ZCRX - apopple ]
> > Signed-off-by: Alistair Popple <apopple@nvidia.com>
> 
> I would make that the first patch in the set since dropping sgt from
> the interface is probably something everybody can agree on.
> 
> And sqash that together with renaming dma_buf_unmap_attachment().
> 
> Regarding the new name I think dma_buf_sgt_(un)map_attachment() is a
> bit long and has the sgt at the wrong location.
> 
> I would name the functions dma_buf_map_sgt() and dma_buf_unmap_sgt().

I was going for a namespace 'dma_buf_sgt_X' would capture all the
functions related to the sgt mapping type and so on for other types.

Jason

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH 23/26] treewide: Rename dma_buf_attach() to dma_buf_sgt_attach()
  2026-10-27 12:07   ` Christian König
@ 2026-10-27 12:38     ` Jason Gunthorpe
  2026-10-27 13:17       ` Christian König
  0 siblings, 1 reply; 71+ messages in thread
From: Jason Gunthorpe @ 2026-10-27 12:38 UTC (permalink / raw)
  To: Christian König
  Cc: Alistair Popple, dri-devel, sumit.semwal, Thomas Hellström,
	Simona Vetter, Matthew Brost, Vivek Kasireddy, Dongwon Kim,
	Leon Romanovsky, Kevin Tian, Xu Yilun, Karl Mehltretter, Baolu Lu,
	Felix Kuehling, Alex Deucher, intel-xe, amd-gfx, linux-media,
	linaro-mm-sig, linux-rdma, iommu, Alexey Kardashevskiy, zhipingz,
	treding, jhubbard

On Tue, Oct 27, 2026 at 01:07:36PM +0100, Christian König wrote:
> On 10/26/26 06:36, Alistair Popple wrote:
> > From: Jason Gunthorpe <jgg@nvidia.com>
> > 
> > This attach function always creates a SGT mapping type importer.
> 
> Yeah that is a clear NO-GO. The attachment should be the same for
> the new interface as well.

Not sure I understand this comment...

This was intended as a helper so that existing drivers can run through
the sgt based mapping type flow without having to open code it. It is
hardwired to only do sgt like this. If you want to use more than sgt
as your mapping type don't use this function

The point was to create a clear distinction in the API names when
things were in a SGT-only flow vs using the newer negotiable flow.

> > Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>

Alistair since you rebased it you should put your SOB on every
patch...

Regards,
Jason

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH 23/26] treewide: Rename dma_buf_attach() to dma_buf_sgt_attach()
  2026-10-27 12:38     ` Jason Gunthorpe
@ 2026-10-27 13:17       ` Christian König
  2026-10-27 14:08         ` Jason Gunthorpe
  0 siblings, 1 reply; 71+ messages in thread
From: Christian König @ 2026-10-27 13:17 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: Alistair Popple, dri-devel, sumit.semwal, Thomas Hellström,
	Simona Vetter, Matthew Brost, Vivek Kasireddy, Dongwon Kim,
	Leon Romanovsky, Kevin Tian, Xu Yilun, Karl Mehltretter, Baolu Lu,
	Felix Kuehling, Alex Deucher, intel-xe, amd-gfx, linux-media,
	linaro-mm-sig, linux-rdma, iommu, Alexey Kardashevskiy, zhipingz,
	treding, jhubbard

On 10/27/26 13:38, Jason Gunthorpe wrote:
> On Tue, Oct 27, 2026 at 01:07:36PM +0100, Christian König wrote:
>> On 10/26/26 06:36, Alistair Popple wrote:
>>> From: Jason Gunthorpe <jgg@nvidia.com>
>>>
>>> This attach function always creates a SGT mapping type importer.
>>
>> Yeah that is a clear NO-GO. The attachment should be the same for
>> the new interface as well.
> 
> Not sure I understand this comment...
> 
> This was intended as a helper so that existing drivers can run through
> the sgt based mapping type flow without having to open code it. It is
> hardwired to only do sgt like this. If you want to use more than sgt
> as your mapping type don't use this function
> 
> The point was to create a clear distinction in the API names when
> things were in a SGT-only flow vs using the newer negotiable flow.

Well that is my point, the dma_buf_attach() or rather dynamic_attach() function should still be part of the new flow.

The only difference is that the importer ops given to the dynamic_attach() functions now also contain the information necessary for the negotiation.

Regards,
Christian.

> 
>>> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
> 
> Alistair since you rebased it you should put your SOB on every
> patch...
> 
> Regards,
> Jason


^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH 23/26] treewide: Rename dma_buf_attach() to dma_buf_sgt_attach()
  2026-10-27 12:33       ` Jason Gunthorpe
@ 2026-10-27 13:34         ` Mikko Perttunen
  2026-10-27 13:43           ` Christian König
  0 siblings, 1 reply; 71+ messages in thread
From: Mikko Perttunen @ 2026-10-27 13:34 UTC (permalink / raw)
  To: linux-rdma
  Cc: Alistair Popple, linux-rdma, dri-devel, christian.koenig,
	sumit.semwal, Thomas Hellström, Simona Vetter, Matthew Brost,
	Vivek Kasireddy, Dongwon Kim, Leon Romanovsky, Kevin Tian,
	Xu Yilun, Baolu Lu, Felix Kuehling, Alex Deucher, intel-xe,
	amd-gfx, linux-media, linaro-mm-sig, iommu, Alexey Kardashevskiy,
	zhipingz, treding, jhubbard, Karl Mehltretter, Jason Gunthorpe

On Tuesday, October 27, 2026 9:33 PM Jason Gunthorpe wrote:
> On Tue, Oct 27, 2026 at 12:42:32PM +0900, Mikko Perttunen wrote:
> 
> > > This page-side use predates the series, so the fault is not itself a v2
> > > regression. Is dma_buf_sgt_attach() valid for this call site, or does Tegra
> > > need a page/physical mapping type first?
> > 
> > Sounds like a bug in TegraDRM; we should be using the DMA addr/length 
> > for the explicit IOMMU mapping as the sgt attachment is for the dummy 
> > DRM device explicitly intended to give us physical addresses.
> 
> No, you cannot connect dmabuf to an iommu_domain. It is 100% always
> illegal. DMABUF does not support this. Do not pass sg_dma to iommu
> functions either.

Sure, I agree -- so let's say it's a bug on top of the baseline crimes 
TegraDRM commits :)

> 
> > I'm currently in the process of removing the whole explicit IOMMU path 
> > so if this only occurs with CONFIG_DMABUF_DEBUG enabled, I don't think 
> > there's a pressing need to fix this before then.
> 
> Yes I think this is probably the only way to fix it :| You have to
> always use the DMA API
> 
> Jason
> 





^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH 23/26] treewide: Rename dma_buf_attach() to dma_buf_sgt_attach()
  2026-10-27 13:34         ` Mikko Perttunen
@ 2026-10-27 13:43           ` Christian König
  0 siblings, 0 replies; 71+ messages in thread
From: Christian König @ 2026-10-27 13:43 UTC (permalink / raw)
  To: Mikko Perttunen, linux-rdma
  Cc: Alistair Popple, dri-devel, sumit.semwal, Thomas Hellström,
	Simona Vetter, Matthew Brost, Vivek Kasireddy, Dongwon Kim,
	Leon Romanovsky, Kevin Tian, Xu Yilun, Baolu Lu, Felix Kuehling,
	Alex Deucher, intel-xe, amd-gfx, linux-media, linaro-mm-sig,
	iommu, Alexey Kardashevskiy, zhipingz, treding, jhubbard,
	Karl Mehltretter, Jason Gunthorpe

On 10/27/26 14:34, Mikko Perttunen wrote:
> On Tuesday, October 27, 2026 9:33 PM Jason Gunthorpe wrote:
>> On Tue, Oct 27, 2026 at 12:42:32PM +0900, Mikko Perttunen wrote:
>>
>>>> This page-side use predates the series, so the fault is not itself a v2
>>>> regression. Is dma_buf_sgt_attach() valid for this call site, or does Tegra
>>>> need a page/physical mapping type first?
>>>
>>> Sounds like a bug in TegraDRM; we should be using the DMA addr/length 
>>> for the explicit IOMMU mapping as the sgt attachment is for the dummy 
>>> DRM device explicitly intended to give us physical addresses.
>>
>> No, you cannot connect dmabuf to an iommu_domain. It is 100% always
>> illegal. DMABUF does not support this. Do not pass sg_dma to iommu
>> functions either.
> 
> Sure, I agree -- so let's say it's a bug on top of the baseline crimes 
> TegraDRM commits :)

Well the initial crime was to abuse sgt to transport dma addresses, don't document how all of this works and then be surprised when everything blew up.

But yeah don't touch the pages in sgt exposed by DMA-buf, that is pretty much one of the most fundamental rules we have now.

Regards,
Christian.

> 
>>
>>> I'm currently in the process of removing the whole explicit IOMMU path 
>>> so if this only occurs with CONFIG_DMABUF_DEBUG enabled, I don't think 
>>> there's a pressing need to fix this before then.
>>
>> Yes I think this is probably the only way to fix it :| You have to
>> always use the DMA API
>>
>> Jason
>>
> 
> 
> 
> 


^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH 23/26] treewide: Rename dma_buf_attach() to dma_buf_sgt_attach()
  2026-10-27 13:17       ` Christian König
@ 2026-10-27 14:08         ` Jason Gunthorpe
  2026-10-27 14:28           ` Christian König
  0 siblings, 1 reply; 71+ messages in thread
From: Jason Gunthorpe @ 2026-10-27 14:08 UTC (permalink / raw)
  To: Christian König
  Cc: Alistair Popple, dri-devel, sumit.semwal, Thomas Hellström,
	Simona Vetter, Matthew Brost, Vivek Kasireddy, Dongwon Kim,
	Leon Romanovsky, Kevin Tian, Xu Yilun, Karl Mehltretter, Baolu Lu,
	Felix Kuehling, Alex Deucher, intel-xe, amd-gfx, linux-media,
	linaro-mm-sig, linux-rdma, iommu, Alexey Kardashevskiy, zhipingz,
	treding, jhubbard

On Tue, Oct 27, 2026 at 02:17:16PM +0100, Christian König wrote:
> On 10/27/26 13:38, Jason Gunthorpe wrote:
> > On Tue, Oct 27, 2026 at 01:07:36PM +0100, Christian König wrote:
> >> On 10/26/26 06:36, Alistair Popple wrote:
> >>> From: Jason Gunthorpe <jgg@nvidia.com>
> >>>
> >>> This attach function always creates a SGT mapping type importer.
> >>
> >> Yeah that is a clear NO-GO. The attachment should be the same for
> >> the new interface as well.
> > 
> > Not sure I understand this comment...
> > 
> > This was intended as a helper so that existing drivers can run through
> > the sgt based mapping type flow without having to open code it. It is
> > hardwired to only do sgt like this. If you want to use more than sgt
> > as your mapping type don't use this function
> > 
> > The point was to create a clear distinction in the API names when
> > things were in a SGT-only flow vs using the newer negotiable flow.
> 
> Well that is my point, the dma_buf_attach() or rather
> dynamic_attach() function should still be part of the new flow.

It is, this is just a helper wrapper effectively to run the flow
exactly as it is right now wired to only do sgt.

Unless you want to see that open coded in ever driver using the more
general functions, I'm not sure I see the alternative?

Jason

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH 23/26] treewide: Rename dma_buf_attach() to dma_buf_sgt_attach()
  2026-10-27 14:08         ` Jason Gunthorpe
@ 2026-10-27 14:28           ` Christian König
  2026-10-27 14:44             ` Jason Gunthorpe
  0 siblings, 1 reply; 71+ messages in thread
From: Christian König @ 2026-10-27 14:28 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: Alistair Popple, dri-devel, sumit.semwal, Thomas Hellström,
	Simona Vetter, Matthew Brost, Vivek Kasireddy, Dongwon Kim,
	Leon Romanovsky, Kevin Tian, Xu Yilun, Karl Mehltretter, Baolu Lu,
	Felix Kuehling, Alex Deucher, intel-xe, amd-gfx, linux-media,
	linaro-mm-sig, linux-rdma, iommu, Alexey Kardashevskiy, zhipingz,
	treding, jhubbard

On 10/27/26 15:08, Jason Gunthorpe wrote:
> On Tue, Oct 27, 2026 at 02:17:16PM +0100, Christian König wrote:
>> On 10/27/26 13:38, Jason Gunthorpe wrote:
>>> On Tue, Oct 27, 2026 at 01:07:36PM +0100, Christian König wrote:
>>>> On 10/26/26 06:36, Alistair Popple wrote:
>>>>> From: Jason Gunthorpe <jgg@nvidia.com>
>>>>>
>>>>> This attach function always creates a SGT mapping type importer.
>>>>
>>>> Yeah that is a clear NO-GO. The attachment should be the same for
>>>> the new interface as well.
>>>
>>> Not sure I understand this comment...
>>>
>>> This was intended as a helper so that existing drivers can run through
>>> the sgt based mapping type flow without having to open code it. It is
>>> hardwired to only do sgt like this. If you want to use more than sgt
>>> as your mapping type don't use this function
>>>
>>> The point was to create a clear distinction in the API names when
>>> things were in a SGT-only flow vs using the newer negotiable flow.
>>
>> Well that is my point, the dma_buf_attach() or rather
>> dynamic_attach() function should still be part of the new flow.
> 
> It is, this is just a helper wrapper effectively to run the flow
> exactly as it is right now wired to only do sgt.
> 
> Unless you want to see that open coded in ever driver using the more
> general functions, I'm not sure I see the alternative?

I still don't see what you mean.

If a driver can only deal with sgt then it won't implement the dma_buf_attach_ops->supported_mapping_types (or whatever we name that).

So if either dma_buf_attach_ops is NULL or dma_buf_attach_ops->supported_mapping_types is NULL then we only match to the sgt export.

What I want to avoid is to get just another dma_buf_attach() variant since we already added a parameter structure here.

Regards,
Christian.

> 
> Jason


^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH 23/26] treewide: Rename dma_buf_attach() to dma_buf_sgt_attach()
  2026-10-27 14:28           ` Christian König
@ 2026-10-27 14:44             ` Jason Gunthorpe
  2026-10-27 14:54               ` Christian König
  0 siblings, 1 reply; 71+ messages in thread
From: Jason Gunthorpe @ 2026-10-27 14:44 UTC (permalink / raw)
  To: Christian König
  Cc: Alistair Popple, dri-devel, sumit.semwal, Thomas Hellström,
	Simona Vetter, Matthew Brost, Vivek Kasireddy, Dongwon Kim,
	Leon Romanovsky, Kevin Tian, Xu Yilun, Karl Mehltretter, Baolu Lu,
	Felix Kuehling, Alex Deucher, intel-xe, amd-gfx, linux-media,
	linaro-mm-sig, linux-rdma, iommu, Alexey Kardashevskiy, zhipingz,
	treding, jhubbard

On Tue, Oct 27, 2026 at 03:28:44PM +0100, Christian König wrote:
> On 10/27/26 15:08, Jason Gunthorpe wrote:
> > On Tue, Oct 27, 2026 at 02:17:16PM +0100, Christian König wrote:
> >> On 10/27/26 13:38, Jason Gunthorpe wrote:
> >>> On Tue, Oct 27, 2026 at 01:07:36PM +0100, Christian König wrote:
> >>>> On 10/26/26 06:36, Alistair Popple wrote:
> >>>>> From: Jason Gunthorpe <jgg@nvidia.com>
> >>>>>
> >>>>> This attach function always creates a SGT mapping type importer.
> >>>>
> >>>> Yeah that is a clear NO-GO. The attachment should be the same for
> >>>> the new interface as well.
> >>>
> >>> Not sure I understand this comment...
> >>>
> >>> This was intended as a helper so that existing drivers can run through
> >>> the sgt based mapping type flow without having to open code it. It is
> >>> hardwired to only do sgt like this. If you want to use more than sgt
> >>> as your mapping type don't use this function
> >>>
> >>> The point was to create a clear distinction in the API names when
> >>> things were in a SGT-only flow vs using the newer negotiable flow.
> >>
> >> Well that is my point, the dma_buf_attach() or rather
> >> dynamic_attach() function should still be part of the new flow.
> > 
> > It is, this is just a helper wrapper effectively to run the flow
> > exactly as it is right now wired to only do sgt.
> > 
> > Unless you want to see that open coded in ever driver using the more
> > general functions, I'm not sure I see the alternative?
> 
> I still don't see what you mean.

The function is this:

struct dma_buf_attachment *dma_buf_sgt_attach(struct dma_buf *dmabuf,
					      struct device *dev)
{
	struct dma_buf_mapping_match sgt_match[] = {
		DMA_BUF_IMAPPING_SGT(dev, DMA_SGT_NO_P2P),
	};

	return dma_buf_mapping_attach(dmabuf, sgt_match, ARRAY_SIZE(sgt_match),
				      NULL, NULL);
}
EXPORT_SYMBOL_NS_GPL(dma_buf_sgt_attach, "DMA_BUF");

Which is just a wrapper around the more general attach function,
forcing it to do SGT.

I don't see why we should label a function that can ony do SGT anything
other than under the SGT names.

If you want to get rid of it then the above has to get dropped into
every caller, or something like...

> If a driver can only deal with sgt then it won't implement the
> dma_buf_attach_ops->supported_mapping_types (or whatever we name
> that).
> 
> So if either dma_buf_attach_ops is NULL or
> dma_buf_attach_ops->supported_mapping_types is NULL then we only
> match to the sgt export.

This is basically changing how dma_buf_mapping_attach() works to hard
wire in SGT behaviors. I think this is something you'd regret down the
road as it starts muddling up different concerns..

dma_buf_sgt_attach() is very readable for what the driver is doing,
and grepable. Implicitly doing things when other things are NULL is
more indirect.

> What I want to avoid is to get just another dma_buf_attach() variant
> since we already added a parameter structure here.

It is a pretty standard kernel style to do things like this rather
than expose super APIs with complex signatures to every caller. If
there are many places with the same operation it does tend to help
alot to mark them with a helper function like this.

Jason

^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH 23/26] treewide: Rename dma_buf_attach() to dma_buf_sgt_attach()
  2026-10-27 14:44             ` Jason Gunthorpe
@ 2026-10-27 14:54               ` Christian König
  0 siblings, 0 replies; 71+ messages in thread
From: Christian König @ 2026-10-27 14:54 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: Alistair Popple, dri-devel, sumit.semwal, Thomas Hellström,
	Simona Vetter, Matthew Brost, Vivek Kasireddy, Dongwon Kim,
	Leon Romanovsky, Kevin Tian, Xu Yilun, Karl Mehltretter, Baolu Lu,
	Felix Kuehling, Alex Deucher, intel-xe, amd-gfx, linux-media,
	linaro-mm-sig, linux-rdma, iommu, Alexey Kardashevskiy, zhipingz,
	treding, jhubbard

On 10/27/26 15:44, Jason Gunthorpe wrote:
> On Tue, Oct 27, 2026 at 03:28:44PM +0100, Christian König wrote:
>> On 10/27/26 15:08, Jason Gunthorpe wrote:
>>> On Tue, Oct 27, 2026 at 02:17:16PM +0100, Christian König wrote:
>>>> On 10/27/26 13:38, Jason Gunthorpe wrote:
>>>>> On Tue, Oct 27, 2026 at 01:07:36PM +0100, Christian König wrote:
>>>>>> On 10/26/26 06:36, Alistair Popple wrote:
>>>>>>> From: Jason Gunthorpe <jgg@nvidia.com>
>>>>>>>
>>>>>>> This attach function always creates a SGT mapping type importer.
>>>>>>
>>>>>> Yeah that is a clear NO-GO. The attachment should be the same for
>>>>>> the new interface as well.
>>>>>
>>>>> Not sure I understand this comment...
>>>>>
>>>>> This was intended as a helper so that existing drivers can run through
>>>>> the sgt based mapping type flow without having to open code it. It is
>>>>> hardwired to only do sgt like this. If you want to use more than sgt
>>>>> as your mapping type don't use this function
>>>>>
>>>>> The point was to create a clear distinction in the API names when
>>>>> things were in a SGT-only flow vs using the newer negotiable flow.
>>>>
>>>> Well that is my point, the dma_buf_attach() or rather
>>>> dynamic_attach() function should still be part of the new flow.
>>>
>>> It is, this is just a helper wrapper effectively to run the flow
>>> exactly as it is right now wired to only do sgt.
>>>
>>> Unless you want to see that open coded in ever driver using the more
>>> general functions, I'm not sure I see the alternative?
>>
>> I still don't see what you mean.
> 
> The function is this:
> 
> struct dma_buf_attachment *dma_buf_sgt_attach(struct dma_buf *dmabuf,
> 					      struct device *dev)
> {
> 	struct dma_buf_mapping_match sgt_match[] = {
> 		DMA_BUF_IMAPPING_SGT(dev, DMA_SGT_NO_P2P),
> 	};
> 
> 	return dma_buf_mapping_attach(dmabuf, sgt_match, ARRAY_SIZE(sgt_match),
> 				      NULL, NULL);

Yeah. exactly that is a clear NO-GO from my side.

The existing dma_buf_dynamic_attach() function should already have everything you need to negotiate the mapping type.

Don't add any new dma_buf_mapping_attach() function since attachments are generally not mapping related.

Regards,
Christian.


> }
> EXPORT_SYMBOL_NS_GPL(dma_buf_sgt_attach, "DMA_BUF");
> 
> Which is just a wrapper around the more general attach function,
> forcing it to do SGT.
> 
> I don't see why we should label a function that can ony do SGT anything
> other than under the SGT names.
> 
> If you want to get rid of it then the above has to get dropped into
> every caller, or something like...
> 
>> If a driver can only deal with sgt then it won't implement the
>> dma_buf_attach_ops->supported_mapping_types (or whatever we name
>> that).
>>
>> So if either dma_buf_attach_ops is NULL or
>> dma_buf_attach_ops->supported_mapping_types is NULL then we only
>> match to the sgt export.
> 
> This is basically changing how dma_buf_mapping_attach() works to hard
> wire in SGT behaviors. I think this is something you'd regret down the
> road as it starts muddling up different concerns..
> 
> dma_buf_sgt_attach() is very readable for what the driver is doing,
> and grepable. Implicitly doing things when other things are NULL is
> more indirect.
> 
>> What I want to avoid is to get just another dma_buf_attach() variant
>> since we already added a parameter structure here.
> 
> It is a pretty standard kernel style to do things like this rather
> than expose super APIs with complex signatures to every caller. If
> there are many places with the same operation it does tend to help
> alot to mark them with a helper function like this.
> 
> Jason


^ permalink raw reply	[flat|nested] 71+ messages in thread

end of thread, other threads:[~2026-10-27 14:54 UTC | newest]

Thread overview: 71+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-26  5:35 [PATCH 00/26] DMA-buf mapping types Alistair Popple
2026-10-26  5:35 ` [PATCH 01/26] dma-buf: Introduce " Alistair Popple
2026-10-26  7:00   ` sashiko-bot
2026-10-26  5:35 ` [PATCH 02/26] dma-buf: Add the SGT DMA mapping type Alistair Popple
2026-10-26  7:04   ` sashiko-bot
2026-10-26  5:35 ` [PATCH 03/26] dma-buf: Add dma_buf_mapping_attach() Alistair Popple
2026-10-26  7:20   ` sashiko-bot
2026-10-26  5:35 ` [PATCH 04/26] dma-buf: Route SGT related actions through attach->map_type Alistair Popple
2026-10-26  7:29   ` sashiko-bot
2026-10-26  5:35 ` [PATCH 05/26] dma-buf: Let the exporter select mapping type at pin/map Alistair Popple
2026-10-26  7:39   ` sashiko-bot
2026-10-26  8:03   ` Karl Mehltretter
2026-10-27  5:46     ` Alistair Popple
2026-10-26  5:35 ` [PATCH 06/26] dma-buf: Add match set queries for exporter placement decisions Alistair Popple
2026-10-26  7:42   ` sashiko-bot
2026-10-26  5:35 ` [PATCH 07/26] dma-buf: Add dma_buf_mapping_map() returning a type-tagged mapping Alistair Popple
2026-10-26  7:56   ` sashiko-bot
2026-10-26  5:35 ` [PATCH 08/26] dma-buf: Allow single exporter drivers to avoid the match_mapping function Alistair Popple
2026-10-26  7:58   ` sashiko-bot
2026-10-26  5:36 ` [PATCH 09/26] drm: Check the SGT ops for drm_gem_map_dma_buf() Alistair Popple
2026-10-26  8:02   ` sashiko-bot
2026-10-26  5:36 ` [PATCH 10/26] dma-buf: Convert all the simple exporters to use SGT mapping type Alistair Popple
2026-10-26  8:12   ` sashiko-bot
2026-10-26  5:36 ` [PATCH 11/26] drm/vmwgfx: Use match_mapping instead of dummy calls Alistair Popple
2026-10-26  8:13   ` sashiko-bot
2026-10-26  5:36 ` [PATCH 12/26] accel/habanalabs: Use the SGT_P2P mapping type Alistair Popple
2026-10-26  8:18   ` sashiko-bot
2026-10-26  5:36 ` [PATCH 13/26] drm/xe/dma-buf: Use the SGT " Alistair Popple
2026-10-26  8:34   ` sashiko-bot
2026-10-26  5:36 ` [PATCH 14/26] drm/amdgpu: " Alistair Popple
2026-10-26  8:46   ` sashiko-bot
2026-10-26  5:36 ` [PATCH 15/26] vfio/pci: Change the DMA-buf exporter to use mapping_type Alistair Popple
2026-10-26  9:00   ` sashiko-bot
2026-10-26  5:36 ` [PATCH 16/26] RDMA/uverbs: Use the SGT_P2P mapping type Alistair Popple
2026-10-26  9:16   ` sashiko-bot
2026-10-26  5:36 ` [PATCH 17/26] dma-buf: Update dma_buf_phys_vec_to_sgt() to use the SGT " Alistair Popple
2026-10-26  9:26   ` sashiko-bot
2026-10-26  5:36 ` [PATCH 18/26] iio: buffer: convert " Alistair Popple
2026-10-26  9:28   ` sashiko-bot
2026-10-26  5:36 ` [PATCH 19/26] functionfs: " Alistair Popple
2026-10-26  9:35   ` sashiko-bot
2026-10-26  5:36 ` [PATCH 20/26] dma-buf: Remove unused SGT stuff from the common structures Alistair Popple
2026-10-26  9:39   ` sashiko-bot
2026-10-26  5:36 ` [PATCH 21/26] treewide: Rename dma_buf_map_attachment(_unlocked) to dma_buf_sgt_ Alistair Popple
2026-10-26  9:49   ` sashiko-bot
2026-10-27 12:05   ` Christian König
2026-10-27 12:35     ` Jason Gunthorpe
2026-10-26  5:36 ` [PATCH 22/26] treewide: Rename dma_buf_unmap_attachment(_unlocked) to dma_buf_sgt_* Alistair Popple
2026-10-26  9:56   ` sashiko-bot
2026-10-26  5:36 ` [PATCH 23/26] treewide: Rename dma_buf_attach() to dma_buf_sgt_attach() Alistair Popple
2026-10-26 10:01   ` sashiko-bot
2026-10-27  2:15   ` Karl Mehltretter
2026-10-27  3:42     ` Mikko Perttunen
2026-10-27 12:33       ` Jason Gunthorpe
2026-10-27 13:34         ` Mikko Perttunen
2026-10-27 13:43           ` Christian König
2026-10-27 12:11     ` Christian König
2026-10-27 12:31     ` Jason Gunthorpe
2026-10-27 12:07   ` Christian König
2026-10-27 12:38     ` Jason Gunthorpe
2026-10-27 13:17       ` Christian König
2026-10-27 14:08         ` Jason Gunthorpe
2026-10-27 14:28           ` Christian König
2026-10-27 14:44             ` Jason Gunthorpe
2026-10-27 14:54               ` Christian König
2026-10-26  5:36 ` [PATCH 24/26] treewide: Rename dma_buf_dynamic_attach() to dma_buf_sgt_dynamic_attach() Alistair Popple
2026-10-26 10:13   ` sashiko-bot
2026-10-26  5:36 ` [PATCH 25/26] dma-buf: Add kunit tests for mapping type Alistair Popple
2026-10-26 10:19   ` sashiko-bot
2026-10-26  5:36 ` [PATCH 26/26] dma-buf: Add kunit tests for mapping type selection Alistair Popple
2026-10-26 10:22   ` sashiko-bot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox