diff --git a/drivers/char/adsprpc.c b/drivers/char/adsprpc.c index e8ba4bed8572..39bdf863b597 100644 --- a/drivers/char/adsprpc.c +++ b/drivers/char/adsprpc.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2012-2021, The Linux Foundation. All rights reserved. - * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022-2025 Qualcomm Innovation Center, Inc. All rights reserved. */ /* Uncomment this block to log an error on every VERIFY failure */ @@ -62,6 +62,7 @@ #define TZ_PIL_AUTH_QDSP6_PROC 1 #define FASTRPC_DMAHANDLE_NOMAP (16) +#define FASTRPC_MAP_DMA_HANDLE 0x20000 #define FASTRPC_ENOSUCH 39 #define DEBUGFS_SIZE 3072 @@ -1128,7 +1129,7 @@ static void fastrpc_mmap_add(struct fastrpc_mmap *map) } static int fastrpc_mmap_find(struct fastrpc_file *fl, int fd, - uintptr_t va, size_t len, int mflags, int refs, + uintptr_t va, size_t len, int mflags, bool refs, struct fastrpc_mmap **ppmap) { struct fastrpc_mmap *match = NULL, *map = NULL; @@ -1306,7 +1307,7 @@ static void fastrpc_mmap_free(struct fastrpc_mmap *map, uint32_t flags) dma_free_attrs(me->dev, map->size, (void *)map->va, (dma_addr_t)map->phys, (unsigned long)map->attr); } - } else if (map->flags == FASTRPC_DMAHANDLE_NOMAP) { + } else if (map->flags & FASTRPC_DMAHANDLE_NOMAP) { trace_fastrpc_dma_unmap(cid, map->phys, map->size); if (!IS_ERR_OR_NULL(map->table)) dma_buf_unmap_attachment(map->attach, map->table, @@ -1391,6 +1392,7 @@ static int fastrpc_mmap_create(struct fastrpc_file *fl, int fd, unsigned long flags; int err = 0, vmid, sgl_index = 0; struct scatterlist *sgl = NULL; + bool take_ref = true; if (!fl) { err = -EBADF; @@ -1404,7 +1406,9 @@ static int fastrpc_mmap_create(struct fastrpc_file *fl, int fd, } chan = &apps->channel[cid]; - if (!fastrpc_mmap_find(fl, fd, va, len, mflags, 1, ppmap)) + if (mflags & FASTRPC_MAP_DMA_HANDLE) + take_ref = false; + if (!fastrpc_mmap_find(fl, fd, va, len, mflags, take_ref, ppmap)) return 0; map = kzalloc(sizeof(*map), GFP_KERNEL); VERIFY(err, !IS_ERR_OR_NULL(map)); @@ -1442,7 +1446,7 @@ static int fastrpc_mmap_create(struct fastrpc_file *fl, int fd, if (err) goto bail; } - } else if (mflags == FASTRPC_DMAHANDLE_NOMAP) { + } else if (mflags & FASTRPC_DMAHANDLE_NOMAP) { VERIFY(err, !IS_ERR_OR_NULL(map->buf = dma_buf_get(fd))); if (err) { ADSPRPC_ERR("dma_buf_get failed for fd %d ret %ld\n", @@ -2496,10 +2500,10 @@ static int get_args(uint32_t kernel, struct smq_invoke_ctx *ctx) handles = REMOTE_SCALARS_INHANDLES(sc) + REMOTE_SCALARS_OUTHANDLES(sc); mutex_lock(&ctx->fl->map_mutex); for (i = bufs; i < bufs + handles; i++) { - int dmaflags = 0; + int dmaflags = FASTRPC_MAP_DMA_HANDLE; if (ctx->attrs && (ctx->attrs[i] & FASTRPC_ATTR_NOMAP)) - dmaflags = FASTRPC_DMAHANDLE_NOMAP; + dmaflags |= FASTRPC_DMAHANDLE_NOMAP; if (ctx->fds && (ctx->fds[i] != -1)) err = fastrpc_mmap_create(ctx->fl, ctx->fds[i], FASTRPC_ATTR_NOVA, 0, 0, dmaflags, @@ -2660,7 +2664,7 @@ static int get_args(uint32_t kernel, struct smq_invoke_ctx *ctx) if (ctx->maps[i]) { /* check if map still exist */ if (!fastrpc_mmap_find(ctx->fl, ctx->fds[i], 0, 0, - 0, 0, &mmap)) { + 0, false, &mmap)) { if (mmap) { pages[i].addr = mmap->phys; pages[i].size = mmap->size; @@ -2875,7 +2879,7 @@ static int put_args(uint32_t kernel, struct smq_invoke_ctx *ctx, if (!fdlist[i]) break; if (!fastrpc_mmap_find(ctx->fl, (int)fdlist[i], 0, 0, - 0, 0, &mmap)) { + 0, false, &mmap)) { if (mmap && mmap->dma_handle_refs) { mmap->dma_handle_refs = 0; fastrpc_mmap_free(mmap, 0); @@ -4955,7 +4959,7 @@ static int fastrpc_internal_munmap_fd(struct fastrpc_file *fl, } mutex_lock(&fl->internal_map_mutex); mutex_lock(&fl->map_mutex); - err = fastrpc_mmap_find(fl, ud->fd, ud->va, ud->len, 0, 0, &map); + err = fastrpc_mmap_find(fl, ud->fd, ud->va, ud->len, 0, false, &map); if (err) { ADSPRPC_ERR( "mapping not found to unmap fd 0x%x, va 0x%llx, len 0x%x, err %d\n", diff --git a/drivers/crypto/msm/qcedev_smmu.c b/drivers/crypto/msm/qcedev_smmu.c index 8d4844becc85..7039bce67c5c 100644 --- a/drivers/crypto/msm/qcedev_smmu.c +++ b/drivers/crypto/msm/qcedev_smmu.c @@ -329,10 +329,6 @@ int qcedev_check_and_map_buffer(void *handle, mapped_size = binfo->ion_buf.mapped_buf_size; atomic_inc(&binfo->ref_count); - /* Add buffer mapping information to regd buffer list */ - mutex_lock(&qce_hndl->registeredbufs.lock); - list_add_tail(&binfo->list, &qce_hndl->registeredbufs.list); - mutex_unlock(&qce_hndl->registeredbufs.lock); } /* Make sure the offset is within the mapped range */ @@ -344,6 +340,13 @@ int qcedev_check_and_map_buffer(void *handle, goto unmap; } + if (!found) { + /* Add buffer mapping information to regd buffer list */ + mutex_lock(&qce_hndl->registeredbufs.lock); + list_add_tail(&binfo->list, &qce_hndl->registeredbufs.list); + mutex_unlock(&qce_hndl->registeredbufs.lock); + } + /* return the mapped virtual address adjusted by offset */ *vaddr += offset; @@ -352,9 +355,6 @@ int qcedev_check_and_map_buffer(void *handle, unmap: if (!found) { qcedev_unmap_buffer(handle, mem_client, binfo); - mutex_lock(&qce_hndl->registeredbufs.lock); - list_del(&binfo->list); - mutex_unlock(&qce_hndl->registeredbufs.lock); } error: diff --git a/drivers/dma/qcom/gpi.c b/drivers/dma/qcom/gpi.c index 44e2e7de129e..eb9aea7851ff 100644 --- a/drivers/dma/qcom/gpi.c +++ b/drivers/dma/qcom/gpi.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2025, Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -2524,6 +2525,12 @@ struct dma_async_tx_descriptor *gpi_prep_slave_sg(struct dma_chan *chan, for_each_sg(sgl, sg, sg_len, i) { tre = sg_virt(sg); + if (!tre) { + kfree(gpi_desc); + GPII_ERR(gpii, gpii_chan->chid, "TRE address is null\n"); + return NULL; + } + if (sg_len == 1) { tre_type = MSM_GPI_TRE_TYPE(((struct msm_gpi_tre *)tre)); diff --git a/drivers/iommu/io-pgtable-fast.c b/drivers/iommu/io-pgtable-fast.c index f07e93b33f05..67ca5c20c521 100644 --- a/drivers/iommu/io-pgtable-fast.c +++ b/drivers/iommu/io-pgtable-fast.c @@ -133,7 +133,7 @@ typeof(base) __base = (base); \ typeof(pmds) __pmds = (pmds); \ (__iova < __base) ? ERR_PTR(-EINVAL) : \ - __pmds + ((__iova - __base) >> AV8L_FAST_PAGE_SHIFT); \ + __pmds + ((__iova - ALIGN_DOWN(__base, SZ_2M)) >> AV8L_FAST_PAGE_SHIFT); \ }) static inline dma_addr_t av8l_dma_addr(void *addr)