On 17/08/2026 06:47, Ekansh Gupta wrote:
> This patch series introduces the Qualcomm DSP Accelerator (QDA) driver,
> a DRM-based accelerator driver for Qualcomm DSPs. The driver provides a
> standardized interface for offloading computational tasks to DSPs found
> on Qualcomm SoCs, supporting all DSP domains.
>
> The QDA driver implements the FastRPC protocol over the DRM accel
> subsystem. It uses the same device-tree node structure as the existing
> fastrpc driver in drivers/misc/. The approach for binding the QDA driver
> to device-tree nodes while coexisting with the fastrpc driver is an open
> item described below.
No. Grow/replace/improve existing driver instead of coming with a duplicate.
That's a standard upstream requirement, basically given on every
upstreaming guide.
Please watch old talk from Greg - "I Don’t Want Your Code!".
>
> v1: https://lore.kernel.org/all/20260519-qda-series-v1-0-b2d984c297f8@oss.qualc…
> RFC: https://lore.kernel.org/dri-devel/20260224-qda-firstpost-v1-0-fe46a9c1a046@…
>
> Changes since v1
> ================
>
> The v1 review raised two architectural objections and one correctness
> issue; all three are resolved in v2:
>
> * Christian König (dma-buf maintainer) pointed out that the imported-
> buffer path silently assumed the IOMMU maps every buffer as a single
> contiguous range, which is not guaranteed. v2 walks the scatterlist
> and cleanly rejects non-contiguous imports; contiguous imports (e.g.
> CMA DMA-buf heap) are accepted. (patch 11)
>
> * Dmitry Baryshkov objected to three different buffer-passing formats
> in the invoke IOCTL (DMA-BUF fd, direct/inline, DMA handle). v2
> passes only GEM handles; userspace imports any fd to a GEM handle
> with DRM_IOCTL_PRIME_FD_TO_HANDLE before invoking. Packing and
> overlap handling are left to userspace. (patch 12)
>
> * The memory manager (patch 07) used a fixed 16-entry array without
> justification and leaked the device descriptor on teardown. v2
> allocates the array from the DT context-bank count (as Dmitry
> suggested) and frees it correctly.
>
> User-space staging branch
> =========================
> https://github.com/qualcomm/fastrpc/tree/accel/staging
>
> Key Features
> ============
>
> * Standard DRM accelerator interface via /dev/accel/accelN
> * GEM-based buffer management with DMA-BUF import (PRIME)
> * IOMMU-based memory isolation using per-process context banks
> * FastRPC protocol implementation for DSP communication
> * RPMsg transport layer for reliable message passing
> * Support for all DSP domains (ADSP, CDSP, SDSP, GDSP)
> * DRM IOCTL interface for DSP session management, buffer allocation,
> and remote procedure invocation
>
> Architecture
> ============
>
> 1. DRM Accelerator Framework Integration
> The driver registers as a DRM accel device, exposing a standard
> /dev/accel/accelN character device node. This provides established
> DRM infrastructure for device management, file operations, and
> IOCTL dispatch.
>
> 2. Memory Management
> Buffers are managed as GEM objects with PRIME support for DMA-BUF
> import. This enables buffer sharing with other DRM drivers (GPU,
> camera, video) using standard kernel mechanisms. Only contiguous
> imports are accepted; the driver verifies contiguity at import time
> rather than assuming it.
>
> 3. IOMMU Context Bank Management
> IOMMU context banks (CBs) are represented as proper struct device
> instances on a custom virtual bus (qda-compute-cb). Each CB device
> is registered with the IOMMU subsystem and receives its own IOMMU
> domain, enabling per-session address space isolation. The custom
> bus was introduced because IOMMU context banks are synthetic
> constructs — not real platform devices — and to ensure CB device
> lifetime is strictly subordinate to the parent QDA device.
> See also: https://lore.kernel.org/all/245d602f-3037-4ae3-9af9-d98f37258aae@oss.qualco…
>
> 4. Memory Manager Architecture
> The memory manager maintains a registry of IOMMU devices in an
> array sized to the number of context banks described in the device
> tree, and coordinates per-process device assignment with reference-
> counted lifetime management. The DMA-coherent backend allocates
> buffers with SID-prefixed DMA addresses for DSP firmware
> compatibility.
>
> 5. Transport Layer
> RPMsg communication is handled in a dedicated transport layer
> (qda_rpmsg.c), separate from the core DRM driver logic.
>
> 6. Code Organization
> The driver is organized across multiple files (~4800 lines total):
> * qda_drv.c: Core driver and DRM integration
> * qda_rpmsg.c: RPMsg transport layer
> * qda_cb.c: Context bank device management
> * qda_compute_bus.c: Custom virtual bus for CB devices
> * qda_gem.c: GEM object management
> * qda_prime.c: DMA-BUF import (PRIME)
> * qda_memory_manager.c: IOMMU device registry and allocation
> * qda_memory_dma.c: DMA-coherent allocation backend
> * qda_fastrpc.c: FastRPC protocol implementation
> * qda_ioctl.c: IOCTL dispatch
>
> 7. UAPI Design
> The driver exposes DRM-style IOCTLs defined in
> include/uapi/drm/qda_accel.h, following DRM UAPI conventions
> (__u32/__u64 types, C++ guard, GPL-2.0-only WITH Linux-syscall-note).
> Buffer arguments are identified by GEM handles; the driver never
> accepts DMA-BUF fds directly in any IOCTL.
>
> Patch Series Organization
> ==========================
>
> Patch 01: MAINTAINERS entry
> Patch 02: Driver documentation (Documentation/accel/qda/)
> Patches 03-04: Core driver skeleton and compute bus
> Patch 05: iommu: Register qda-compute-cb bus with IOMMU subsystem
> Patches 06-07: CB device enumeration and memory manager
> Patch 08: QUERY IOCTL and UAPI header
> Patches 09-11: GEM buffer management and PRIME import
> Patches 12-15: FastRPC protocol (invoke, session create/release,
> map/unmap)
>
> Open Items
> ===========
>
> 1. Device-Tree Compatible String
> The QDA driver uses the same device-tree node structure and
> properties as the existing fastrpc driver in drivers/misc/. A
> mechanism is needed to allow the QDA driver to bind to its device
> node independently of the fastrpc driver.
>
> The intended coexistence model is: platforms that require the
> complete fastrpc feature set continue to use "qcom,fastrpc"; new
> platforms where QDA's feature set is sufficient use a QDA-specific
> compatible string. New feature development is directed toward QDA.
>
> The options under consideration are:
>
> a) Add a new "qcom,qda" compatible string to the existing
> qcom,fastrpc.yaml binding, since the DT node structure and
> properties are identical.
No
>
> b) Introduce a separate qcom,qda.yaml binding that references or
> inherits the fastrpc binding properties.
No
>
> Seeking guidance from DT binding maintainers on the preferred
> approach.
Grow existing driver. You do not get new driver, you do not get new
bindings.
Best regards,
Krzysztof
On 17/08/2026 06:47, Ekansh Gupta wrote:
> This patch series introduces the Qualcomm DSP Accelerator (QDA) driver,
> a DRM-based accelerator driver for Qualcomm DSPs. The driver provides a
> standardized interface for offloading computational tasks to DSPs found
> on Qualcomm SoCs, supporting all DSP domains.
>
> The QDA driver implements the FastRPC protocol over the DRM accel
> subsystem. It uses the same device-tree node structure as the existing
> fastrpc driver in drivers/misc/. The approach for binding the QDA driver
> to device-tree nodes while coexisting with the fastrpc driver is an open
> item described below.
>
> v1: https://lore.kernel.org/all/20260519-qda-series-v1-0-b2d984c297f8@oss.qualc…
> RFC: https://lore.kernel.org/dri-devel/20260224-qda-firstpost-v1-0-fe46a9c1a046@…
So this is a v3, not v2. Please start using b4 correctly, so versioning
will be kept instead of faking the numbers.
Best regards,
Krzysztof
On 17/08/2026 06:47, Ekansh Gupta wrote:
> Add the skeleton of the Qualcomm DSP Accelerator (QDA) driver, a DRM
> accel driver for the Hexagon DSPs found on Qualcomm SoCs.
>
> This patch registers a DRM accel device, exposing a /dev/accel/accelN
> character device node, and binds it to the RPMsg channel used to reach
> the DSP. Buffer management, IOMMU context banks and the FastRPC
> protocol are added by later patches in this series.
>
> qda_drv.c / qda_drv.h define the drm_driver ops table, the per-file
> private state (qda_file_priv) and the main device structure (qda_dev),
> which embeds drm_device so that it can be recovered with container_of().
>
> qda_rpmsg.c binds to the "qcom,fastrpc" compatible via
> module_rpmsg_driver(), reads the DSP domain name from the "label"
> device-tree property, and registers the DRM device.
>
> Assisted-by: Claude:claude-sonnet-5
> Signed-off-by: Ekansh Gupta <ekansh.gupta(a)oss.qualcomm.com>
> ---
> Changes in v2:
> - Use module_rpmsg_driver() and drop the qda_rpmsg_register()/
> _unregister() wrappers, module_init()/module_exit() and
> qda_rpmsg.h entirely (Dmitry Baryshkov)
> - Read the "label" property directly into qdev->dsp_name (Dmitry Baryshkov)
> - Drop the probe/remove/init log messages (Dmitry Baryshkov)
> - Return the result of qda_register_device() directly (Dmitry Baryshkov)
> - Clarify the Kconfig help text (Dmitry Baryshkov)
> ---
> drivers/accel/Kconfig | 1 +
> drivers/accel/Makefile | 1 +
> drivers/accel/qda/Kconfig | 30 ++++++++++++++++
> drivers/accel/qda/Makefile | 10 ++++++
> drivers/accel/qda/qda_drv.c | 71 ++++++++++++++++++++++++++++++++++++++
> drivers/accel/qda/qda_drv.h | 61 +++++++++++++++++++++++++++++++++
> drivers/accel/qda/qda_rpmsg.c | 79 +++++++++++++++++++++++++++++++++++++++++++
> 7 files changed, 253 insertions(+)
>
> diff --git a/drivers/accel/Kconfig b/drivers/accel/Kconfig
> index bdf48ccafcf2..74ac0f71bc9d 100644
> --- a/drivers/accel/Kconfig
> +++ b/drivers/accel/Kconfig
> @@ -29,6 +29,7 @@ source "drivers/accel/ethosu/Kconfig"
> source "drivers/accel/habanalabs/Kconfig"
> source "drivers/accel/ivpu/Kconfig"
> source "drivers/accel/qaic/Kconfig"
> +source "drivers/accel/qda/Kconfig"
> source "drivers/accel/rocket/Kconfig"
>
> endif
> diff --git a/drivers/accel/Makefile b/drivers/accel/Makefile
> index 1d3a7251b950..58c08dd5f389 100644
> --- a/drivers/accel/Makefile
> +++ b/drivers/accel/Makefile
> @@ -5,4 +5,5 @@ obj-$(CONFIG_DRM_ACCEL_ARM_ETHOSU) += ethosu/
> obj-$(CONFIG_DRM_ACCEL_HABANALABS) += habanalabs/
> obj-$(CONFIG_DRM_ACCEL_IVPU) += ivpu/
> obj-$(CONFIG_DRM_ACCEL_QAIC) += qaic/
> +obj-$(CONFIG_DRM_ACCEL_QDA) += qda/
> obj-$(CONFIG_DRM_ACCEL_ROCKET) += rocket/
> \ No newline at end of file
You have trivial patch errors.
...
> +}
> +
> +static const struct of_device_id qda_rpmsg_id_table[] = {
> + { .compatible = "qcom,fastrpc" },
> + {},
Device node with this compatible is already populated, so this looks
simply wrong or you are adding a duplicated driver.
That's a no-go, you are supposed to work with existing drivers and grow
them.
Best regards,
Krzysztof
On Tue, Aug 18, 2026 at 10:40:25AM +0530, Ekansh Gupta wrote:
> The CB child nodes are not separate addressable hardware — they are SMMU
> stream-ID assignments described as sub-resources of the parent DSP
> interface.
So this is exactly the same thing.
Read my remarks here:
https://lore.kernel.org/linux-iommu/20260618151745.GD231643@ziepe.ca/
The DT modeling for devices that have multiple stream-IDs is to list
them all in iommus list.
If you don't like that DT modeling then you need to start out by
explaining why not very clearly.
There is undeniably a Linux gap where it forces all streams in the
iommus property to share a translation. This is a *linux* problem in
the iommu subsystem and DMA API. In an ideal world it should not be
fixed by hacking up new busses or mangling the DT.
But of the easy options I think hacking in new busses is the worst
option and has already been basically NAK'd for the hamoa project so
please don't use it here for a diferent qualcomm IP.
Given several qualcomm chips now have this same issue I strongly
suggest qualcomm consider trying to fix the root cause and provide
some way for a Linux driver to progmatically "unbundle" the multiple
streams.
It would be much easier if the HW properly supported actual sub
streams as we do already have a programming model for PASID. Maybe
some kind of driver thing to reconstruct the iommus so that each entry
is exposed as a PASID in the API instead of an alias or something like
that would be an easy direction.
Jason
On 8/13/26 09:46, Taimuraz Kaitmazov wrote:
> amdxdna_gem_obj_vmap() takes whatever dma_buf_vmap() returns and only
> rejects a NULL vaddr. iosys_map is discriminated by is_iomem, so an
> exporter answering with an I/O mapping leaves a void __iomem pointer in
> abo->mem.kva, which amdxdna_cmd_set_error() memsets and memcpys through.
>
> amdxdna_drm_va_tbl takes a dmabuf_fd, so such a BO can be any exporter's
> buffer. amdgpu cannot reach this: its .pin forces GTT for a non peer to
> peer attachment like ours. An exporter on drm_gem_prime_dmabuf_ops has
> no .pin, and drm_gem_ttm_vmap() answers iomem for a VRAM resident
> object, so an NPU paired with nouveau or radeon does.
>
> Refuse the mapping. vmw_gem_vmap() does the same; unlike that one this
> path is reachable from an unprivileged ioctl, so it does not warn.
>
> Signed-off-by: Taimuraz Kaitmazov <taimuraz(a)kaitmazov.com>
> ---
> drivers/accel/amdxdna/amdxdna_gem.c | 10 ++++++++--
> 1 file changed, 8 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/accel/amdxdna/amdxdna_gem.c b/drivers/accel/amdxdna/amdxdna_gem.c
> index 1f190b319bb..b66ec9e4828 100644
> --- a/drivers/accel/amdxdna/amdxdna_gem.c
> +++ b/drivers/accel/amdxdna/amdxdna_gem.c
> @@ -683,10 +683,16 @@ static int amdxdna_gem_obj_vmap(struct drm_gem_object *obj, struct iosys_map *ma
>
> dma_resv_assert_held(obj->resv);
>
> - if (is_import_bo(abo))
> + if (is_import_bo(abo)) {
> ret = dma_buf_vmap(abo->dma_buf, map);
> - else
> + /* Callers use mem.kva as an ordinary kernel address. */
> + if (!ret && map->is_iomem) {
> + dma_buf_vunmap(abo->dma_buf, map);
> + return -EOPNOTSUPP;
> + }
Thanks for the fix. The 'is_iomem' check should be moved to
amdxdna_gem_vmap() to cover all the cases.
Lizhi
> + } else {
> ret = drm_gem_shmem_object_vmap(obj, map);
> + }
> if (ret)
> return ret;
> if (!map->vaddr)
On Mon, Aug 17, 2026 at 10:17:40AM +0530, Ekansh Gupta wrote:
> Register the QDA compute context bank bus (qda-compute-cb) with the
> IOMMU subsystem by adding it to the iommu_buses[] array.
>
> The QDA driver creates synthetic devices on this bus to represent
> IOMMU context banks (CBs). Each CB device needs its own IOMMU domain
> so that the DSP memory manager can enforce per-session address space
> isolation. Without this registration, the IOMMU subsystem does not
> probe CB devices for IOMMU groups and of_dma_configure() in the bus
> dma_configure callback has no IOMMU domain to attach to.
I didn't notice a clear explanation of the proposed DT schema for this
But it looks awfully similar to the other driver that was creating a
kernel synthetic bus for actual real HW, that wasn't well liked.
What is this for? Why can't you have a normal DT binding for the
iommu with normal devices?
Jason
On Mon, Aug 17, 2026 at 10:17:40AM +0530, Ekansh Gupta wrote:
> Register the QDA compute context bank bus (qda-compute-cb) with the
> IOMMU subsystem by adding it to the iommu_buses[] array.
>
> The QDA driver creates synthetic devices on this bus to represent
> IOMMU context banks (CBs). Each CB device needs its own IOMMU domain
> so that the DSP memory manager can enforce per-session address space
> isolation. Without this registration, the IOMMU subsystem does not
> probe CB devices for IOMMU groups and of_dma_configure() in the bus
> dma_configure callback has no IOMMU domain to attach to.
>
> Assisted-by: Claude:claude-sonnet-5
> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov(a)oss.qualcomm.com>
> Signed-off-by: Ekansh Gupta <ekansh.gupta(a)oss.qualcomm.com>
> ---
> drivers/iommu/iommu.c | 4 ++++
> 1 file changed, 4 insertions(+)
Acked-by: Joerg Roedel <joerg.roedel(a)amd.com>
Hi all,
The goal of this series is to enable userspace driver designs that use
VFIO to export DMABUFs representing subsets of PCI device BARs, and
"vend" those buffers from a primary process to other subordinate
processes by fd. These processes then mmap() the buffers and their
access to the device is isolated to the exported ranges. This is an
improvement on sharing the VFIO device fd to subordinate processes,
which would allow unfettered access.
This is achieved by enabling mmap() of vfio-pci DMABUFs, passed by fd
to subordinate processes. Second, a new revocation mechanism is added
to allow the primary process to forcibly revoke access to
previously-shared BAR spans, even if the subordinate processes haven't
cleanly exited.
(The related topic of safe delegation of iommufd control to the
subordinate processes is not addressed here, and is follow-up work.)
The background/rationale is covered in more detail in the RFC cover
letters.
Feedback from the RFCs requested that, instead of creating
DMABUF-specific vm_ops and .fault paths, to go the whole way and
migrate the existing VFIO PCI BAR mmap() to be backed by a DMABUF too,
resulting in a common vm_ops and fault handler for mmap()s of both the
VFIO device and explicitly-exported DMABUFs. This will help future
iommufd emulation of VFIO Type1 peer-to-peer, making it easier to get
a DMABUF for a VFIO BAR as a DMA target.
mmap() conversion to use DMABUF underneath has been done for vfio-pci,
but not sub-drivers:
nvgrace-gpu's mmap() override path is unchanged; I kept this out of
scope for now not least because I don't have a thorough test setup
for this system. I would prefer to help the nvgrace-gpu maintainers
enable BAR mmap() DMABUFs themselves.
Notes on patches
================
PCI/P2PDMA: Split pool-related cleanup out of pci_p2pdma_release()
PCI/P2PDMA: Add CONFIG_PCI_P2PDMA_CORE
Later in the series, vfio-pci's mmap() is going to depend on
pcim_p2pdma_provider() which depended on CONFIG_PCI_P2PDMA, which
in turn depended on ZONE_DEVICE. That isn't available on 32-bit
and some archs, because they lack MEMORY_HOTPLUG and friends.
VFIO does _not_ require actual P2P to be present for basic mmap()
functionality, only for the optional CONFIG_DMA_SHARED_BUFFER
feature.
These split out p2pdma_core.c under CONFIG_PCI_P2PDMA_CORE (which
currently contains pcim_p2pdma_provider()), and an optional
CONFIG_PCI_P2PDMA which depends on ZONE_DEVICE etc. providing
P2P functionality in the existing p2pdma.c. The first splits
out pool cleanup from the release path, and the second does the
refactor/code move to the new file.
vfio/pci: Add a helper to look up PFNs for DMABUFs
vfio/pci: Add a helper to create a DMABUF for a BAR-map VMA
The first adds a DMABUF VMA fault handler helper to determine
arbitrary-sized PFNs from ranges in DMABUF. The second refactors
DMABUF export for use by the existing export feature, and adds a
helper that creates a DMABUF corresponding to a VFIO BAR mmap()
request.
vfio/pci: Convert BAR mmap() to use a DMABUF
The vfio-pci core mmap() creates a DMABUF with the helper above,
and the vm_ops fault handler uses the other helper to resolve the
fault. Because this depends on DMABUF structs/code,
CONFIG_VFIO_PCI_CORE needs to depend on CONFIG_DMA_SHARED_BUFFER.
The CONFIG_VFIO_PCI_DMABUF still conditionally enables the export
support code.
NOTE: The user mmap()s a device fd, but the resulting VMA's vm_file
becomes that of the DMABUF. The DMABUF takes ownership of the
device file and put()s it on release, which maintains the existing
behaviour of a VMA keeping the VFIO device open.
BAR zapping then happens via the existing vfio_pci_dma_buf_move()
path, which now needs to unmap PTEs in the DMABUF's address_space.
vfio/pci: Provide a user-facing name for BAR mappings
There was a request for decent debug naming in /proc/<pid>/maps
etc. comparable to the existing VFIO names: since the VMAs are
DMABUFs, they have a "dmabuf:" prefix and can't be 100% identical
to before. This is a user-visible change, but this patch at least
now gives us extra info on the BDF & BAR being mapped.
vfio/pci: Clean up BAR zap and revocation
In general (see NOTE!) the vfio_pci_zap_bars() is now obsolete,
since it unmaps PTEs in the VFIO device address_space which is now
unused. This consolidates all calls (e.g. around reset) with the
neighbouring vfio_pci_dma_buf_move()s into new functions, to
revoke/unrevoke (making the steps clearer).
NOTE: Because drivers can use their own vm_ops and override .mmap,
the core must conservatively assume an overridden .mmap might still
add PTEs to the VFIO device address_space and therefore still does
the zap. A new flag, zap_bars_on_revoke, enables the zap when
.mmap is overridden. A driver that does not need the zap can clear
this to opt-out, e.g. if the driver calls down to the common mmap
(and so uses DMABUFs). hisi-acc-vfio-pci does just this, and thus
sets the opt-out flag.
vfio/pci: Support mmap() of a VFIO DMABUF
Adds mmap() for a DMABUF fd exported from vfio-pci.
It was a goal to keep the VFIO device fd lifetime behaviour
unchanged with respect to the DMABUFs. An application can close
all device fds, and this will revoke/clean up all DMABUFs; then, no
mappings or other access can be performed. When enabling mmap() of
the DMABUFs, this means access through the VMA is also revoked.
This complicates the fault handler because whilst the DMABUF
exists, it has no guarantee that the corresponding VFIO device is
still alive. Adds synchronisation ensuring the vdev is available
before vdev->memory_lock is touched; this holds the device
registration so that even if the buffer has been cleaned up, vdev
hasn't been freed and so the lock can be safely taken.
vfio/pci: Permanently revoke a DMABUF on request
This is mostly a rename of `revoked` to an enum, `status`, and
adding a third state for a buffer: usable, revoked temporary,
revoked permanent. A new VFIO feature is added,
VFIO_DEVICE_FEATURE_DMA_BUF_REVOKE, which takes a DMABUF (exported
from the same device) and permanently revokes it. Thus a userspace
driver can guarantee any downstream consumers of a shared fd are
prevented from accessing a BAR range, and that range can be reused.
NOTE: This might block userspace, waiting on importers to detach.
The code doing revocation in vfio_pci_dma_buf_move() is moved, to a
common function for use by ..._move() and this new feature.
NOTE: See changelog, by request v4 added a condition to the
existing code to elide the unnecessary invalidation/sync on the
un-revoke path.)
NOTE: Previous versions contained an additional feature patch,
"vfio/pci: Add mmap() attributes to DMABUF feature". This has been
dropped in v5 because:
- The mechanism simply set vma->vm_page_prot. This would be
sufficient for arm64 and other architectures.
- However, (locally-run claude-opus-4-8) Sashiko flagged that, on
x86, additional memtype handling is required to set up the PAT.
Without this, the memtype is returned back to UC- by
pfnmap_setup_cachemode() upon PTE creation.
Most other sources of userspace WC mappings create PTEs eagerly with
e.g. io_remap_pfn_range() which memtype_reserve() WC for the range.
Getting them with lazy-fault used by vfio-pci is more complicated
(e.g. perhaps registering WC for BARs with PAT/MTRRs, and deciding how
to deal with aliasing...). Since this feature is not critical for
this series to be useful, I've decided for now to drop it in favour of
a simpler series now and revisiting this separ*ately.
Testing
=======
(The [RFC ONLY] userspace test program, for QEMU edu-plus, can be
found in the GitHub branch below. It at least illustrates how the
export, map, revoke, and close semantics interoperate.)
This code has been tested in mapping DMABUFs of single/multiple ranges
from multiple BARs, aliasing mmap()s, aliasing ranges across DMABUFs,
vm_pgoff > 0, revocation, shutdown/cleanup scenarios, and hugepage
mappings. No regressions observed on the VFIO selftests, or on our
internal vfio-pci applications. VFIO on i386 has been build-tested.
Dear Reviewers,
===============
I was grateful for the reviews and Reviewed-Bys on previous versions.
Thanks; I've added some Reviewed-Bys/Acks. I have NOT included your
tags where the patch has materially changed after your review (or
where requested changes ended up more than super-trivial). I hope
that's okay.
End
===
This is based on v7.2-rc3.
These commits are on GitHub for easier browsing, along with
"[RFC ONLY] selftests: vfio: Add standalone vfio_dmabuf_mmap_test":
https://github.com/metamev/linux/compare/v7.2-rc3...dev/mev/vfio-dmabuf-mma…
Thanks for reading,
Matt
================================================================================
Changelog:
v5:
- Rebased on 7.2-rc3
- Dropped the memattr/WC feature (see explanation above).
- "vfio/pci: Convert BAR mmap() to use a DMABUF": Fixed a
potentially-nasty bug (which (locally-run) Sashiko found!) whereby
the unmap_mapping_range() performed in cleanup was passed a range
up from offset zero for the DMABUF size. Initially this was how
all DMABUFs were created and an appropriate zap, but a new version
kept the VFIO region index encoded in the offset -- for BAR > 0 the
unmap span would then mismatch. Instead, pass size 0 to mean an
"all" range. Because the goal is to shoot down everything relating
to one DMABUF and the address_space can only contain things
relating to that DMABUF, this is equivalent and has the bonus of
never failing to match mappings...
Praan, Kevin, I kept your R-Bs on this fix.
- The revoke patch converts vfio_pci_dma_buf_cleanup()'s priv->vdev =
NULL to a WRITE_ONCE, corresponding to the revoke function's
READ_ONCE (performed to test that the VFIO and DMABUF are related).
- Clarified the VFIO_DEVICE_FEATURE_DMA_BUF_REVOKE UAPI comments,
documenting previously-missing error cases and their reasons.
v4: https://lore.kernel.org/all/20260701171245.90111-1-matt@ozlabs.org/
v3: https://lore.kernel.org/all/20260610154327.37758-1-matt@ozlabs.org/
v2: https://lore.kernel.org/all/20260527102319.100128-1-mattev@meta.com/
v1: https://lore.kernel.org/kvm/20260416131815.2729131-1-mattev@meta.com/
RFCv2: https://lore.kernel.org/kvm/20260312184613.3710705-1-mattev@meta.com/
RFCv1: https://lore.kernel.org/all/20260226202211.929005-1-mattev@meta.com/
Tech topic: https://lore.kernel.org/linux-iommu/20250918214425.2677057-1-amastro@fb.com/
Matt Evans (9):
PCI/P2PDMA: Split pool-related cleanup out of pci_p2pdma_release()
PCI/P2PDMA: Add CONFIG_PCI_P2PDMA_CORE
vfio/pci: Add a 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: Provide a user-facing name for BAR mappings
vfio/pci: Clean up BAR zap and revocation
vfio/pci: Support mmap() of a VFIO DMABUF
vfio/pci: Permanently revoke a DMABUF on request
MAINTAINERS | 2 +-
drivers/pci/Kconfig | 5 +
drivers/pci/Makefile | 1 +
drivers/pci/p2pdma.c | 113 +---
drivers/pci/p2pdma.h | 29 +
drivers/pci/p2pdma_core.c | 122 +++++
drivers/vfio/pci/Kconfig | 5 +-
drivers/vfio/pci/Makefile | 3 +-
.../vfio/pci/hisilicon/hisi_acc_vfio_pci.c | 8 +
drivers/vfio/pci/vfio_pci_config.c | 30 +-
drivers/vfio/pci/vfio_pci_core.c | 210 +++++--
drivers/vfio/pci/vfio_pci_dmabuf.c | 515 +++++++++++++++---
drivers/vfio/pci/vfio_pci_priv.h | 53 +-
include/linux/pci-p2pdma.h | 24 +-
include/linux/pci.h | 2 +-
include/linux/vfio_pci_core.h | 1 +
include/uapi/linux/vfio.h | 25 +
17 files changed, 875 insertions(+), 273 deletions(-)
create mode 100644 drivers/pci/p2pdma.h
create mode 100644 drivers/pci/p2pdma_core.c
--
2.50.1 (Apple Git-155)
On 8/12/26 01:13, Taimuraz Kaitmazov wrote:
> SYNC_BO carries an offset and a size, but amdxdna_flush_bo() honours them
> only on the vmap path. An imported BO is tested for first and flushes its
> whole scatterlist,
Absolutely clear NAK to that from a DMA-buf maintainer side.
Flushing on imported scatterlist of a DMA-buf is a really big NO-GO.
If DMA-buf imports are used with the device then the device needs to be able to coherently access the underlying memory.
In other words you *CAN'T* call drm_clflush_pages() on imported memory.
Regards,
Christian.
> so a sync costs what the BO is worth rather than what
> the caller asked to maintain: on npu4 an imported 64 MiB BO cost 1056 us
> to sync at every size from 4 KiB up. Patch 5 reorders the arms so the
> vmap path is tried first, and indexes the page-array fallback from the
> requested offset.
>
> The four before it are the ground that has to be solid first. Patch 1
> refuses an I/O memory mapping, which the driver currently stores as if it
> were an ordinary kernel address. Patch 2 adds a probe that does not log,
> so patch 5 does not make an exporter without a vmap op print on every
> ioctl. Patches 3 and 4 fix two ways the ioctl mishandles its own range: a
> zero length reaching drm_clflush_virt_range(), and an offset and size
> added to the BO address without an overflow check, one level above a
> function that checks the same arithmetic. All four stand on their own and
> can be taken separately; only patch 5 depends on them.
>
> v1 did not reach dri-devel, so this is the first version visible there.
> It is on lore via the other lists it was copied to:
> https://lore.kernel.org/lkml/20260811204556.875037-1-taimuraz@kaitmazov.com/
>
> Changes in v2:
> - patch 2: take the device from the GEM object rather than abo->client.
> amdxdna_gem_obj_close() clears that pointer under abo->lock, which the
> pre-split code held across the log and the split did not.
> - new patch 3: return early from a zero-length flush.
> - new patch 4: check the sync range for overflow on a device BO.
> - patch 5: say why the persistent mapping adds no pin.
>
> The measurements in patch 5 were taken with the equivalent change in
> AMD's out-of-tree xdna-driver, where this merged as #1541. That version
> and this one differ only in a page-array fallback mainline has no field
> for, reached when the mapping fails and the BO is neither imported nor
> shmem backed, and in the name of the mapping helper. The flush and the
> helper are otherwise identical. This version is compile-tested; it has
> not been booted.
>
> Patch 1 is from inspection rather than a reproducer. The exporter I can
> test against is amdgpu, and amdgpu is the case that cannot reach it: it
> implements .pin, so a non peer to peer attachment like this driver's
> forces the buffer to GTT before anything maps it. Reproducing it needs a
> GPU whose exporter has no .pin, which I do not have paired with an NPU
> here.
>
> Taimuraz Kaitmazov (5):
> accel/amdxdna: refuse an I/O memory mapping of an imported BO
> accel/amdxdna: add a quiet variant of amdxdna_gem_vmap()
> accel/amdxdna: return early from a zero-length flush
> accel/amdxdna: check the sync range for overflow on a device BO
> accel/amdxdna: flush only the requested range in amdxdna_flush_bo
>
> drivers/accel/amdxdna/amdxdna_gem.c | 66 +++++++++++++++++++++--------
> 1 file changed, 49 insertions(+), 17 deletions(-)
>
> --
> 2.55.0
>