Hi all,
There were various suggestions in the September 2025 thread "[TECH
TOPIC] vfio, iommufd: Enabling user space drivers to vend more
granular access to client processes" [0], and LPC discussions, around
improving the situation for multi-process userspace driver designs.
This RFC series implements some of these ideas.
(Thanks for feedback on v1! Revised series, with changes noted
inline.)
Background: Multi-process USDs
==============================
The userspace driver scenario discussed in that thread involves a
primary process driving a PCIe function through VFIO/iommufd, which
manages the function-wide ownership/lifecycle. The function is
designed to provide multiple distinct programming interfaces (for
example, several independent MMIO register frames in one function),
and the primary process delegates control of these interfaces to
multiple independent client processes (which do the actual work).
This scenario clearly relies on a HW design that provides appropriate
isolation between the programming interfaces.
The two key needs are:
1. Mechanisms to safely delegate a subset of the device MMIO
resources to a client process without over-sharing wider access
(or influence over whole-device activities, such as reset).
2. Mechanisms to allow a client process to do its own iommufd
management w.r.t. its address space, in a way that's isolated
from DMA relating to other clients.
mmap() of VFIO DMABUFs
======================
This RFC addresses #1 in "vfio/pci: Support mmap() of a VFIO DMABUF",
implementing the proposals in [0] to add mmap() support to the
existing VFIO DMABUF exporter.
This enables a userspace driver to define DMABUF ranges corresponding
to sub-ranges of a BAR, and grant a given client (via a shared fd)
the capability to access (only) those sub-ranges. The VFIO device fds
would be kept private to the primary process. All the client can do
with that fd is map (or iomap via iommufd) that specific subset of
resources, and the impact of bugs/malice is contained.
(We'll follow up on #2 separately, as a related-but-distinct problem.
PASIDs are one way to achieve per-client isolation of DMA; another
could be sharing of a single IOVA space via 'constrained' iommufds.)
New in v2: To achieve this, the existing VFIO BAR mmap() path is
converted to use DMABUFs behind the scenes, in "vfio/pci: Convert BAR
mmap() to use a DMABUF" plus new helper functions, as Jason/Christian
suggested in the v1 discussion [3].
This means:
- Both regular and new DMABUF BAR mappings share the same vm_ops,
i.e. mmap()ing DMABUFs is a smaller change on top of the existing
mmap().
- The zapping of mappings occurs via vfio_pci_dma_buf_move(), and the
vfio_pci_zap_bars() originally paired with the _move()s can go
away. Each DMABUF has a unique address_space.
- It's a step towards future iommufd VFIO Type1 emulation
implementing P2P, since iommufd can now get a DMABUF from a VA that
it's mapping for IO; the VMAs' vm_file is that of the backing
DMABUF.
Revocation/reclaim
==================
Mapping a BAR subset is useful, but the lifetime of access granted to
a client needs to be managed well. For example, a protocol between
the primary process and the client can indicate when the client is
done, and when it's safe to reuse the resources elsewhere, but cleanup
can't practically be cooperative.
For robustness, we enable the driver to make the resources
guaranteed-inaccessible when it chooses, so that it can re-assign them
to other uses in future.
"vfio/pci: Permanently revoke a DMABUF on request" adds a new VFIO
device fd ioctl, VFIO_DEVICE_PCI_DMABUF_REVOKE. This takes a DMABUF
fd parameter previously exported (from that device!) and permanently
revokes the DMABUF. This notifies/detaches importers, zaps PTEs for
any mappings, and guarantees no future attachment/import/map/access is
possible by any means.
A primary driver process would use this operation when the client's
tenure ends to reclaim "loaned-out" MMIO interfaces, at which point
the interfaces could be safely re-used.
New in v2: ioctl() on VFIO driver fd, rather than DMABUF fd. A DMABUF
is revoked using code common to vfio_pci_dma_buf_move(), selectively
zapping mappings (after waiting for completion on the
dma_buf_invalidate_mappings() request).
BAR mapping access attributes
=============================
Inspired by Alex [Mastro] and Jason's comments in [0] and Mahmoud's
work in [1] with the goal of controlling CPU access attributes for
VFIO BAR mappings (e.g. WC), we can decorate DMABUFs with access
attributes that are then used by a mapping's PTEs.
I've proposed reserving a field in struct
vfio_device_feature_dma_buf's flags to specify an attribute for its
ranges. Although that keeps the (UAPI) struct unchanged, it means all
ranges in a DMABUF share the same attribute. I feel a single
attribute-to-mmap() relation is logical/reasonable. An application
can also create multiple DMABUFs to describe any BAR layout and mix of
attributes.
Tests
=====
(Still sharing the [RFC ONLY] userspace test/demo program for context,
not for merge.)
It illustrates & tests various map/revoke cases, but doesn't use the
existing VFIO selftests and relies on a (tweaked) QEMU EDU function.
I'm (still) working on integrating the scenarios into the existing
VFIO selftests.
This code has been tested in mapping DMABUFs of single/multiple
ranges, aliasing mmap()s, aliasing ranges across DMABUFs, vm_pgoff >
0, revocation, shutdown/cleanup scenarios, and hugepage mappings seem
to work correctly. I've lightly tested WC mappings also (by observing
resulting PTEs as having the correct attributes...).
Fin
===
v2 is based on next-20260310 (to build on Leon's recent series
"vfio: Wait for dma-buf invalidation to complete" [2]).
Please share your thoughts! I'd like to de-RFC if we feel this
approach is now fair.
Many thanks,
Matt
References:
[0]: https://lore.kernel.org/linux-iommu/20250918214425.2677057-1-amastro@fb.com/
[1]: https://lore.kernel.org/all/20250804104012.87915-1-mngyadam@amazon.de/
[2]: https://lore.kernel.org/linux-iommu/20260205-nocturnal-poetic-chamois-f566a…
[3]: https://lore.kernel.org/all/20260226202211.929005-1-mattev@meta.com/
--------------------------------------------------------------------------------
Changelog:
v2: Respin based on the feedback/suggestions:
- Transform the existing VFIO BAR mmap path to also use DMABUFs behind
the scenes, and then simply share that code for explicitly-mapped
DMABUFs.
- Refactors the export itself out of vfio_pci_core_feature_dma_buf,
and shared by a new vfio_pci_core_mmap_prep_dmabuf helper used by
the regular VFIO mmap to create a DMABUF.
- Revoke buffers using a VFIO device fd ioctl
v1: https://lore.kernel.org/all/20260226202211.929005-1-mattev@meta.com/
Matt Evans (10):
vfio/pci: Set up VFIO barmap before creating a DMABUF
vfio/pci: Clean up DMABUFs before disabling function
vfio/pci: Add helper to look up PFNs for DMABUFs
vfio/pci: Add a helper to create a DMABUF for a BAR-map VMA
vfio/pci: Convert BAR mmap() to use a DMABUF
vfio/pci: Remove vfio_pci_zap_bars()
vfio/pci: Support mmap() of a VFIO DMABUF
vfio/pci: Permanently revoke a DMABUF on request
vfio/pci: Add mmap() attributes to DMABUF feature
[RFC ONLY] selftests: vfio: Add standalone vfio_dmabuf_mmap_test
drivers/vfio/pci/Kconfig | 3 +-
drivers/vfio/pci/Makefile | 3 +-
drivers/vfio/pci/vfio_pci_config.c | 18 +-
drivers/vfio/pci/vfio_pci_core.c | 123 +--
drivers/vfio/pci/vfio_pci_dmabuf.c | 425 +++++++--
drivers/vfio/pci/vfio_pci_priv.h | 46 +-
include/uapi/linux/vfio.h | 42 +-
tools/testing/selftests/vfio/Makefile | 1 +
.../vfio/standalone/vfio_dmabuf_mmap_test.c | 837 ++++++++++++++++++
9 files changed, 1339 insertions(+), 159 deletions(-)
create mode 100644 tools/testing/selftests/vfio/standalone/vfio_dmabuf_mmap_test.c
--
2.47.3
Commit 3a236f6a5cf2 ("dma: contiguous: Turn heap registration logic
around") didn't remove one last call to dma_heap_cma_register_heap()
that it removed, thus breaking the build.
That last call is in dma_contiguous_reserve(), to handle the
registration of the default CMA region heap instance.
The default CMA region instance is already somewhat handled by
retrieving it through the dev_get_cma_area() call in the CMA heap
driver. However, since commit 854acbe75ff4 ("dma-buf: heaps: Give
default CMA heap a fixed name"), we will create two heap instances for
the CMA default region.
The first one is always called "default_cma_region", and is the one
handled by the call to dev_get_cma_area() mentioned earlier. The second
one is the name it used to have prior to that last commit for backward
compatibility.
In the case where the default CMA region is defined in the DT, then that
region is registered through rmem_cma_setup() and that region is added
to the list of CMA regions to create a CMA heap instance for.
In the case where the default CMA region is not defined in the DT
though used to be the case covered by the now removed
dma_heap_cma_register_heap() in dma_contiguous_reserve(). If we only
remove the call to dma_heap_cma_register_heap(), then the legacy name of
the CMA heap will not be registered anymore. We thus need to replace
that call with a call to rmem_cma_insert_area() to make sure we queue
this instance, if created, to create a heap instance.
Once that call to dma_heap_cma_register_heap() replaced, we can also
remove the now unused function definition, its now empty header, and all
includes of this header.
Fixes: 3a236f6a5cf2 ("dma: contiguous: Turn heap registration logic around")
Reported-by: Mark Brown <broonie(a)kernel.org>
Closes: https://lore.kernel.org/linux-next/acbjaDJ1a-YQC64d@sirena.co.uk/
Signed-off-by: Maxime Ripard <mripard(a)kernel.org>
---
Changes in v2:
- Fix creation of the CMA heap instance with the legacy name when not
declared in the DT.
- Link to v1: https://lore.kernel.org/r/20260330-dma-build-fix-v1-1-748b64f0d8af@kernel.o…
---
drivers/dma-buf/heaps/cma_heap.c | 1 -
include/linux/dma-buf/heaps/cma.h | 16 ----------------
kernel/dma/contiguous.c | 14 +++++++++++---
3 files changed, 11 insertions(+), 20 deletions(-)
diff --git a/drivers/dma-buf/heaps/cma_heap.c b/drivers/dma-buf/heaps/cma_heap.c
index 7216a14262b04bb6130ddf26b7d009f7d15b03fd..9a8b36bc929f6daa483a0139a2919d95127e0d23 100644
--- a/drivers/dma-buf/heaps/cma_heap.c
+++ b/drivers/dma-buf/heaps/cma_heap.c
@@ -12,11 +12,10 @@
#define pr_fmt(fmt) "cma_heap: " fmt
#include <linux/cma.h>
#include <linux/dma-buf.h>
-#include <linux/dma-buf/heaps/cma.h>
#include <linux/dma-heap.h>
#include <linux/dma-map-ops.h>
#include <linux/err.h>
#include <linux/highmem.h>
#include <linux/io.h>
diff --git a/include/linux/dma-buf/heaps/cma.h b/include/linux/dma-buf/heaps/cma.h
deleted file mode 100644
index e751479e21e703e24a5f799b4a7fc8bd0df3c1c4..0000000000000000000000000000000000000000
--- a/include/linux/dma-buf/heaps/cma.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef DMA_BUF_HEAP_CMA_H_
-#define DMA_BUF_HEAP_CMA_H_
-
-struct cma;
-
-#ifdef CONFIG_DMABUF_HEAPS_CMA
-int dma_heap_cma_register_heap(struct cma *cma);
-#else
-static inline int dma_heap_cma_register_heap(struct cma *cma)
-{
- return 0;
-}
-#endif // CONFIG_DMABUF_HEAPS_CMA
-
-#endif // DMA_BUF_HEAP_CMA_H_
diff --git a/kernel/dma/contiguous.c b/kernel/dma/contiguous.c
index ad50512d71d3088a73e4b1ac02d6e6122374888e..d5d15983060c5c54744d6a63f2b591e1a3455b86 100644
--- a/kernel/dma/contiguous.c
+++ b/kernel/dma/contiguous.c
@@ -40,11 +40,10 @@
#include <asm/page.h>
#include <linux/memblock.h>
#include <linux/err.h>
#include <linux/sizes.h>
-#include <linux/dma-buf/heaps/cma.h>
#include <linux/dma-map-ops.h>
#include <linux/cma.h>
#include <linux/nospec.h>
#ifdef CONFIG_CMA_SIZE_MBYTES
@@ -217,10 +216,19 @@ static void __init dma_numa_cma_reserve(void)
static inline void __init dma_numa_cma_reserve(void)
{
}
#endif
+#ifdef CONFIG_OF_RESERVED_MEM
+static int rmem_cma_insert_area(struct cma *cma);
+#else
+static inline int rmem_cma_insert_area(struct cma *cma)
+{
+ return 0;
+}
+#endif
+
/**
* dma_contiguous_reserve() - reserve area(s) for contiguous memory handling
* @limit: End address of the reserved memory (optional, 0 for any).
*
* This function reserves memory from early allocator. It should be
@@ -271,13 +279,13 @@ void __init dma_contiguous_reserve(phys_addr_t limit)
&dma_contiguous_default_area,
fixed);
if (ret)
return;
- ret = dma_heap_cma_register_heap(dma_contiguous_default_area);
+ ret = rmem_cma_insert_area(dma_contiguous_default_area);
if (ret)
- pr_warn("Couldn't register default CMA heap.");
+ pr_warn("Couldn't queue default CMA region for heap creation.");
}
}
void __weak
dma_contiguous_early_fixup(phys_addr_t base, unsigned long size)
---
base-commit: 6c683d5b1903a14e362c9f1628ce9fe61eac35e7
change-id: 20260330-dma-build-fix-706a4feb0e0f
Best regards,
--
Maxime Ripard <mripard(a)kernel.org>
When CONFIG_DMA_API_DEBUG_SG is enabled, importing a udmabuf into a DRM
driver (e.g. amdgpu for video playback in GNOME Videos / Showtime)
triggers a spurious warning:
DMA-API: amdgpu 0000:03:00.0: cacheline tracking EEXIST, \
overlapping mappings aren't supported
WARNING: kernel/dma/debug.c:619 at add_dma_entry+0x473/0x5f0
The call chain is:
amdgpu_cs_ioctl
-> amdgpu_ttm_backend_bind
-> dma_buf_map_attachment
-> [udmabuf] map_udmabuf -> get_sg_table
-> dma_map_sgtable(dev, sg, direction, 0) // attrs=0
-> debug_dma_map_sg -> add_dma_entry -> EEXIST
This happens because udmabuf builds a per-page scatter-gather list via
sg_set_folio(). When begin_cpu_udmabuf() has already created an sg
table mapped for the misc device, and an importer such as amdgpu maps
the same pages for its own device via map_udmabuf(), the DMA debug
infrastructure sees two active mappings whose physical addresses share
cacheline boundaries and warns about the overlap.
The DMA_ATTR_SKIP_CPU_SYNC flag suppresses this check in
add_dma_entry() because it signals that no CPU cache maintenance is
performed at map/unmap time, making the cacheline overlap harmless.
All other major dma-buf exporters already pass this flag:
- drm_gem_map_dma_buf() passes DMA_ATTR_SKIP_CPU_SYNC
- amdgpu_dma_buf_map() passes DMA_ATTR_SKIP_CPU_SYNC
The CPU sync at map/unmap time is also redundant for udmabuf:
begin_cpu_udmabuf() and end_cpu_udmabuf() already perform explicit
cache synchronization via dma_sync_sgtable_for_cpu/device() when CPU
access is requested through the dma-buf interface.
Pass DMA_ATTR_SKIP_CPU_SYNC to dma_map_sgtable() and
dma_unmap_sgtable() in udmabuf to suppress the spurious warning and
skip the redundant sync.
Fixes: 284562e1f348 ("udmabuf: implement begin_cpu_access/end_cpu_access hooks")
Cc: stable(a)vger.kernel.org
Signed-off-by: Mikhail Gavrilov <mikhail.v.gavrilov(a)gmail.com>
---
drivers/dma-buf/udmabuf.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c
index 94b8ecb892bb..9c6f8785a28a 100644
--- a/drivers/dma-buf/udmabuf.c
+++ b/drivers/dma-buf/udmabuf.c
@@ -162,7 +162,7 @@ static struct sg_table *get_sg_table(struct device *dev, struct dma_buf *buf,
sg_set_folio(sgl, ubuf->folios[i], PAGE_SIZE,
ubuf->offsets[i]);
- ret = dma_map_sgtable(dev, sg, direction, 0);
+ ret = dma_map_sgtable(dev, sg, direction, DMA_ATTR_SKIP_CPU_SYNC);
if (ret < 0)
goto err_map;
return sg;
@@ -177,7 +177,7 @@ static struct sg_table *get_sg_table(struct device *dev, struct dma_buf *buf,
static void put_sg_table(struct device *dev, struct sg_table *sg,
enum dma_data_direction direction)
{
- dma_unmap_sgtable(dev, sg, direction, 0);
+ dma_unmap_sgtable(dev, sg, direction, DMA_ATTR_SKIP_CPU_SYNC);
sg_free_table(sg);
kfree(sg);
}
--
2.53.0
This is the next version of the shmem backed GEM objects series
originally from Asahi, previously posted by Daniel Almeida.
The previous version of the patch series can be found here:
https://patchwork.freedesktop.org/series/156093/
This patch series may be applied on top of the
driver-core/driver-core-testing branch:
https://git.kernel.org/pub/scm/linux/kernel/git/driver-core/driver-core.git…
Changelogs are per-patch
Asahi Lina (2):
rust: helpers: Add bindings/wrappers for dma_resv_lock
rust: drm: gem: shmem: Add DRM shmem helper abstraction
Lyude Paul (5):
rust: drm: Add gem::impl_aref_for_gem_obj!
rust: drm: gem: Add raw_dma_resv() function
rust: gem: Introduce DriverObject::Args
rust: drm: gem: Introduce shmem::SGTable
rust: drm/gem: Add vmap functions to shmem bindings
drivers/gpu/drm/nova/gem.rs | 5 +-
drivers/gpu/drm/tyr/gem.rs | 3 +-
rust/bindings/bindings_helper.h | 3 +
rust/helpers/dma-resv.c | 13 +
rust/helpers/drm.c | 56 ++-
rust/helpers/helpers.c | 1 +
rust/kernel/drm/gem/mod.rs | 79 +++-
rust/kernel/drm/gem/shmem.rs | 654 ++++++++++++++++++++++++++++++++
8 files changed, 792 insertions(+), 22 deletions(-)
create mode 100644 rust/helpers/dma-resv.c
create mode 100644 rust/kernel/drm/gem/shmem.rs
base-commit: dc33ae50d32b509af5ae61030912fa20c79ef112
prerequisite-patch-id: c631986f96e2073263e97e82a65b96fc5ada6924
prerequisite-patch-id: ae853e8eb8d58c77881371960be4ae92755e83c6
prerequisite-patch-id: 0ab78b50648c7d8f66b83c32ed2af0ec3ede42a3
prerequisite-patch-id: 636ec7f913f4047e5e1a1788f3e835b7259698c2
prerequisite-patch-id: d75e4d7140eadeeed8017af8cd093bfd2766ee8e
prerequisite-patch-id: 67a8010c1bc95bca1d2cf6b246c67bc79d24e766
--
2.53.0
dma_fence_chain_find_seqno() uses dma_fence_chain_for_each() to walk a
given dma_fence_chain. dma_fence_chain_for_each() always holds a
reference for the current fence during iteration. The reference must
be dropped after breaking out. Instead of dereferencing the last fence
as intended, dma_fence_chain_find_seqno() incorrectly dereferences the
first fence in the chain.
Fixes: 7bf60c52e093 ("dma-buf: add new dma_fence_chain container v7")
Signed-off-by: Li Ming <ming.li(a)zohomail.com>
---
drivers/dma-buf/dma-fence-chain.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/dma-buf/dma-fence-chain.c b/drivers/dma-buf/dma-fence-chain.c
index a8a90acf4f34..71fa173aef13 100644
--- a/drivers/dma-buf/dma-fence-chain.c
+++ b/drivers/dma-buf/dma-fence-chain.c
@@ -103,7 +103,7 @@ int dma_fence_chain_find_seqno(struct dma_fence **pfence, uint64_t seqno)
to_dma_fence_chain(*pfence)->prev_seqno < seqno)
break;
}
- dma_fence_put(&chain->base);
+ dma_fence_put(*pfence);
return 0;
}
---
base-commit: c369299895a591d96745d6492d4888259b004a9e
change-id: 20260327-fix_dma_fence_chain_find_seqno-7adea64efe01
Best regards,
--
Li Ming <ming.li(a)zohomail.com>
dma_fence_chain_find_seqno() uses dma_fence_chain_for_each() to walk a
given dma_fence_chain. dma_fence_chain_for_each() always holds a
reference for the current fence during iteration. The reference must
be dropped after breaking out. Instead of dereferencing the last fence
as intended, dma_fence_chain_find_seqno() incorrectly dereferences the
first fence in the chain.
Fixes: 7bf60c52e093 ("dma-buf: add new dma_fence_chain container v7")
Signed-off-by: Li Ming <ming.li(a)zohomail.com>
---
drivers/dma-buf/dma-fence-chain.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/dma-buf/dma-fence-chain.c b/drivers/dma-buf/dma-fence-chain.c
index a8a90acf4f34..71fa173aef13 100644
--- a/drivers/dma-buf/dma-fence-chain.c
+++ b/drivers/dma-buf/dma-fence-chain.c
@@ -103,7 +103,7 @@ int dma_fence_chain_find_seqno(struct dma_fence **pfence, uint64_t seqno)
to_dma_fence_chain(*pfence)->prev_seqno < seqno)
break;
}
- dma_fence_put(&chain->base);
+ dma_fence_put(*pfence);
return 0;
}
---
base-commit: c369299895a591d96745d6492d4888259b004a9e
change-id: 20260327-fix_dma_fence_chain_find_seqno-7adea64efe01
Best regards,
--
Li Ming <ming.li(a)zohomail.com>
Hi,
The recent introduction of heaps in the optee driver [1] made possible
the creation of heaps as modules.
It's generally a good idea if possible, including for the already
existing system and CMA heaps.
The system one is pretty trivial, the CMA one is a bit more involved,
especially since we have a call from kernel/dma/contiguous.c to the CMA
heap code. This was solved by turning the logic around and making the
CMA heap call into the contiguous DMA code.
Let me know what you think,
Maxime
1: https://lore.kernel.org/dri-devel/20250911135007.1275833-4-jens.wiklander@l…
Signed-off-by: Maxime Ripard <mripard(a)kernel.org>
---
Changes in v3:
- Squashed cma_get_name and cma_alloc/release patches
- Fixed typo in Export dev_get_cma_area commit title
- Fixed compilation failure with DMA_CMA but not OF_RESERVED_MEM
- Link to v2: https://lore.kernel.org/r/20260227-dma-buf-heaps-as-modules-v2-0-454aee7e06…
Changes in v2:
- Collect tags
- Don't export dma_contiguous_default_area anymore, but export
dev_get_cma_area instead
- Mentioned that heap modules can't be removed
- Link to v1: https://lore.kernel.org/r/20260225-dma-buf-heaps-as-modules-v1-0-2109225a09…
---
Maxime Ripard (8):
dma: contiguous: Turn heap registration logic around
dma: contiguous: Make dev_get_cma_area() a proper function
dma: contiguous: Make dma_contiguous_default_area static
dma: contiguous: Export dev_get_cma_area()
mm: cma: Export cma_alloc(), cma_release() and cma_get_name()
dma-buf: heaps: Export mem_accounting parameter
dma-buf: heaps: cma: Turn the heap into a module
dma-buf: heaps: system: Turn the heap into a module
drivers/dma-buf/dma-heap.c | 1 +
drivers/dma-buf/heaps/Kconfig | 4 ++--
drivers/dma-buf/heaps/cma_heap.c | 21 +++++----------------
drivers/dma-buf/heaps/system_heap.c | 5 +++++
include/linux/dma-map-ops.h | 18 ++++++++++--------
kernel/dma/contiguous.c | 37 ++++++++++++++++++++++++++++++++++---
mm/cma.c | 3 +++
7 files changed, 60 insertions(+), 29 deletions(-)
---
base-commit: 499a718536dc0e1c1d1b6211847207d58acd9916
change-id: 20260225-dma-buf-heaps-as-modules-1034b3ec9f2a
Best regards,
--
Maxime Ripard <mripard(a)kernel.org>
Introduce a new accel driver for the Neutron Neural Processing Unit
(NPU), along with associated dt-bindings and DTS node.
The first patch extends the GEM DMA helper APIs to allow bidirectional
mapping of non-coherent DMA buffers. While not part of the Neutron
driver, it's a prerequisite allowing us to use the GEM DMA helper.
Neutron is a Neural Processing Unit from NXP, providing machine
learning (ML) acceleration for edge AI applications. Neutron is
integrated on NXP SoCs such as the i.MX95.
The NPU consists of the following:
- RISC-V core running a proprietary firmware
- One or more Neutron cores, representing the main computation
engine performing ML operations
- Dedicated fast memory (TCM)
- DMA engine that handles data transfers between DDR and TCM
The firmware is closed source and distributed as a binary here [1].
The Neutron software stack also contains a userspace library [1] and
a LiteRT custom delegate [2] that allow integration with standard
LiteRT tools.
[1] https://github.com/nxp-upstream/neutron/tree/upstream
[2] https://github.com/nxp-imx/tflite-neutron-delegate
Signed-off-by: Ioana Ciocoi-Radulescu <ruxandra.radulescu(a)nxp.com>
---
Changes in v2:
- rebase on newer drm-misc-next
- dt bindings: clock fixes and renames
- update DTS to match new names
- remove unnecessary fields from neutron_job structure
- fix use of uninitialized variable
- Link to v1: https://lore.kernel.org/r/20260226-neutron-v1-0-46eccb3bb50a@nxp.com
---
Ioana Ciocoi-Radulescu (9):
drm/gem-dma: Add flag for bidirectional mapping of non-coherent GEM DMA buffers
accel/neutron: Add documentation for NXP Neutron accelerator driver
dt-bindings: npu: Add NXP Neutron
accel/neutron: Add driver for NXP Neutron NPU
accel/neutron: Add GEM buffer object support
accel/neutron: Add mailbox support
accel/neutron: Add job submission IOCTL
accel/neutron: Add logging support
arm64: dts: imx95: Add Neutron node
Documentation/accel/index.rst | 1 +
Documentation/accel/neutron/index.rst | 12 +
Documentation/accel/neutron/neutron.rst | 131 ++++++++
.../devicetree/bindings/npu/nxp,imx95-neutron.yaml | 96 ++++++
MAINTAINERS | 10 +
arch/arm64/boot/dts/freescale/imx95.dtsi | 28 ++
drivers/accel/Kconfig | 1 +
drivers/accel/Makefile | 3 +-
drivers/accel/neutron/Kconfig | 16 +
drivers/accel/neutron/Makefile | 12 +
drivers/accel/neutron/neutron_debugfs.c | 34 ++
drivers/accel/neutron/neutron_debugfs.h | 15 +
drivers/accel/neutron/neutron_device.c | 239 +++++++++++++
drivers/accel/neutron/neutron_device.h | 155 +++++++++
drivers/accel/neutron/neutron_driver.c | 262 +++++++++++++++
drivers/accel/neutron/neutron_driver.h | 16 +
drivers/accel/neutron/neutron_gem.c | 116 +++++++
drivers/accel/neutron/neutron_gem.h | 14 +
drivers/accel/neutron/neutron_job.c | 372 +++++++++++++++++++++
drivers/accel/neutron/neutron_job.h | 43 +++
drivers/accel/neutron/neutron_mailbox.c | 47 +++
drivers/accel/neutron/neutron_mailbox.h | 42 +++
drivers/gpu/drm/drm_gem_dma_helper.c | 6 +-
include/drm/drm_gem_dma_helper.h | 3 +
include/uapi/drm/neutron_accel.h | 130 +++++++
25 files changed, 1801 insertions(+), 3 deletions(-)
---
base-commit: 6716101ae42949e98ad4b9e71eeba08c055be410
change-id: 20260226-neutron-c435e39d167f
Best regards,
--
Ioana Ciocoi-Radulescu <ruxandra.radulescu(a)nxp.com>