[PATCH 1/3] accel/amdxdna: refuse an I/O memory mapping of an imported BO
From: Taimuraz Kaitmazov
Date: Tue Aug 11 2026 - 16:47:02 EST
amdxdna_gem_obj_vmap() accepts whatever dma_buf_vmap() returns and only
rejects a NULL vaddr. struct iosys_map is a union discriminated by
is_iomem, so an exporter that answers with an I/O mapping leaves a
void __iomem pointer in map->vaddr, and amdxdna_gem_vmap() stores it in
abo->mem.kva, which callers use as an ordinary kernel address:
amdxdna_cmd_set_error() memsets and memcpys through it.
amdxdna_drm_va_tbl takes a dmabuf_fd, so a BO of type AMDXDNA_BO_SHARE
or AMDXDNA_BO_CMD can be any exporter's buffer. Whether such a buffer is
still in a bus aperture when it is mapped depends on the exporter.
amdxdna attaches without importer ops, so an exporter that implements
.pin has it called before the mapping, and amdgpu's removes VRAM from
the allowed domains as soon as one attachment cannot do peer to peer,
which this driver's cannot; an amdgpu buffer is therefore in GTT
before any of this runs. An exporter using drm_gem_prime_dmabuf_ops
has no .pin at all, nothing moves the buffer, and drm_gem_ttm_vmap()
answers with iosys_map_set_vaddr_iomem() for a VRAM resident object.
nouveau and radeon are in that group, so an NPU paired with one of
those GPUs reaches this.
Refuse the mapping, so it never reaches a caller that cannot use it.
vmw_gem_vmap() does the same for the same reason. Unlike that one, this
path is reachable from an unprivileged ioctl, so it does not warn;
-EOPNOTSUPP is what drm_gem_vmap_locked() already returns here for an
exporter with no vmap op.
Signed-off-by: Taimuraz Kaitmazov <taimuraz@xxxxxxxxxxxxx>
---
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 1f190b319..b66ec9e48 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;
+ }
+ } else {
ret = drm_gem_shmem_object_vmap(obj, map);
+ }
if (ret)
return ret;
if (!map->vaddr)
--
2.55.0