Loading drivers/char/adsprpc.c +54 −13 Original line number Diff line number Diff line Loading @@ -522,7 +522,7 @@ static int fastrpc_mmap_remove(struct fastrpc_file *fl, uintptr_t va, return -ENOTTY; } static void fastrpc_mmap_free(struct fastrpc_mmap *map) static void fastrpc_mmap_free(struct fastrpc_mmap *map, uint32_t flags) { struct fastrpc_apps *me = &gfa; struct fastrpc_file *fl; Loading @@ -539,15 +539,17 @@ static void fastrpc_mmap_free(struct fastrpc_mmap *map) if (!map->refs) hlist_del_init(&map->hn); spin_unlock(&me->hlock); if (map->refs > 0) return; } else { spin_lock(&fl->hlock); map->refs--; if (!map->refs) hlist_del_init(&map->hn); spin_unlock(&fl->hlock); } if (map->refs > 0) if (map->refs > 0 && !flags) return; } if (map->flags == ADSP_MMAP_HEAP_ADDR || map->flags == ADSP_MMAP_REMOTE_HEAP_ADDR) { Loading Loading @@ -637,6 +639,11 @@ static int fastrpc_mmap_create(struct fastrpc_file *fl, int fd, map->size = len; map->va = (uintptr_t __user)map->phys; } else { if (map->attr && (map->attr & FASTRPC_ATTR_KEEP_MAP)) { pr_info("adsprpc: buffer mapped with persist attr %x\n", (unsigned int)map->attr); map->refs = 2; } VERIFY(err, !IS_ERR_OR_NULL(map->handle = ion_import_dma_buf_fd(fl->apps->client, fd))); if (err) Loading Loading @@ -726,7 +733,7 @@ static int fastrpc_mmap_create(struct fastrpc_file *fl, int fd, bail: if (err && map) fastrpc_mmap_free(map); fastrpc_mmap_free(map, 0); return err; } Loading Loading @@ -997,7 +1004,7 @@ static void context_free(struct smq_invoke_ctx *ctx) hlist_del_init(&ctx->hn); spin_unlock(&ctx->fl->hlock); for (i = 0; i < nbufs; ++i) fastrpc_mmap_free(ctx->maps[i]); fastrpc_mmap_free(ctx->maps[i], 0); fastrpc_buf_free(ctx->buf, 1); ctx->magic = 0; kfree(ctx); Loading Loading @@ -1347,7 +1354,7 @@ static int put_args(uint32_t kernel, struct smq_invoke_ctx *ctx, if (err) goto bail; } else { fastrpc_mmap_free(ctx->maps[i]); fastrpc_mmap_free(ctx->maps[i], 0); ctx->maps[i] = NULL; } } Loading @@ -1357,7 +1364,7 @@ static int put_args(uint32_t kernel, struct smq_invoke_ctx *ctx, break; if (!fastrpc_mmap_find(ctx->fl, (int)fdlist[i], 0, 0, 0, 0, &mmap)) fastrpc_mmap_free(mmap); fastrpc_mmap_free(mmap, 0); } } if (ctx->crc && crclist && rpra) Loading Loading @@ -1784,10 +1791,10 @@ static int fastrpc_init_process(struct fastrpc_file *fl, if (mem->flags == ADSP_MMAP_REMOTE_HEAP_ADDR) hyp_assign_phys(mem->phys, (uint64_t)mem->size, destVM, 1, srcVM, hlosVMperm, 1); fastrpc_mmap_free(mem); fastrpc_mmap_free(mem, 0); } if (file) fastrpc_mmap_free(file); fastrpc_mmap_free(file, 0); return err; } Loading Loading @@ -2018,7 +2025,7 @@ static int fastrpc_mmap_remove_ssr(struct fastrpc_file *fl) kfree(ramdump_segments_rh); } } fastrpc_mmap_free(match); fastrpc_mmap_free(match, 0); } } while (match); bail: Loading @@ -2044,13 +2051,36 @@ static int fastrpc_internal_munmap(struct fastrpc_file *fl, VERIFY(err, !fastrpc_munmap_on_dsp(fl, map)); if (err) goto bail; fastrpc_mmap_free(map); fastrpc_mmap_free(map, 0); bail: if (err && map) fastrpc_mmap_add(map); return err; } static int fastrpc_internal_munmap_fd(struct fastrpc_file *fl, struct fastrpc_ioctl_munmap_fd *ud) { int err = 0; struct fastrpc_mmap *map = NULL; VERIFY(err, (fl && ud)); if (err) goto bail; if (!fastrpc_mmap_find(fl, ud->fd, ud->va, ud->len, 0, 0, &map)) { pr_err("mapping not found to unamp %x va %llx %x\n", ud->fd, (unsigned long long)ud->va, (unsigned int)ud->len); err = -1; goto bail; } if (map) fastrpc_mmap_free(map, 0); bail: return err; } static int fastrpc_internal_mmap(struct fastrpc_file *fl, struct fastrpc_ioctl_mmap *ud) { Loading @@ -2073,7 +2103,7 @@ static int fastrpc_internal_mmap(struct fastrpc_file *fl, ud->vaddrout = map->raddr; bail: if (err && map) fastrpc_mmap_free(map); fastrpc_mmap_free(map, 0); return err; } Loading Loading @@ -2243,7 +2273,7 @@ static int fastrpc_file_free(struct fastrpc_file *fl) fastrpc_context_list_dtor(fl); fastrpc_buf_list_free(fl); hlist_for_each_entry_safe(map, n, &fl->maps, hn) { fastrpc_mmap_free(map); fastrpc_mmap_free(map, 1); } if (fl->ssrcount == fl->apps->channel[cid].ssrcount) kref_put_mutex(&fl->apps->channel[cid].kref, Loading Loading @@ -2677,6 +2707,7 @@ static long fastrpc_device_ioctl(struct file *file, unsigned int ioctl_num, struct fastrpc_ioctl_invoke_crc inv; struct fastrpc_ioctl_mmap mmap; struct fastrpc_ioctl_munmap munmap; struct fastrpc_ioctl_munmap_fd munmap_fd; struct fastrpc_ioctl_init_attrs init; struct fastrpc_ioctl_perf perf; struct fastrpc_ioctl_control cp; Loading Loading @@ -2743,6 +2774,16 @@ static long fastrpc_device_ioctl(struct file *file, unsigned int ioctl_num, if (err) goto bail; break; case FASTRPC_IOCTL_MUNMAP_FD: K_COPY_FROM_USER(err, 0, &p.munmap_fd, param, sizeof(p.munmap_fd)); if (err) goto bail; VERIFY(err, 0 == (err = fastrpc_internal_munmap_fd(fl, &p.munmap_fd))); if (err) goto bail; break; case FASTRPC_IOCTL_SETMODE: switch ((uint32_t)ioctl_param) { case FASTRPC_MODE_PARALLEL: Loading drivers/char/adsprpc_shared.h +11 −0 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ #define FASTRPC_IOCTL_INIT_ATTRS _IOWR('R', 10, struct fastrpc_ioctl_init_attrs) #define FASTRPC_IOCTL_INVOKE_CRC _IOWR('R', 11, struct fastrpc_ioctl_invoke_crc) #define FASTRPC_IOCTL_CONTROL _IOWR('R', 12, struct fastrpc_ioctl_control) #define FASTRPC_IOCTL_MUNMAP_FD _IOWR('R', 13, struct fastrpc_ioctl_munmap_fd) #define FASTRPC_GLINK_GUID "fastrpcglink-apps-dsp" #define FASTRPC_SMD_GUID "fastrpcsmd-apps-dsp" Loading @@ -43,6 +44,9 @@ /* Set for buffers that are dma coherent */ #define FASTRPC_ATTR_COHERENT 0x4 /* Fastrpc attribute for keeping the map persistent */ #define FASTRPC_ATTR_KEEP_MAP 0x8 /* Driver should operate in parallel with the co-processor */ #define FASTRPC_MODE_PARALLEL 0 Loading Loading @@ -204,6 +208,13 @@ struct fastrpc_ioctl_mmap { uintptr_t vaddrout; /* dsps virtual address */ }; struct fastrpc_ioctl_munmap_fd { int fd; /* fd */ uint32_t flags; /* control flags */ uintptr_t va; /* va */ ssize_t len; /* length */ }; struct fastrpc_ioctl_perf { /* kernel performance data */ uintptr_t __user data; uint32_t numkeys; Loading Loading
drivers/char/adsprpc.c +54 −13 Original line number Diff line number Diff line Loading @@ -522,7 +522,7 @@ static int fastrpc_mmap_remove(struct fastrpc_file *fl, uintptr_t va, return -ENOTTY; } static void fastrpc_mmap_free(struct fastrpc_mmap *map) static void fastrpc_mmap_free(struct fastrpc_mmap *map, uint32_t flags) { struct fastrpc_apps *me = &gfa; struct fastrpc_file *fl; Loading @@ -539,15 +539,17 @@ static void fastrpc_mmap_free(struct fastrpc_mmap *map) if (!map->refs) hlist_del_init(&map->hn); spin_unlock(&me->hlock); if (map->refs > 0) return; } else { spin_lock(&fl->hlock); map->refs--; if (!map->refs) hlist_del_init(&map->hn); spin_unlock(&fl->hlock); } if (map->refs > 0) if (map->refs > 0 && !flags) return; } if (map->flags == ADSP_MMAP_HEAP_ADDR || map->flags == ADSP_MMAP_REMOTE_HEAP_ADDR) { Loading Loading @@ -637,6 +639,11 @@ static int fastrpc_mmap_create(struct fastrpc_file *fl, int fd, map->size = len; map->va = (uintptr_t __user)map->phys; } else { if (map->attr && (map->attr & FASTRPC_ATTR_KEEP_MAP)) { pr_info("adsprpc: buffer mapped with persist attr %x\n", (unsigned int)map->attr); map->refs = 2; } VERIFY(err, !IS_ERR_OR_NULL(map->handle = ion_import_dma_buf_fd(fl->apps->client, fd))); if (err) Loading Loading @@ -726,7 +733,7 @@ static int fastrpc_mmap_create(struct fastrpc_file *fl, int fd, bail: if (err && map) fastrpc_mmap_free(map); fastrpc_mmap_free(map, 0); return err; } Loading Loading @@ -997,7 +1004,7 @@ static void context_free(struct smq_invoke_ctx *ctx) hlist_del_init(&ctx->hn); spin_unlock(&ctx->fl->hlock); for (i = 0; i < nbufs; ++i) fastrpc_mmap_free(ctx->maps[i]); fastrpc_mmap_free(ctx->maps[i], 0); fastrpc_buf_free(ctx->buf, 1); ctx->magic = 0; kfree(ctx); Loading Loading @@ -1347,7 +1354,7 @@ static int put_args(uint32_t kernel, struct smq_invoke_ctx *ctx, if (err) goto bail; } else { fastrpc_mmap_free(ctx->maps[i]); fastrpc_mmap_free(ctx->maps[i], 0); ctx->maps[i] = NULL; } } Loading @@ -1357,7 +1364,7 @@ static int put_args(uint32_t kernel, struct smq_invoke_ctx *ctx, break; if (!fastrpc_mmap_find(ctx->fl, (int)fdlist[i], 0, 0, 0, 0, &mmap)) fastrpc_mmap_free(mmap); fastrpc_mmap_free(mmap, 0); } } if (ctx->crc && crclist && rpra) Loading Loading @@ -1784,10 +1791,10 @@ static int fastrpc_init_process(struct fastrpc_file *fl, if (mem->flags == ADSP_MMAP_REMOTE_HEAP_ADDR) hyp_assign_phys(mem->phys, (uint64_t)mem->size, destVM, 1, srcVM, hlosVMperm, 1); fastrpc_mmap_free(mem); fastrpc_mmap_free(mem, 0); } if (file) fastrpc_mmap_free(file); fastrpc_mmap_free(file, 0); return err; } Loading Loading @@ -2018,7 +2025,7 @@ static int fastrpc_mmap_remove_ssr(struct fastrpc_file *fl) kfree(ramdump_segments_rh); } } fastrpc_mmap_free(match); fastrpc_mmap_free(match, 0); } } while (match); bail: Loading @@ -2044,13 +2051,36 @@ static int fastrpc_internal_munmap(struct fastrpc_file *fl, VERIFY(err, !fastrpc_munmap_on_dsp(fl, map)); if (err) goto bail; fastrpc_mmap_free(map); fastrpc_mmap_free(map, 0); bail: if (err && map) fastrpc_mmap_add(map); return err; } static int fastrpc_internal_munmap_fd(struct fastrpc_file *fl, struct fastrpc_ioctl_munmap_fd *ud) { int err = 0; struct fastrpc_mmap *map = NULL; VERIFY(err, (fl && ud)); if (err) goto bail; if (!fastrpc_mmap_find(fl, ud->fd, ud->va, ud->len, 0, 0, &map)) { pr_err("mapping not found to unamp %x va %llx %x\n", ud->fd, (unsigned long long)ud->va, (unsigned int)ud->len); err = -1; goto bail; } if (map) fastrpc_mmap_free(map, 0); bail: return err; } static int fastrpc_internal_mmap(struct fastrpc_file *fl, struct fastrpc_ioctl_mmap *ud) { Loading @@ -2073,7 +2103,7 @@ static int fastrpc_internal_mmap(struct fastrpc_file *fl, ud->vaddrout = map->raddr; bail: if (err && map) fastrpc_mmap_free(map); fastrpc_mmap_free(map, 0); return err; } Loading Loading @@ -2243,7 +2273,7 @@ static int fastrpc_file_free(struct fastrpc_file *fl) fastrpc_context_list_dtor(fl); fastrpc_buf_list_free(fl); hlist_for_each_entry_safe(map, n, &fl->maps, hn) { fastrpc_mmap_free(map); fastrpc_mmap_free(map, 1); } if (fl->ssrcount == fl->apps->channel[cid].ssrcount) kref_put_mutex(&fl->apps->channel[cid].kref, Loading Loading @@ -2677,6 +2707,7 @@ static long fastrpc_device_ioctl(struct file *file, unsigned int ioctl_num, struct fastrpc_ioctl_invoke_crc inv; struct fastrpc_ioctl_mmap mmap; struct fastrpc_ioctl_munmap munmap; struct fastrpc_ioctl_munmap_fd munmap_fd; struct fastrpc_ioctl_init_attrs init; struct fastrpc_ioctl_perf perf; struct fastrpc_ioctl_control cp; Loading Loading @@ -2743,6 +2774,16 @@ static long fastrpc_device_ioctl(struct file *file, unsigned int ioctl_num, if (err) goto bail; break; case FASTRPC_IOCTL_MUNMAP_FD: K_COPY_FROM_USER(err, 0, &p.munmap_fd, param, sizeof(p.munmap_fd)); if (err) goto bail; VERIFY(err, 0 == (err = fastrpc_internal_munmap_fd(fl, &p.munmap_fd))); if (err) goto bail; break; case FASTRPC_IOCTL_SETMODE: switch ((uint32_t)ioctl_param) { case FASTRPC_MODE_PARALLEL: Loading
drivers/char/adsprpc_shared.h +11 −0 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ #define FASTRPC_IOCTL_INIT_ATTRS _IOWR('R', 10, struct fastrpc_ioctl_init_attrs) #define FASTRPC_IOCTL_INVOKE_CRC _IOWR('R', 11, struct fastrpc_ioctl_invoke_crc) #define FASTRPC_IOCTL_CONTROL _IOWR('R', 12, struct fastrpc_ioctl_control) #define FASTRPC_IOCTL_MUNMAP_FD _IOWR('R', 13, struct fastrpc_ioctl_munmap_fd) #define FASTRPC_GLINK_GUID "fastrpcglink-apps-dsp" #define FASTRPC_SMD_GUID "fastrpcsmd-apps-dsp" Loading @@ -43,6 +44,9 @@ /* Set for buffers that are dma coherent */ #define FASTRPC_ATTR_COHERENT 0x4 /* Fastrpc attribute for keeping the map persistent */ #define FASTRPC_ATTR_KEEP_MAP 0x8 /* Driver should operate in parallel with the co-processor */ #define FASTRPC_MODE_PARALLEL 0 Loading Loading @@ -204,6 +208,13 @@ struct fastrpc_ioctl_mmap { uintptr_t vaddrout; /* dsps virtual address */ }; struct fastrpc_ioctl_munmap_fd { int fd; /* fd */ uint32_t flags; /* control flags */ uintptr_t va; /* va */ ssize_t len; /* length */ }; struct fastrpc_ioctl_perf { /* kernel performance data */ uintptr_t __user data; uint32_t numkeys; Loading