Loading drivers/char/adsprpc.c +73 −20 Original line number Diff line number Diff line Loading @@ -264,6 +264,9 @@ enum fastrpc_msg_type { #define IS_ASYNC_FASTRPC_AVAILABLE (1) /* User PD Dump Name Max length */ #define RAMDUMP_NAME_MAX_LENGTH 20 static int fastrpc_pdr_notifier_cb(struct notifier_block *nb, unsigned long code, void *data); Loading Loading @@ -332,6 +335,7 @@ struct fastrpc_file; struct fastrpc_buf { struct hlist_node hn; struct hlist_node hn_rem; struct hlist_node hn_init; struct fastrpc_file *fl; void *virt; uint64_t phys; Loading Loading @@ -511,6 +515,7 @@ struct fastrpc_channel_ctx { struct smq_invoke_ctx *ctxtable[FASTRPC_CTX_MAX]; spinlock_t ctxlock; struct fastrpc_rpmsg_log gmsg_log; struct hlist_head initmems; }; struct fastrpc_apps { Loading Loading @@ -888,6 +893,23 @@ static inline void reset_unique_index(int index) mutex_unlock(&gfa.mut_uid); } /** * fastrpc_elf_ramdump - Dump given ram dump entry * @rh_dump_dev : Device handle for given channel * @ramdump_entry : Dump region entry * * Returns int */ static int fastrpc_elf_ramdump(void *rh_dump_dev, struct ramdump_segment *ramdump_seg) { int err = 0; err = do_elf_ramdump( rh_dump_dev, ramdump_seg, 1); return err; } /** * fastrpc_minidump_add_region - Add mini dump region Loading Loading @@ -2219,6 +2241,42 @@ static void fastrpc_notify_users_staticpd_pdr(struct fastrpc_file *me) spin_unlock(&me->hlock); } static void fastrpc_ramdump_collection(int cid) { struct fastrpc_file *fl = NULL; struct hlist_node *n = NULL; struct fastrpc_apps *me = &gfa; struct fastrpc_channel_ctx *chan = &me->channel[cid]; struct ramdump_segment ramdump_entry; struct fastrpc_buf *buf = NULL; int ret; char ramdump_name[RAMDUMP_NAME_MAX_LENGTH]; spin_lock(&me->hlock); hlist_for_each_entry_safe(fl, n, &me->drivers, hn) { if (fl->cid == cid && fl->init_mem) hlist_add_head(&fl->init_mem->hn_init, &chan->initmems); } spin_unlock(&me->hlock); if (chan->rh_dump_dev) { hlist_for_each_entry_safe(buf, n, &chan->initmems, hn_init) { ramdump_entry.address = buf->phys; ramdump_entry.v_address = (void __iomem *)buf->virt; ramdump_entry.size = buf->size; if (buf->fl) { scnprintf(ramdump_name, ARRAY_SIZE(ramdump_name), "%s_%x_", gcinfo[cid].subsys, buf->fl->tgid); ramdump_entry.name = ramdump_name; } ret = fastrpc_elf_ramdump(chan->rh_dump_dev, &ramdump_entry); if (ret < 0) pr_err("adsprpc: %s: unable to dump PD memory (err %d)\n", __func__, ret); hlist_del_init(&buf->hn_init); } } } static void fastrpc_notify_drivers(struct fastrpc_apps *me, int cid) { Loading Loading @@ -2891,6 +2949,7 @@ static void fastrpc_init(struct fastrpc_apps *me) mutex_init(&me->channel[i].rpmsg_mutex); spin_lock_init(&me->channel[i].ctxlock); spin_lock_init(&me->channel[i].gmsg_log.lock); INIT_HLIST_HEAD(&me->channel[i].initmems); } /* Set CDSP channel to non secure */ me->channel[CDSP_DOMAIN_ID].secure = NON_SECURE_CHANNEL; Loading Loading @@ -4436,7 +4495,7 @@ static int fastrpc_mmap_remove_ssr(struct fastrpc_file *fl) struct hlist_node *n = NULL; int err = 0, ret = 0; struct fastrpc_apps *me = &gfa; struct ramdump_segment *ramdump_segments_rh = NULL; struct ramdump_segment ramdump_segments_rh; VERIFY(err, fl->cid == RH_CID); if (err) { Loading @@ -4459,22 +4518,15 @@ static int fastrpc_mmap_remove_ssr(struct fastrpc_file *fl) if (err) goto bail; if (me->ramdump_handle && me->enable_ramdump) { ramdump_segments_rh = kcalloc(1, sizeof(struct ramdump_segment), GFP_KERNEL); if (ramdump_segments_rh) { ramdump_segments_rh->address = ramdump_segments_rh.address = match->phys; ramdump_segments_rh->v_address = ramdump_segments_rh.v_address = (void __iomem *)match->va; ramdump_segments_rh->size = match->size; ret = do_elf_ramdump( me->ramdump_handle, ramdump_segments_rh, 1); ramdump_segments_rh.size = match->size; ret = fastrpc_elf_ramdump(me->ramdump_handle, &ramdump_segments_rh); if (ret < 0) pr_err("adsprpc: %s: unable to dump heap (err %d)\n", __func__, ret); kfree(ramdump_segments_rh); } } fastrpc_mmap_free(match, 0); } Loading Loading @@ -4925,7 +4977,6 @@ static void fastrpc_rpmsg_remove(struct rpmsg_device *rpdev) { int err = 0; int cid = -1; struct fastrpc_apps *me = &gfa; VERIFY(err, !IS_ERR_OR_NULL(rpdev)); if (err) { Loading @@ -4942,7 +4993,6 @@ static void fastrpc_rpmsg_remove(struct rpmsg_device *rpdev) mutex_lock(&gcinfo[cid].rpmsg_mutex); gcinfo[cid].rpdev = NULL; mutex_unlock(&gcinfo[cid].rpmsg_mutex); fastrpc_notify_drivers(me, cid); ADSPRPC_INFO("closed rpmsg channel of %s\n", gcinfo[cid].subsys); bail: Loading Loading @@ -6112,6 +6162,8 @@ static int fastrpc_restart_notifier_cb(struct notifier_block *nb, if (me->ramdump_handle) me->channel[RH_CID].ramdumpenabled = 1; } if (cid == CDSP_DOMAIN_ID) fastrpc_ramdump_collection(cid); pr_info("adsprpc: %s: received RAMDUMP notification for %s\n", __func__, gcinfo[cid].subsys); } else if (code == SUBSYS_BEFORE_POWERUP) { Loading @@ -6122,6 +6174,7 @@ static int fastrpc_restart_notifier_cb(struct notifier_block *nb, me->channel[RH_CID].ramdumpenabled = 0; } } fastrpc_notify_drivers(me, cid); } else if (code == SUBSYS_AFTER_POWERUP) { pr_info("adsprpc: %s: %s subsystem is up\n", __func__, gcinfo[cid].subsys); Loading Loading @@ -6719,7 +6772,7 @@ static int __init fastrpc_device_init(void) pr_info("adsprpc: %s: SSR notifier registered for %s\n", __func__, gcinfo[i].subsys); } me->channel[CDSP_DOMAIN_ID].rh_dump_dev = create_ramdump_device("cdsp_minidump", NULL); err = register_rpmsg_driver(&fastrpc_rpmsg_client); if (err) { pr_err("Error: adsprpc: %s: register_rpmsg_driver failed with err %d\n", Loading Loading
drivers/char/adsprpc.c +73 −20 Original line number Diff line number Diff line Loading @@ -264,6 +264,9 @@ enum fastrpc_msg_type { #define IS_ASYNC_FASTRPC_AVAILABLE (1) /* User PD Dump Name Max length */ #define RAMDUMP_NAME_MAX_LENGTH 20 static int fastrpc_pdr_notifier_cb(struct notifier_block *nb, unsigned long code, void *data); Loading Loading @@ -332,6 +335,7 @@ struct fastrpc_file; struct fastrpc_buf { struct hlist_node hn; struct hlist_node hn_rem; struct hlist_node hn_init; struct fastrpc_file *fl; void *virt; uint64_t phys; Loading Loading @@ -511,6 +515,7 @@ struct fastrpc_channel_ctx { struct smq_invoke_ctx *ctxtable[FASTRPC_CTX_MAX]; spinlock_t ctxlock; struct fastrpc_rpmsg_log gmsg_log; struct hlist_head initmems; }; struct fastrpc_apps { Loading Loading @@ -888,6 +893,23 @@ static inline void reset_unique_index(int index) mutex_unlock(&gfa.mut_uid); } /** * fastrpc_elf_ramdump - Dump given ram dump entry * @rh_dump_dev : Device handle for given channel * @ramdump_entry : Dump region entry * * Returns int */ static int fastrpc_elf_ramdump(void *rh_dump_dev, struct ramdump_segment *ramdump_seg) { int err = 0; err = do_elf_ramdump( rh_dump_dev, ramdump_seg, 1); return err; } /** * fastrpc_minidump_add_region - Add mini dump region Loading Loading @@ -2219,6 +2241,42 @@ static void fastrpc_notify_users_staticpd_pdr(struct fastrpc_file *me) spin_unlock(&me->hlock); } static void fastrpc_ramdump_collection(int cid) { struct fastrpc_file *fl = NULL; struct hlist_node *n = NULL; struct fastrpc_apps *me = &gfa; struct fastrpc_channel_ctx *chan = &me->channel[cid]; struct ramdump_segment ramdump_entry; struct fastrpc_buf *buf = NULL; int ret; char ramdump_name[RAMDUMP_NAME_MAX_LENGTH]; spin_lock(&me->hlock); hlist_for_each_entry_safe(fl, n, &me->drivers, hn) { if (fl->cid == cid && fl->init_mem) hlist_add_head(&fl->init_mem->hn_init, &chan->initmems); } spin_unlock(&me->hlock); if (chan->rh_dump_dev) { hlist_for_each_entry_safe(buf, n, &chan->initmems, hn_init) { ramdump_entry.address = buf->phys; ramdump_entry.v_address = (void __iomem *)buf->virt; ramdump_entry.size = buf->size; if (buf->fl) { scnprintf(ramdump_name, ARRAY_SIZE(ramdump_name), "%s_%x_", gcinfo[cid].subsys, buf->fl->tgid); ramdump_entry.name = ramdump_name; } ret = fastrpc_elf_ramdump(chan->rh_dump_dev, &ramdump_entry); if (ret < 0) pr_err("adsprpc: %s: unable to dump PD memory (err %d)\n", __func__, ret); hlist_del_init(&buf->hn_init); } } } static void fastrpc_notify_drivers(struct fastrpc_apps *me, int cid) { Loading Loading @@ -2891,6 +2949,7 @@ static void fastrpc_init(struct fastrpc_apps *me) mutex_init(&me->channel[i].rpmsg_mutex); spin_lock_init(&me->channel[i].ctxlock); spin_lock_init(&me->channel[i].gmsg_log.lock); INIT_HLIST_HEAD(&me->channel[i].initmems); } /* Set CDSP channel to non secure */ me->channel[CDSP_DOMAIN_ID].secure = NON_SECURE_CHANNEL; Loading Loading @@ -4436,7 +4495,7 @@ static int fastrpc_mmap_remove_ssr(struct fastrpc_file *fl) struct hlist_node *n = NULL; int err = 0, ret = 0; struct fastrpc_apps *me = &gfa; struct ramdump_segment *ramdump_segments_rh = NULL; struct ramdump_segment ramdump_segments_rh; VERIFY(err, fl->cid == RH_CID); if (err) { Loading @@ -4459,22 +4518,15 @@ static int fastrpc_mmap_remove_ssr(struct fastrpc_file *fl) if (err) goto bail; if (me->ramdump_handle && me->enable_ramdump) { ramdump_segments_rh = kcalloc(1, sizeof(struct ramdump_segment), GFP_KERNEL); if (ramdump_segments_rh) { ramdump_segments_rh->address = ramdump_segments_rh.address = match->phys; ramdump_segments_rh->v_address = ramdump_segments_rh.v_address = (void __iomem *)match->va; ramdump_segments_rh->size = match->size; ret = do_elf_ramdump( me->ramdump_handle, ramdump_segments_rh, 1); ramdump_segments_rh.size = match->size; ret = fastrpc_elf_ramdump(me->ramdump_handle, &ramdump_segments_rh); if (ret < 0) pr_err("adsprpc: %s: unable to dump heap (err %d)\n", __func__, ret); kfree(ramdump_segments_rh); } } fastrpc_mmap_free(match, 0); } Loading Loading @@ -4925,7 +4977,6 @@ static void fastrpc_rpmsg_remove(struct rpmsg_device *rpdev) { int err = 0; int cid = -1; struct fastrpc_apps *me = &gfa; VERIFY(err, !IS_ERR_OR_NULL(rpdev)); if (err) { Loading @@ -4942,7 +4993,6 @@ static void fastrpc_rpmsg_remove(struct rpmsg_device *rpdev) mutex_lock(&gcinfo[cid].rpmsg_mutex); gcinfo[cid].rpdev = NULL; mutex_unlock(&gcinfo[cid].rpmsg_mutex); fastrpc_notify_drivers(me, cid); ADSPRPC_INFO("closed rpmsg channel of %s\n", gcinfo[cid].subsys); bail: Loading Loading @@ -6112,6 +6162,8 @@ static int fastrpc_restart_notifier_cb(struct notifier_block *nb, if (me->ramdump_handle) me->channel[RH_CID].ramdumpenabled = 1; } if (cid == CDSP_DOMAIN_ID) fastrpc_ramdump_collection(cid); pr_info("adsprpc: %s: received RAMDUMP notification for %s\n", __func__, gcinfo[cid].subsys); } else if (code == SUBSYS_BEFORE_POWERUP) { Loading @@ -6122,6 +6174,7 @@ static int fastrpc_restart_notifier_cb(struct notifier_block *nb, me->channel[RH_CID].ramdumpenabled = 0; } } fastrpc_notify_drivers(me, cid); } else if (code == SUBSYS_AFTER_POWERUP) { pr_info("adsprpc: %s: %s subsystem is up\n", __func__, gcinfo[cid].subsys); Loading Loading @@ -6719,7 +6772,7 @@ static int __init fastrpc_device_init(void) pr_info("adsprpc: %s: SSR notifier registered for %s\n", __func__, gcinfo[i].subsys); } me->channel[CDSP_DOMAIN_ID].rh_dump_dev = create_ramdump_device("cdsp_minidump", NULL); err = register_rpmsg_driver(&fastrpc_rpmsg_client); if (err) { pr_err("Error: adsprpc: %s: register_rpmsg_driver failed with err %d\n", Loading