mirror of https://github.com/torvalds/linux.git
Char/Misc fixes for 6.18-rc1
Here are some small nvmem and fastrpc fixes for 6.18-rc1. They missed the cut-off to get into 6.17-final, due to me being slow in getting them out, my fault, not the maintainers of these subsystems :( Anyway, better late than never. Changes included in here are: - nvmem fix for automatic module loading - fastrpc driver fixes for reported issues All of these have been in linux-next for weeks (4?) with no reported issues. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -----BEGIN PGP SIGNATURE----- iG0EABECAC0WIQT0tgzFv3jCIUoxPcsxR9QN2y37KQUCaOUMwg8cZ3JlZ0Brcm9h aC5jb20ACgkQMUfUDdst+yletACgvGqfpfSAd3c08ex6F9eDNsQ1aAcAn2p+h0nL Xu/ja1YO8z+PBS6ji2Cz =ILvk -----END PGP SIGNATURE----- Merge tag 'char-misc-6.18-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc Pull char/misc fixes from Greg KH: "Here are some small nvmem and fastrpc fixes that missed the cut-off to get into 6.17-final, due to me being slow in getting them out, my fault, not the maintainers of these subsystems :( Anyway, better late than never. Changes included in here are: - nvmem fix for automatic module loading - fastrpc driver fixes for reported issues All of these have been in linux-next for weeks (4?) with no reported issues" * tag 'char-misc-6.18-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc: misc: fastrpc: Skip reference for DMA handles misc: fastrpc: fix possible map leak in fastrpc_put_args misc: fastrpc: Fix fastrpc_map_lookup operation misc: fastrpc: Save actual DMA size in fastrpc_map structure nvmem: layouts: fix automatic module loading
This commit is contained in:
commit
fdb8d00af9
|
|
@ -320,11 +320,11 @@ static void fastrpc_free_map(struct kref *ref)
|
|||
|
||||
perm.vmid = QCOM_SCM_VMID_HLOS;
|
||||
perm.perm = QCOM_SCM_PERM_RWX;
|
||||
err = qcom_scm_assign_mem(map->phys, map->size,
|
||||
err = qcom_scm_assign_mem(map->phys, map->len,
|
||||
&src_perms, &perm, 1);
|
||||
if (err) {
|
||||
dev_err(map->fl->sctx->dev, "Failed to assign memory phys 0x%llx size 0x%llx err %d\n",
|
||||
map->phys, map->size, err);
|
||||
map->phys, map->len, err);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -360,26 +360,21 @@ static int fastrpc_map_get(struct fastrpc_map *map)
|
|||
|
||||
|
||||
static int fastrpc_map_lookup(struct fastrpc_user *fl, int fd,
|
||||
struct fastrpc_map **ppmap, bool take_ref)
|
||||
struct fastrpc_map **ppmap)
|
||||
{
|
||||
struct fastrpc_session_ctx *sess = fl->sctx;
|
||||
struct fastrpc_map *map = NULL;
|
||||
struct dma_buf *buf;
|
||||
int ret = -ENOENT;
|
||||
|
||||
buf = dma_buf_get(fd);
|
||||
if (IS_ERR(buf))
|
||||
return PTR_ERR(buf);
|
||||
|
||||
spin_lock(&fl->lock);
|
||||
list_for_each_entry(map, &fl->maps, node) {
|
||||
if (map->fd != fd)
|
||||
if (map->fd != fd || map->buf != buf)
|
||||
continue;
|
||||
|
||||
if (take_ref) {
|
||||
ret = fastrpc_map_get(map);
|
||||
if (ret) {
|
||||
dev_dbg(sess->dev, "%s: Failed to get map fd=%d ret=%d\n",
|
||||
__func__, fd, ret);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
*ppmap = map;
|
||||
ret = 0;
|
||||
break;
|
||||
|
|
@ -749,16 +744,14 @@ static const struct dma_buf_ops fastrpc_dma_buf_ops = {
|
|||
.release = fastrpc_release,
|
||||
};
|
||||
|
||||
static int fastrpc_map_create(struct fastrpc_user *fl, int fd,
|
||||
static int fastrpc_map_attach(struct fastrpc_user *fl, int fd,
|
||||
u64 len, u32 attr, struct fastrpc_map **ppmap)
|
||||
{
|
||||
struct fastrpc_session_ctx *sess = fl->sctx;
|
||||
struct fastrpc_map *map = NULL;
|
||||
struct sg_table *table;
|
||||
int err = 0;
|
||||
|
||||
if (!fastrpc_map_lookup(fl, fd, ppmap, true))
|
||||
return 0;
|
||||
struct scatterlist *sgl = NULL;
|
||||
int err = 0, sgl_index = 0;
|
||||
|
||||
map = kzalloc(sizeof(*map), GFP_KERNEL);
|
||||
if (!map)
|
||||
|
|
@ -795,7 +788,15 @@ static int fastrpc_map_create(struct fastrpc_user *fl, int fd,
|
|||
map->phys = sg_dma_address(map->table->sgl);
|
||||
map->phys += ((u64)fl->sctx->sid << 32);
|
||||
}
|
||||
map->size = len;
|
||||
for_each_sg(map->table->sgl, sgl, map->table->nents,
|
||||
sgl_index)
|
||||
map->size += sg_dma_len(sgl);
|
||||
if (len > map->size) {
|
||||
dev_dbg(sess->dev, "Bad size passed len 0x%llx map size 0x%llx\n",
|
||||
len, map->size);
|
||||
err = -EINVAL;
|
||||
goto map_err;
|
||||
}
|
||||
map->va = sg_virt(map->table->sgl);
|
||||
map->len = len;
|
||||
|
||||
|
|
@ -812,10 +813,10 @@ static int fastrpc_map_create(struct fastrpc_user *fl, int fd,
|
|||
dst_perms[1].vmid = fl->cctx->vmperms[0].vmid;
|
||||
dst_perms[1].perm = QCOM_SCM_PERM_RWX;
|
||||
map->attr = attr;
|
||||
err = qcom_scm_assign_mem(map->phys, (u64)map->size, &src_perms, dst_perms, 2);
|
||||
err = qcom_scm_assign_mem(map->phys, (u64)map->len, &src_perms, dst_perms, 2);
|
||||
if (err) {
|
||||
dev_err(sess->dev, "Failed to assign memory with phys 0x%llx size 0x%llx err %d\n",
|
||||
map->phys, map->size, err);
|
||||
map->phys, map->len, err);
|
||||
goto map_err;
|
||||
}
|
||||
}
|
||||
|
|
@ -836,6 +837,24 @@ static int fastrpc_map_create(struct fastrpc_user *fl, int fd,
|
|||
return err;
|
||||
}
|
||||
|
||||
static int fastrpc_map_create(struct fastrpc_user *fl, int fd,
|
||||
u64 len, u32 attr, struct fastrpc_map **ppmap)
|
||||
{
|
||||
struct fastrpc_session_ctx *sess = fl->sctx;
|
||||
int err = 0;
|
||||
|
||||
if (!fastrpc_map_lookup(fl, fd, ppmap)) {
|
||||
if (!fastrpc_map_get(*ppmap))
|
||||
return 0;
|
||||
dev_dbg(sess->dev, "%s: Failed to get map fd=%d\n",
|
||||
__func__, fd);
|
||||
}
|
||||
|
||||
err = fastrpc_map_attach(fl, fd, len, attr, ppmap);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* Fastrpc payload buffer with metadata looks like:
|
||||
*
|
||||
|
|
@ -908,8 +927,12 @@ static int fastrpc_create_maps(struct fastrpc_invoke_ctx *ctx)
|
|||
ctx->args[i].length == 0)
|
||||
continue;
|
||||
|
||||
err = fastrpc_map_create(ctx->fl, ctx->args[i].fd,
|
||||
ctx->args[i].length, ctx->args[i].attr, &ctx->maps[i]);
|
||||
if (i < ctx->nbufs)
|
||||
err = fastrpc_map_create(ctx->fl, ctx->args[i].fd,
|
||||
ctx->args[i].length, ctx->args[i].attr, &ctx->maps[i]);
|
||||
else
|
||||
err = fastrpc_map_attach(ctx->fl, ctx->args[i].fd,
|
||||
ctx->args[i].length, ctx->args[i].attr, &ctx->maps[i]);
|
||||
if (err) {
|
||||
dev_err(dev, "Error Creating map %d\n", err);
|
||||
return -EINVAL;
|
||||
|
|
@ -1068,6 +1091,7 @@ static int fastrpc_put_args(struct fastrpc_invoke_ctx *ctx,
|
|||
struct fastrpc_phy_page *pages;
|
||||
u64 *fdlist;
|
||||
int i, inbufs, outbufs, handles;
|
||||
int ret = 0;
|
||||
|
||||
inbufs = REMOTE_SCALARS_INBUFS(ctx->sc);
|
||||
outbufs = REMOTE_SCALARS_OUTBUFS(ctx->sc);
|
||||
|
|
@ -1083,23 +1107,26 @@ static int fastrpc_put_args(struct fastrpc_invoke_ctx *ctx,
|
|||
u64 len = rpra[i].buf.len;
|
||||
|
||||
if (!kernel) {
|
||||
if (copy_to_user((void __user *)dst, src, len))
|
||||
return -EFAULT;
|
||||
if (copy_to_user((void __user *)dst, src, len)) {
|
||||
ret = -EFAULT;
|
||||
goto cleanup_fdlist;
|
||||
}
|
||||
} else {
|
||||
memcpy(dst, src, len);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cleanup_fdlist:
|
||||
/* Clean up fdlist which is updated by DSP */
|
||||
for (i = 0; i < FASTRPC_MAX_FDLIST; i++) {
|
||||
if (!fdlist[i])
|
||||
break;
|
||||
if (!fastrpc_map_lookup(fl, (int)fdlist[i], &mmap, false))
|
||||
if (!fastrpc_map_lookup(fl, (int)fdlist[i], &mmap))
|
||||
fastrpc_map_put(mmap);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int fastrpc_invoke_send(struct fastrpc_session_ctx *sctx,
|
||||
|
|
@ -2031,7 +2058,7 @@ static int fastrpc_req_mem_map(struct fastrpc_user *fl, char __user *argp)
|
|||
args[0].length = sizeof(req_msg);
|
||||
|
||||
pages.addr = map->phys;
|
||||
pages.size = map->size;
|
||||
pages.size = map->len;
|
||||
|
||||
args[1].ptr = (u64) (uintptr_t) &pages;
|
||||
args[1].length = sizeof(pages);
|
||||
|
|
@ -2046,7 +2073,7 @@ static int fastrpc_req_mem_map(struct fastrpc_user *fl, char __user *argp)
|
|||
err = fastrpc_internal_invoke(fl, true, FASTRPC_INIT_HANDLE, sc, &args[0]);
|
||||
if (err) {
|
||||
dev_err(dev, "mem mmap error, fd %d, vaddr %llx, size %lld\n",
|
||||
req.fd, req.vaddrin, map->size);
|
||||
req.fd, req.vaddrin, map->len);
|
||||
goto err_invoke;
|
||||
}
|
||||
|
||||
|
|
@ -2059,7 +2086,7 @@ static int fastrpc_req_mem_map(struct fastrpc_user *fl, char __user *argp)
|
|||
if (copy_to_user((void __user *)argp, &req, sizeof(req))) {
|
||||
/* unmap the memory and release the buffer */
|
||||
req_unmap.vaddr = (uintptr_t) rsp_msg.vaddr;
|
||||
req_unmap.length = map->size;
|
||||
req_unmap.length = map->len;
|
||||
fastrpc_req_mem_unmap_impl(fl, &req_unmap);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,11 +45,24 @@ static void nvmem_layout_bus_remove(struct device *dev)
|
|||
return drv->remove(layout);
|
||||
}
|
||||
|
||||
static int nvmem_layout_bus_uevent(const struct device *dev,
|
||||
struct kobj_uevent_env *env)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = of_device_uevent_modalias(dev, env);
|
||||
if (ret != ENODEV)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct bus_type nvmem_layout_bus_type = {
|
||||
.name = "nvmem-layout",
|
||||
.match = nvmem_layout_bus_match,
|
||||
.probe = nvmem_layout_bus_probe,
|
||||
.remove = nvmem_layout_bus_remove,
|
||||
.uevent = nvmem_layout_bus_uevent,
|
||||
};
|
||||
|
||||
int __nvmem_layout_driver_register(struct nvmem_layout_driver *drv,
|
||||
|
|
|
|||
Loading…
Reference in New Issue