Loading drivers/char/adsprpc.c +379 −323 Original line number Diff line number Diff line Loading @@ -65,14 +65,17 @@ #define UL_SIZE 25 #define PID_SIZE 10 #define AUDIO_PDR_ADSP_DTSI_PROPERTY_NAME "qcom,fastrpc-adsp-audio-pdr" #define AUDIO_PDR_SERVICE_LOCATION_CLIENT_NAME "audio_pdr_adsprpc" #define AUDIO_PDR_ADSP_SERVICE_NAME "avs/audio" #define ADSP_AUDIOPD_NAME "msm/adsp/audio_pd" #define SENSORS_PDR_ADSP_DTSI_PROPERTY_NAME "qcom,fastrpc-adsp-sensors-pdr" #define SENSORS_PDR_ADSP_SERVICE_LOCATION_CLIENT_NAME "sensors_pdr_adsprpc" #define SENSORS_PDR_ADSP_SERVICE_NAME "tms/servreg" #define ADSP_SENSORPD_NAME "msm/adsp/sensor_pd" #define SENSORS_PDR_SLPI_DTSI_PROPERTY_NAME "qcom,fastrpc-slpi-sensors-pdr" #define SENSORS_PDR_SLPI_SERVICE_LOCATION_CLIENT_NAME "sensors_pdr_sdsprpc" #define SENSORS_PDR_SLPI_SERVICE_NAME SENSORS_PDR_ADSP_SERVICE_NAME #define SLPI_SENSORPD_NAME "msm/slpi/sensor_pd" Loading Loading @@ -200,6 +203,12 @@ (int64_t *)(perf_ptr + offset)\ : (int64_t *)NULL) : (int64_t *)NULL) /* Macro for comparing local client and PD names with those from callback */ #define COMPARE_SERVICE_LOCATOR_NAMES(cb_client, local_client, \ cb_pdname, local_pdname) \ ((!strcmp(cb_client, local_client)) \ && (!strcmp(cb_pdname, local_pdname))) #define IS_ASYNC_FASTRPC_AVAILABLE (1) static int fastrpc_pdr_notifier_cb(struct notifier_block *nb, Loading Loading @@ -2706,29 +2715,24 @@ static int fastrpc_mmap_remove_pdr(struct fastrpc_file *fl); static int fastrpc_channel_open(struct fastrpc_file *fl); static int fastrpc_mmap_remove_ssr(struct fastrpc_file *fl); static void fastrpc_check_privileged_process(struct fastrpc_file *fl, struct fastrpc_ioctl_init_attrs *uproc) { unsigned int gid = sorted_lists_intersection(fl->gidlist.gids, fl->gidlist.gidcount, gfa.gidlist.gids, gfa.gidlist.gidcount); /* disregard any privilege bits from userspace */ uproc->attrs &= (~FASTRPC_MODE_PRIVILEGED); if (gid) { pr_info("adsprpc: %s: %s (PID %d, GID %u) is a privileged process\n", __func__, current->comm, fl->tgid, gid); uproc->attrs |= FASTRPC_MODE_PRIVILEGED; } } /* * This function makes a call to create a thread group in the root * process or static process on the remote subsystem. * Examples: * - guestOS daemons on all DSPs * - sensors daemon on sensorsPD on SLPI/ADSP */ static int fastrpc_init_attach_process(struct fastrpc_file *fl, struct fastrpc_ioctl_init *init) { int err = 0; int err = 0, tgid = fl->tgid; remote_arg_t ra[1]; struct fastrpc_ioctl_invoke_async ioctl; int tgid = fl->tgid; /* * Prepare remote arguments for creating thread group * in guestOS/staticPD on the remote subsystem. */ ra[0].buf.pv = (void *)&tgid; ra[0].buf.len = sizeof(tgid); ioctl.inv.handle = FASTRPC_STATIC_HANDLE_PROCESS_GROUP; Loading @@ -2738,6 +2742,7 @@ static int fastrpc_init_attach_process(struct fastrpc_file *fl, ioctl.attrs = NULL; ioctl.crc = NULL; ioctl.job = NULL; if (init->flags == FASTRPC_INIT_ATTACH) fl->pd = 0; else if (init->flags == FASTRPC_INIT_ATTACH_SENSORS) { Loading @@ -2747,50 +2752,35 @@ static int fastrpc_init_attach_process(struct fastrpc_file *fl, else if (fl->cid == SDSP_DOMAIN_ID) fl->servloc_name = SENSORS_PDR_SLPI_SERVICE_LOCATION_CLIENT_NAME; /* Setting to 2 will route the message to sensorsPD */ fl->pd = 2; } VERIFY(err, !(err = fastrpc_internal_invoke(fl, FASTRPC_MODE_PARALLEL, 1, &ioctl))); err = fastrpc_internal_invoke(fl, FASTRPC_MODE_PARALLEL, 1, &ioctl); if (err) goto bail; bail: return err; } static int fastrpc_init_process(struct fastrpc_file *fl, /* * This function makes a call to spawn a dynamic process * on the remote subsystem. * Example: all compute offloads to CDSP */ static int fastrpc_init_create_dynamic_process(struct fastrpc_file *fl, struct fastrpc_ioctl_init_attrs *uproc) { int err = 0, rh_hyp_done = 0; struct fastrpc_apps *me = &gfa; int err = 0, memlen = 0, mflags = 0; struct fastrpc_ioctl_invoke_async ioctl; struct fastrpc_ioctl_init *init = &uproc->init; struct smq_phy_page pages[1]; struct fastrpc_mmap *file = NULL, *mem = NULL; struct fastrpc_mmap *file = NULL; struct fastrpc_buf *imem = NULL; unsigned long imem_dma_attr = 0; char *proc_name = NULL; VERIFY(err, init->filelen >= 0 && init->filelen < INIT_FILELEN_MAX); if (err) goto bail; VERIFY(err, init->memlen >= 0 && init->memlen < INIT_MEMLEN_MAX); if (err) goto bail; VERIFY(err, 0 == (err = fastrpc_channel_open(fl))); if (err) goto bail; if (init->flags == FASTRPC_INIT_ATTACH || init->flags == FASTRPC_INIT_ATTACH_SENSORS) { VERIFY(err, !(err = fastrpc_init_attach_process(fl, init))); if (err) goto bail; } else if (init->flags == FASTRPC_INIT_CREATE) { int memlen; remote_arg_t ra[6]; int fds[6]; int mflags = 0; unsigned int gid = 0, one_mb = 1024*1024; struct { int pgid; unsigned int namelen; Loading @@ -2805,22 +2795,41 @@ static int fastrpc_init_process(struct fastrpc_file *fl, inbuf.filelen = init->filelen; fl->pd = 1; VERIFY(err, access_ok((void __user *)init->file, init->filelen)); /* Check if file memory passed by userspace is valid */ VERIFY(err, access_ok((void __user *)init->file, init->filelen)); if (err) goto bail; if (init->filelen) { /* Map the shell file buffer to remote subsystem */ mutex_lock(&fl->map_mutex); VERIFY(err, !fastrpc_mmap_create(fl, init->filefd, 0, init->file, init->filelen, mflags, &file)); err = fastrpc_mmap_create(fl, init->filefd, 0, init->file, init->filelen, mflags, &file); mutex_unlock(&fl->map_mutex); if (err) goto bail; } inbuf.pageslen = 1; fastrpc_check_privileged_process(fl, uproc); /* Disregard any privilege bits from userspace */ uproc->attrs &= (~FASTRPC_MODE_PRIVILEGED); /* * Check if the primary or supplementary group(s) of the process is * one of the 'privileged' fastrpc GIDs stored in the device-tree. */ gid = sorted_lists_intersection(fl->gidlist.gids, fl->gidlist.gidcount, gfa.gidlist.gids, gfa.gidlist.gidcount); if (gid) { pr_info("adsprpc: %s: %s (PID %d, GID %u) is a privileged process\n", __func__, current->comm, fl->tgid, gid); uproc->attrs |= FASTRPC_MODE_PRIVILEGED; } /* * Userspace client should try to allocate the initial memory donated * to remote subsystem as only the kernel and DSP should have access * to that memory. */ VERIFY(err, !init->mem); if (err) { err = -EINVAL; Loading @@ -2828,18 +2837,24 @@ static int fastrpc_init_process(struct fastrpc_file *fl, current->comm, __func__); goto bail; } memlen = ALIGN(max(1024*1024*3, (int)init->filelen * 4), 1024*1024); /* Free any previous donated memory */ if (fl->init_mem) fastrpc_buf_free(fl->init_mem, 0); /* Allocate DMA buffer in kernel for donating to remote process */ memlen = ALIGN(max(3*one_mb, init->filelen * 4), one_mb); imem_dma_attr = DMA_ATTR_EXEC_MAPPING | DMA_ATTR_DELAYED_UNMAP | DMA_ATTR_NO_KERNEL_MAPPING; err = fastrpc_buf_alloc(fl, memlen, imem_dma_attr, 0, 0, &imem); if (err) goto bail; if (fl->init_mem) fastrpc_buf_free(fl->init_mem, 0); fl->init_mem = imem; /* * Prepare remote arguments for dynamic process create * call to remote subsystem. */ inbuf.pageslen = 1; ra[0].buf.pv = (void *)&inbuf; ra[0].buf.len = sizeof(inbuf); Loading Loading @@ -2870,6 +2885,11 @@ static int fastrpc_init_process(struct fastrpc_file *fl, fds[5] = -1; ioctl.inv.handle = FASTRPC_STATIC_HANDLE_PROCESS_GROUP; /* * Choose appropriate remote method ID depending on whether the * HLOS process has any attributes enabled (like unsignedPD, * critical process, adaptive QoS, CRC checks etc). */ ioctl.inv.sc = REMOTE_SCALARS_MAKE(6, 4, 0); if (uproc->attrs) ioctl.inv.sc = REMOTE_SCALARS_MAKE(7, 6, 0); Loading @@ -2878,15 +2898,48 @@ static int fastrpc_init_process(struct fastrpc_file *fl, ioctl.attrs = NULL; ioctl.crc = NULL; ioctl.job = NULL; VERIFY(err, !(err = fastrpc_internal_invoke(fl, FASTRPC_MODE_PARALLEL, 1, &ioctl))); err = fastrpc_internal_invoke(fl, FASTRPC_MODE_PARALLEL, 1, &ioctl); if (err) goto bail; } else if (init->flags == FASTRPC_INIT_CREATE_STATIC) { bail: /* * Shell is loaded into the donated memory on remote subsystem. So, the * original file buffer can be DMA unmapped. In case of a failure also, * the mapping needs to be removed. */ if (file) { mutex_lock(&fl->map_mutex); fastrpc_mmap_free(file, 0); mutex_unlock(&fl->map_mutex); } if (err) { if (!IS_ERR_OR_NULL(fl->init_mem)) { fastrpc_buf_free(fl->init_mem, 0); fl->init_mem = NULL; } } return err; } /* * This function makes a call to create a thread group in the static * process on the remote subsystem. * Example: audio daemon 'adsprpcd' on audioPD on ADSP */ static int fastrpc_init_create_static_process(struct fastrpc_file *fl, struct fastrpc_ioctl_init *init) { int err = 0, rh_hyp_done = 0; struct fastrpc_apps *me = &gfa; struct fastrpc_ioctl_invoke_async ioctl; struct smq_phy_page pages[1]; struct fastrpc_mmap *mem = NULL; char *proc_name = NULL; remote_arg_t ra[3]; uint64_t phys = 0; size_t size = 0; int fds[3]; struct secure_vm *rhvm = &me->channel[fl->cid].rhvm; struct { int pgid; unsigned int namelen; Loading @@ -2900,44 +2953,49 @@ static int fastrpc_init_process(struct fastrpc_file *fl, VERIFY(err, !IS_ERR_OR_NULL(proc_name)); if (err) goto bail; VERIFY(err, 0 == copy_from_user((void *)proc_name, (void __user *)init->file, init->filelen)); err = copy_from_user((void *)proc_name, (void __user *)init->file, init->filelen); if (err) goto bail; fl->pd = 1; inbuf.pgid = current->tgid; inbuf.pgid = fl->tgid; inbuf.namelen = init->filelen; inbuf.pageslen = 0; if (!strcmp(proc_name, "audiopd")) { fl->servloc_name = AUDIO_PDR_SERVICE_LOCATION_CLIENT_NAME; VERIFY(err, !fastrpc_mmap_remove_pdr(fl)); fl->servloc_name = AUDIO_PDR_SERVICE_LOCATION_CLIENT_NAME; /* * Remove any previous mappings in case process is trying * to reconnect after a PD restart on remote subsystem. */ err = fastrpc_mmap_remove_pdr(fl); if (err) goto bail; } if (!me->staticpd_flags && !(me->legacy_remote_heap)) { if (!me->staticpd_flags && !me->legacy_remote_heap) { inbuf.pageslen = 1; mutex_lock(&fl->map_mutex); err = fastrpc_mmap_create(fl, -1, 0, init->mem, init->memlen, ADSP_MMAP_REMOTE_HEAP_ADDR, &mem); init->memlen, ADSP_MMAP_REMOTE_HEAP_ADDR, &mem); mutex_unlock(&fl->map_mutex); if (err) goto bail; phys = mem->phys; size = mem->size; if (me->channel[fl->cid].rhvm.vmid) { err = hyp_assign_phys(phys, (uint64_t)size, hlosvm, 1, me->channel[fl->cid].rhvm.vmid, me->channel[fl->cid].rhvm.vmperm, me->channel[fl->cid].rhvm.vmcount); /* * If remote-heap VMIDs are defined in DTSI, then do * hyp_assign from HLOS to those VMs (LPASS, ADSP). */ if (rhvm->vmid) { err = hyp_assign_phys(phys, (uint64_t)size, hlosvm, 1, rhvm->vmid, rhvm->vmperm, rhvm->vmcount); if (err) { pr_err("adsprpc: %s: rh hyp assign failed with %d for phys 0x%llx, size %zd\n", __func__, err, phys, size); pr_err("adsprpc: %s: %s: rh hyp assign failed with %d for phys 0x%llx, size %zu\n", __func__, current->comm, err, phys, size); goto bail; } rh_hyp_done = 1; Loading @@ -2945,6 +3003,10 @@ static int fastrpc_init_process(struct fastrpc_file *fl, me->staticpd_flags = 1; } /* * Prepare remote arguments for static process create * call to remote subsystem. */ ra[0].buf.pv = (void *)&inbuf; ra[0].buf.len = sizeof(inbuf); fds[0] = -1; Loading @@ -2967,49 +3029,65 @@ static int fastrpc_init_process(struct fastrpc_file *fl, ioctl.attrs = NULL; ioctl.crc = NULL; ioctl.job = NULL; VERIFY(err, !(err = fastrpc_internal_invoke(fl, FASTRPC_MODE_PARALLEL, 1, &ioctl))); err = fastrpc_internal_invoke(fl, FASTRPC_MODE_PARALLEL, 1, &ioctl); if (err) goto bail; } else { err = -ENOTTY; goto bail; } fl->dsp_proc_init = 1; bail: kfree(proc_name); if (err && (init->flags == FASTRPC_INIT_CREATE_STATIC)) if (err) { me->staticpd_flags = 0; if (mem && err) { if (mem->flags == ADSP_MMAP_REMOTE_HEAP_ADDR && me->channel[fl->cid].rhvm.vmid && rh_hyp_done) { if (rh_hyp_done) { int hyp_err = 0; hyp_err = hyp_assign_phys(mem->phys, (uint64_t)mem->size, me->channel[fl->cid].rhvm.vmid, me->channel[fl->cid].rhvm.vmcount, /* Assign memory back to HLOS in case of errors */ hyp_err = hyp_assign_phys(phys, (uint64_t)size, rhvm->vmid, rhvm->vmcount, hlosvm, hlosvmperm, 1); if (hyp_err) pr_warn("adsprpc: %s: %s: rh hyp unassign failed with %d for phys 0x%llx of size %zd\n", pr_warn("adsprpc: %s: %s: rh hyp unassign failed with %d for phys 0x%llx of size %zu\n", __func__, current->comm, hyp_err, mem->phys, mem->size); hyp_err, phys, size); } mutex_lock(&fl->map_mutex); fastrpc_mmap_free(mem, 0); mutex_unlock(&fl->map_mutex); } if (err) { if (!IS_ERR_OR_NULL(fl->init_mem)) { fastrpc_buf_free(fl->init_mem, 0); fl->init_mem = NULL; } return err; } if (file) { mutex_lock(&fl->map_mutex); fastrpc_mmap_free(file, 0); mutex_unlock(&fl->map_mutex); static int fastrpc_init_process(struct fastrpc_file *fl, struct fastrpc_ioctl_init_attrs *uproc) { int err = 0; struct fastrpc_ioctl_init *init = &uproc->init; VERIFY(err, init->filelen < INIT_FILELEN_MAX && init->memlen < INIT_MEMLEN_MAX); if (err) goto bail; err = fastrpc_channel_open(fl); if (err) goto bail; switch (init->flags) { case FASTRPC_INIT_ATTACH: case FASTRPC_INIT_ATTACH_SENSORS: err = fastrpc_init_attach_process(fl, init); break; case FASTRPC_INIT_CREATE: err = fastrpc_init_create_dynamic_process(fl, uproc); break; case FASTRPC_INIT_CREATE_STATIC: err = fastrpc_init_create_static_process(fl, init); break; default: err = -ENOTTY; break; } if (err) goto bail; fl->dsp_proc_init = 1; bail: return err; } Loading Loading @@ -4882,35 +4960,44 @@ static int fastrpc_pdr_notifier_cb(struct notifier_block *pdrnb, return NOTIFY_DONE; } /* * The service locator callback function where the PDR notification * callback functions are registered. * (like audioPD on ADSP, sensorPD on SLPI/ADSP) */ static int fastrpc_get_service_location_notify(struct notifier_block *nb, unsigned long opcode, void *data) { struct fastrpc_static_pd *spd; struct pd_qmi_client_data *pdr = data; int curr_state = 0, i = 0; char *cb_pdname = NULL, *subsys = NULL; uint32_t instance_id = 0; spd = container_of(nb, struct fastrpc_static_pd, get_service_nb); subsys = gcinfo[spd->cid].subsys; if (opcode == LOCATOR_DOWN) { pr_warn("adsprpc: %s: PDR notifier locator for %s is down for %s\n", __func__, gcinfo[spd->cid].subsys, spd->servloc_name); __func__, subsys, spd->servloc_name); return NOTIFY_DONE; } for (i = 0; i < pdr->total_domains; i++) { if ((!strcmp(spd->servloc_name, AUDIO_PDR_SERVICE_LOCATION_CLIENT_NAME)) && (!strcmp(pdr->domain_list[i].name, ADSP_AUDIOPD_NAME))) { goto pdr_register; } else if ((!strcmp(spd->servloc_name, SENSORS_PDR_ADSP_SERVICE_LOCATION_CLIENT_NAME)) && (!strcmp(pdr->domain_list[i].name, ADSP_SENSORPD_NAME))) { goto pdr_register; } else if ((!strcmp(spd->servloc_name, SENSORS_PDR_SLPI_SERVICE_LOCATION_CLIENT_NAME)) && (!strcmp(pdr->domain_list[i].name, SLPI_SENSORPD_NAME))) { cb_pdname = pdr->domain_list[i].name; instance_id = pdr->domain_list[i].instance_id; /* Check the client and staticPD in the callback */ if (COMPARE_SERVICE_LOCATOR_NAMES(spd->servloc_name, AUDIO_PDR_SERVICE_LOCATION_CLIENT_NAME, cb_pdname, ADSP_AUDIOPD_NAME) || COMPARE_SERVICE_LOCATOR_NAMES(spd->servloc_name, SENSORS_PDR_ADSP_SERVICE_LOCATION_CLIENT_NAME, cb_pdname, ADSP_SENSORPD_NAME) || COMPARE_SERVICE_LOCATOR_NAMES(spd->servloc_name, SENSORS_PDR_SLPI_SERVICE_LOCATION_CLIENT_NAME, cb_pdname, SLPI_SENSORPD_NAME)) { goto pdr_register; } } Loading @@ -4918,35 +5005,28 @@ static int fastrpc_get_service_location_notify(struct notifier_block *nb, pdr_register: if (!spd->pdrhandle) { spd->pdrhandle = service_notif_register_notifier( pdr->domain_list[i].name, pdr->domain_list[i].instance_id, &spd->pdrnb, &curr_state); /* Register the PDR notifier callback function */ spd->pdrhandle = service_notif_register_notifier(cb_pdname, instance_id, &spd->pdrnb, &curr_state); if (IS_ERR_OR_NULL(spd->pdrhandle)) pr_warn("adsprpc: %s: PDR notifier for %s register failed for %s (%s) with err %ld\n", __func__, gcinfo[spd->cid].subsys, pdr->domain_list[i].name, spd->servloc_name, __func__, subsys, cb_pdname, spd->servloc_name, PTR_ERR(spd->pdrhandle)); else pr_info("adsprpc: %s: PDR notifier for %s registered for %s (%s)\n", __func__, gcinfo[spd->cid].subsys, pdr->domain_list[i].name, spd->servloc_name); __func__, subsys, cb_pdname, spd->servloc_name); } else { pr_warn("adsprpc: %s: %s (%s) notifier is already registered for %s\n", __func__, pdr->domain_list[i].name, spd->servloc_name, gcinfo[spd->cid].subsys); __func__, cb_pdname, spd->servloc_name, subsys); } if (curr_state == SERVREG_NOTIF_SERVICE_STATE_UP_V01) { pr_info("adsprpc: %s: %s (%s) PDR service for %s is up\n", __func__, spd->servloc_name, pdr->domain_list[i].name, gcinfo[spd->cid].subsys); __func__, spd->servloc_name, cb_pdname, subsys); spd->ispdup = 1; } else if (curr_state == SERVREG_NOTIF_SERVICE_STATE_UNINIT_V01) { pr_info("adsprpc: %s: %s (%s) PDR service for %s is uninitialized\n", __func__, spd->servloc_name, pdr->domain_list[i].name, gcinfo[spd->cid].subsys); __func__, spd->servloc_name, cb_pdname, subsys); } return NOTIFY_DONE; } Loading Loading @@ -5146,6 +5226,36 @@ static void configure_secure_channels(uint32_t secure_domains) } } /* * This function is used to create the service locator required for * registering for remote process restart (PDR) notifications if that * PDR property has been enabled in the fastrpc node on the DTSI. */ static int fastrpc_setup_service_locator(struct device *dev, const char *propname, char *client_name, char *service_name) { int err = 0, session = -1, cid = -1; struct fastrpc_apps *me = &gfa; if (of_property_read_bool(dev->of_node, propname)) { err = fastrpc_get_spd_session(client_name, &session, &cid); if (err) goto bail; /* Register the service locator's callback function */ me->channel[cid].spd[session].get_service_nb.notifier_call = fastrpc_get_service_location_notify; err = get_service_location(client_name, service_name, &me->channel[cid].spd[session].get_service_nb); if (err) pr_warn("adsprpc: %s: get service location failed with %d for %s (%s)\n", __func__, err, service_name, client_name); else pr_info("adsprpc: %s: service location enabled for %s (%s)\n", __func__, service_name, client_name); } bail: return err; } static int fastrpc_probe(struct platform_device *pdev) { Loading @@ -5153,8 +5263,7 @@ static int fastrpc_probe(struct platform_device *pdev) struct fastrpc_apps *me = &gfa; struct device *dev = &pdev->dev; int ret = 0; uint32_t secure_domains; int session = -1, cid = -1; uint32_t secure_domains = 0; if (of_device_is_compatible(dev->of_node, "qcom,msm-fastrpc-compute")) { Loading Loading @@ -5192,70 +5301,17 @@ static int fastrpc_probe(struct platform_device *pdev) } me->legacy_remote_heap = of_property_read_bool(dev->of_node, "qcom,fastrpc-legacy-remote-heap"); if (of_property_read_bool(dev->of_node, "qcom,fastrpc-adsp-audio-pdr")) { err = fastrpc_get_spd_session( AUDIO_PDR_SERVICE_LOCATION_CLIENT_NAME, &session, &cid); if (err) goto spdbail; me->channel[cid].spd[session].get_service_nb.notifier_call = fastrpc_get_service_location_notify; ret = get_service_location( fastrpc_setup_service_locator(dev, AUDIO_PDR_ADSP_DTSI_PROPERTY_NAME, AUDIO_PDR_SERVICE_LOCATION_CLIENT_NAME, AUDIO_PDR_ADSP_SERVICE_NAME, &me->channel[cid].spd[session].get_service_nb); if (ret) pr_warn("adsprpc: %s: get service location failed with %d for %s (%s)\n", __func__, ret, AUDIO_PDR_ADSP_SERVICE_NAME, AUDIO_PDR_SERVICE_LOCATION_CLIENT_NAME); else pr_info("adsprpc: %s: service location enabled for %s (%s)\n", __func__, AUDIO_PDR_ADSP_SERVICE_NAME, AUDIO_PDR_SERVICE_LOCATION_CLIENT_NAME); } if (of_property_read_bool(dev->of_node, "qcom,fastrpc-adsp-sensors-pdr")) { err = fastrpc_get_spd_session( SENSORS_PDR_ADSP_SERVICE_LOCATION_CLIENT_NAME, &session, &cid); if (err) goto spdbail; me->channel[cid].spd[session].get_service_nb.notifier_call = fastrpc_get_service_location_notify; ret = get_service_location( AUDIO_PDR_ADSP_SERVICE_NAME); fastrpc_setup_service_locator(dev, SENSORS_PDR_ADSP_DTSI_PROPERTY_NAME, SENSORS_PDR_ADSP_SERVICE_LOCATION_CLIENT_NAME, SENSORS_PDR_ADSP_SERVICE_NAME, &me->channel[cid].spd[session].get_service_nb); if (ret) pr_warn("adsprpc: %s: get service location failed with %d for %s (%s)\n", __func__, ret, SENSORS_PDR_SLPI_SERVICE_NAME, SENSORS_PDR_ADSP_SERVICE_LOCATION_CLIENT_NAME); else pr_info("adsprpc: %s: service location enabled for %s (%s)\n", __func__, SENSORS_PDR_SLPI_SERVICE_NAME, SENSORS_PDR_ADSP_SERVICE_LOCATION_CLIENT_NAME); } if (of_property_read_bool(dev->of_node, "qcom,fastrpc-slpi-sensors-pdr")) { err = fastrpc_get_spd_session( SENSORS_PDR_SLPI_SERVICE_LOCATION_CLIENT_NAME, &session, &cid); if (err) goto spdbail; me->channel[cid].spd[session].get_service_nb.notifier_call = fastrpc_get_service_location_notify; ret = get_service_location( SENSORS_PDR_ADSP_SERVICE_NAME); fastrpc_setup_service_locator(dev, SENSORS_PDR_SLPI_DTSI_PROPERTY_NAME, SENSORS_PDR_SLPI_SERVICE_LOCATION_CLIENT_NAME, SENSORS_PDR_SLPI_SERVICE_NAME, &me->channel[cid].spd[session].get_service_nb); if (ret) pr_warn("adsprpc: %s: get service location failed with %d for %s (%s)\n", __func__, ret, SENSORS_PDR_SLPI_SERVICE_NAME, SENSORS_PDR_SLPI_SERVICE_LOCATION_CLIENT_NAME); else pr_info("adsprpc: %s: service location enabled for %s (%s)\n", __func__, SENSORS_PDR_SLPI_SERVICE_NAME, SENSORS_PDR_SLPI_SERVICE_LOCATION_CLIENT_NAME); } spdbail: SENSORS_PDR_SLPI_SERVICE_NAME); err = of_platform_populate(pdev->dev.of_node, fastrpc_match_table, NULL, &pdev->dev); Loading Loading
drivers/char/adsprpc.c +379 −323 Original line number Diff line number Diff line Loading @@ -65,14 +65,17 @@ #define UL_SIZE 25 #define PID_SIZE 10 #define AUDIO_PDR_ADSP_DTSI_PROPERTY_NAME "qcom,fastrpc-adsp-audio-pdr" #define AUDIO_PDR_SERVICE_LOCATION_CLIENT_NAME "audio_pdr_adsprpc" #define AUDIO_PDR_ADSP_SERVICE_NAME "avs/audio" #define ADSP_AUDIOPD_NAME "msm/adsp/audio_pd" #define SENSORS_PDR_ADSP_DTSI_PROPERTY_NAME "qcom,fastrpc-adsp-sensors-pdr" #define SENSORS_PDR_ADSP_SERVICE_LOCATION_CLIENT_NAME "sensors_pdr_adsprpc" #define SENSORS_PDR_ADSP_SERVICE_NAME "tms/servreg" #define ADSP_SENSORPD_NAME "msm/adsp/sensor_pd" #define SENSORS_PDR_SLPI_DTSI_PROPERTY_NAME "qcom,fastrpc-slpi-sensors-pdr" #define SENSORS_PDR_SLPI_SERVICE_LOCATION_CLIENT_NAME "sensors_pdr_sdsprpc" #define SENSORS_PDR_SLPI_SERVICE_NAME SENSORS_PDR_ADSP_SERVICE_NAME #define SLPI_SENSORPD_NAME "msm/slpi/sensor_pd" Loading Loading @@ -200,6 +203,12 @@ (int64_t *)(perf_ptr + offset)\ : (int64_t *)NULL) : (int64_t *)NULL) /* Macro for comparing local client and PD names with those from callback */ #define COMPARE_SERVICE_LOCATOR_NAMES(cb_client, local_client, \ cb_pdname, local_pdname) \ ((!strcmp(cb_client, local_client)) \ && (!strcmp(cb_pdname, local_pdname))) #define IS_ASYNC_FASTRPC_AVAILABLE (1) static int fastrpc_pdr_notifier_cb(struct notifier_block *nb, Loading Loading @@ -2706,29 +2715,24 @@ static int fastrpc_mmap_remove_pdr(struct fastrpc_file *fl); static int fastrpc_channel_open(struct fastrpc_file *fl); static int fastrpc_mmap_remove_ssr(struct fastrpc_file *fl); static void fastrpc_check_privileged_process(struct fastrpc_file *fl, struct fastrpc_ioctl_init_attrs *uproc) { unsigned int gid = sorted_lists_intersection(fl->gidlist.gids, fl->gidlist.gidcount, gfa.gidlist.gids, gfa.gidlist.gidcount); /* disregard any privilege bits from userspace */ uproc->attrs &= (~FASTRPC_MODE_PRIVILEGED); if (gid) { pr_info("adsprpc: %s: %s (PID %d, GID %u) is a privileged process\n", __func__, current->comm, fl->tgid, gid); uproc->attrs |= FASTRPC_MODE_PRIVILEGED; } } /* * This function makes a call to create a thread group in the root * process or static process on the remote subsystem. * Examples: * - guestOS daemons on all DSPs * - sensors daemon on sensorsPD on SLPI/ADSP */ static int fastrpc_init_attach_process(struct fastrpc_file *fl, struct fastrpc_ioctl_init *init) { int err = 0; int err = 0, tgid = fl->tgid; remote_arg_t ra[1]; struct fastrpc_ioctl_invoke_async ioctl; int tgid = fl->tgid; /* * Prepare remote arguments for creating thread group * in guestOS/staticPD on the remote subsystem. */ ra[0].buf.pv = (void *)&tgid; ra[0].buf.len = sizeof(tgid); ioctl.inv.handle = FASTRPC_STATIC_HANDLE_PROCESS_GROUP; Loading @@ -2738,6 +2742,7 @@ static int fastrpc_init_attach_process(struct fastrpc_file *fl, ioctl.attrs = NULL; ioctl.crc = NULL; ioctl.job = NULL; if (init->flags == FASTRPC_INIT_ATTACH) fl->pd = 0; else if (init->flags == FASTRPC_INIT_ATTACH_SENSORS) { Loading @@ -2747,50 +2752,35 @@ static int fastrpc_init_attach_process(struct fastrpc_file *fl, else if (fl->cid == SDSP_DOMAIN_ID) fl->servloc_name = SENSORS_PDR_SLPI_SERVICE_LOCATION_CLIENT_NAME; /* Setting to 2 will route the message to sensorsPD */ fl->pd = 2; } VERIFY(err, !(err = fastrpc_internal_invoke(fl, FASTRPC_MODE_PARALLEL, 1, &ioctl))); err = fastrpc_internal_invoke(fl, FASTRPC_MODE_PARALLEL, 1, &ioctl); if (err) goto bail; bail: return err; } static int fastrpc_init_process(struct fastrpc_file *fl, /* * This function makes a call to spawn a dynamic process * on the remote subsystem. * Example: all compute offloads to CDSP */ static int fastrpc_init_create_dynamic_process(struct fastrpc_file *fl, struct fastrpc_ioctl_init_attrs *uproc) { int err = 0, rh_hyp_done = 0; struct fastrpc_apps *me = &gfa; int err = 0, memlen = 0, mflags = 0; struct fastrpc_ioctl_invoke_async ioctl; struct fastrpc_ioctl_init *init = &uproc->init; struct smq_phy_page pages[1]; struct fastrpc_mmap *file = NULL, *mem = NULL; struct fastrpc_mmap *file = NULL; struct fastrpc_buf *imem = NULL; unsigned long imem_dma_attr = 0; char *proc_name = NULL; VERIFY(err, init->filelen >= 0 && init->filelen < INIT_FILELEN_MAX); if (err) goto bail; VERIFY(err, init->memlen >= 0 && init->memlen < INIT_MEMLEN_MAX); if (err) goto bail; VERIFY(err, 0 == (err = fastrpc_channel_open(fl))); if (err) goto bail; if (init->flags == FASTRPC_INIT_ATTACH || init->flags == FASTRPC_INIT_ATTACH_SENSORS) { VERIFY(err, !(err = fastrpc_init_attach_process(fl, init))); if (err) goto bail; } else if (init->flags == FASTRPC_INIT_CREATE) { int memlen; remote_arg_t ra[6]; int fds[6]; int mflags = 0; unsigned int gid = 0, one_mb = 1024*1024; struct { int pgid; unsigned int namelen; Loading @@ -2805,22 +2795,41 @@ static int fastrpc_init_process(struct fastrpc_file *fl, inbuf.filelen = init->filelen; fl->pd = 1; VERIFY(err, access_ok((void __user *)init->file, init->filelen)); /* Check if file memory passed by userspace is valid */ VERIFY(err, access_ok((void __user *)init->file, init->filelen)); if (err) goto bail; if (init->filelen) { /* Map the shell file buffer to remote subsystem */ mutex_lock(&fl->map_mutex); VERIFY(err, !fastrpc_mmap_create(fl, init->filefd, 0, init->file, init->filelen, mflags, &file)); err = fastrpc_mmap_create(fl, init->filefd, 0, init->file, init->filelen, mflags, &file); mutex_unlock(&fl->map_mutex); if (err) goto bail; } inbuf.pageslen = 1; fastrpc_check_privileged_process(fl, uproc); /* Disregard any privilege bits from userspace */ uproc->attrs &= (~FASTRPC_MODE_PRIVILEGED); /* * Check if the primary or supplementary group(s) of the process is * one of the 'privileged' fastrpc GIDs stored in the device-tree. */ gid = sorted_lists_intersection(fl->gidlist.gids, fl->gidlist.gidcount, gfa.gidlist.gids, gfa.gidlist.gidcount); if (gid) { pr_info("adsprpc: %s: %s (PID %d, GID %u) is a privileged process\n", __func__, current->comm, fl->tgid, gid); uproc->attrs |= FASTRPC_MODE_PRIVILEGED; } /* * Userspace client should try to allocate the initial memory donated * to remote subsystem as only the kernel and DSP should have access * to that memory. */ VERIFY(err, !init->mem); if (err) { err = -EINVAL; Loading @@ -2828,18 +2837,24 @@ static int fastrpc_init_process(struct fastrpc_file *fl, current->comm, __func__); goto bail; } memlen = ALIGN(max(1024*1024*3, (int)init->filelen * 4), 1024*1024); /* Free any previous donated memory */ if (fl->init_mem) fastrpc_buf_free(fl->init_mem, 0); /* Allocate DMA buffer in kernel for donating to remote process */ memlen = ALIGN(max(3*one_mb, init->filelen * 4), one_mb); imem_dma_attr = DMA_ATTR_EXEC_MAPPING | DMA_ATTR_DELAYED_UNMAP | DMA_ATTR_NO_KERNEL_MAPPING; err = fastrpc_buf_alloc(fl, memlen, imem_dma_attr, 0, 0, &imem); if (err) goto bail; if (fl->init_mem) fastrpc_buf_free(fl->init_mem, 0); fl->init_mem = imem; /* * Prepare remote arguments for dynamic process create * call to remote subsystem. */ inbuf.pageslen = 1; ra[0].buf.pv = (void *)&inbuf; ra[0].buf.len = sizeof(inbuf); Loading Loading @@ -2870,6 +2885,11 @@ static int fastrpc_init_process(struct fastrpc_file *fl, fds[5] = -1; ioctl.inv.handle = FASTRPC_STATIC_HANDLE_PROCESS_GROUP; /* * Choose appropriate remote method ID depending on whether the * HLOS process has any attributes enabled (like unsignedPD, * critical process, adaptive QoS, CRC checks etc). */ ioctl.inv.sc = REMOTE_SCALARS_MAKE(6, 4, 0); if (uproc->attrs) ioctl.inv.sc = REMOTE_SCALARS_MAKE(7, 6, 0); Loading @@ -2878,15 +2898,48 @@ static int fastrpc_init_process(struct fastrpc_file *fl, ioctl.attrs = NULL; ioctl.crc = NULL; ioctl.job = NULL; VERIFY(err, !(err = fastrpc_internal_invoke(fl, FASTRPC_MODE_PARALLEL, 1, &ioctl))); err = fastrpc_internal_invoke(fl, FASTRPC_MODE_PARALLEL, 1, &ioctl); if (err) goto bail; } else if (init->flags == FASTRPC_INIT_CREATE_STATIC) { bail: /* * Shell is loaded into the donated memory on remote subsystem. So, the * original file buffer can be DMA unmapped. In case of a failure also, * the mapping needs to be removed. */ if (file) { mutex_lock(&fl->map_mutex); fastrpc_mmap_free(file, 0); mutex_unlock(&fl->map_mutex); } if (err) { if (!IS_ERR_OR_NULL(fl->init_mem)) { fastrpc_buf_free(fl->init_mem, 0); fl->init_mem = NULL; } } return err; } /* * This function makes a call to create a thread group in the static * process on the remote subsystem. * Example: audio daemon 'adsprpcd' on audioPD on ADSP */ static int fastrpc_init_create_static_process(struct fastrpc_file *fl, struct fastrpc_ioctl_init *init) { int err = 0, rh_hyp_done = 0; struct fastrpc_apps *me = &gfa; struct fastrpc_ioctl_invoke_async ioctl; struct smq_phy_page pages[1]; struct fastrpc_mmap *mem = NULL; char *proc_name = NULL; remote_arg_t ra[3]; uint64_t phys = 0; size_t size = 0; int fds[3]; struct secure_vm *rhvm = &me->channel[fl->cid].rhvm; struct { int pgid; unsigned int namelen; Loading @@ -2900,44 +2953,49 @@ static int fastrpc_init_process(struct fastrpc_file *fl, VERIFY(err, !IS_ERR_OR_NULL(proc_name)); if (err) goto bail; VERIFY(err, 0 == copy_from_user((void *)proc_name, (void __user *)init->file, init->filelen)); err = copy_from_user((void *)proc_name, (void __user *)init->file, init->filelen); if (err) goto bail; fl->pd = 1; inbuf.pgid = current->tgid; inbuf.pgid = fl->tgid; inbuf.namelen = init->filelen; inbuf.pageslen = 0; if (!strcmp(proc_name, "audiopd")) { fl->servloc_name = AUDIO_PDR_SERVICE_LOCATION_CLIENT_NAME; VERIFY(err, !fastrpc_mmap_remove_pdr(fl)); fl->servloc_name = AUDIO_PDR_SERVICE_LOCATION_CLIENT_NAME; /* * Remove any previous mappings in case process is trying * to reconnect after a PD restart on remote subsystem. */ err = fastrpc_mmap_remove_pdr(fl); if (err) goto bail; } if (!me->staticpd_flags && !(me->legacy_remote_heap)) { if (!me->staticpd_flags && !me->legacy_remote_heap) { inbuf.pageslen = 1; mutex_lock(&fl->map_mutex); err = fastrpc_mmap_create(fl, -1, 0, init->mem, init->memlen, ADSP_MMAP_REMOTE_HEAP_ADDR, &mem); init->memlen, ADSP_MMAP_REMOTE_HEAP_ADDR, &mem); mutex_unlock(&fl->map_mutex); if (err) goto bail; phys = mem->phys; size = mem->size; if (me->channel[fl->cid].rhvm.vmid) { err = hyp_assign_phys(phys, (uint64_t)size, hlosvm, 1, me->channel[fl->cid].rhvm.vmid, me->channel[fl->cid].rhvm.vmperm, me->channel[fl->cid].rhvm.vmcount); /* * If remote-heap VMIDs are defined in DTSI, then do * hyp_assign from HLOS to those VMs (LPASS, ADSP). */ if (rhvm->vmid) { err = hyp_assign_phys(phys, (uint64_t)size, hlosvm, 1, rhvm->vmid, rhvm->vmperm, rhvm->vmcount); if (err) { pr_err("adsprpc: %s: rh hyp assign failed with %d for phys 0x%llx, size %zd\n", __func__, err, phys, size); pr_err("adsprpc: %s: %s: rh hyp assign failed with %d for phys 0x%llx, size %zu\n", __func__, current->comm, err, phys, size); goto bail; } rh_hyp_done = 1; Loading @@ -2945,6 +3003,10 @@ static int fastrpc_init_process(struct fastrpc_file *fl, me->staticpd_flags = 1; } /* * Prepare remote arguments for static process create * call to remote subsystem. */ ra[0].buf.pv = (void *)&inbuf; ra[0].buf.len = sizeof(inbuf); fds[0] = -1; Loading @@ -2967,49 +3029,65 @@ static int fastrpc_init_process(struct fastrpc_file *fl, ioctl.attrs = NULL; ioctl.crc = NULL; ioctl.job = NULL; VERIFY(err, !(err = fastrpc_internal_invoke(fl, FASTRPC_MODE_PARALLEL, 1, &ioctl))); err = fastrpc_internal_invoke(fl, FASTRPC_MODE_PARALLEL, 1, &ioctl); if (err) goto bail; } else { err = -ENOTTY; goto bail; } fl->dsp_proc_init = 1; bail: kfree(proc_name); if (err && (init->flags == FASTRPC_INIT_CREATE_STATIC)) if (err) { me->staticpd_flags = 0; if (mem && err) { if (mem->flags == ADSP_MMAP_REMOTE_HEAP_ADDR && me->channel[fl->cid].rhvm.vmid && rh_hyp_done) { if (rh_hyp_done) { int hyp_err = 0; hyp_err = hyp_assign_phys(mem->phys, (uint64_t)mem->size, me->channel[fl->cid].rhvm.vmid, me->channel[fl->cid].rhvm.vmcount, /* Assign memory back to HLOS in case of errors */ hyp_err = hyp_assign_phys(phys, (uint64_t)size, rhvm->vmid, rhvm->vmcount, hlosvm, hlosvmperm, 1); if (hyp_err) pr_warn("adsprpc: %s: %s: rh hyp unassign failed with %d for phys 0x%llx of size %zd\n", pr_warn("adsprpc: %s: %s: rh hyp unassign failed with %d for phys 0x%llx of size %zu\n", __func__, current->comm, hyp_err, mem->phys, mem->size); hyp_err, phys, size); } mutex_lock(&fl->map_mutex); fastrpc_mmap_free(mem, 0); mutex_unlock(&fl->map_mutex); } if (err) { if (!IS_ERR_OR_NULL(fl->init_mem)) { fastrpc_buf_free(fl->init_mem, 0); fl->init_mem = NULL; } return err; } if (file) { mutex_lock(&fl->map_mutex); fastrpc_mmap_free(file, 0); mutex_unlock(&fl->map_mutex); static int fastrpc_init_process(struct fastrpc_file *fl, struct fastrpc_ioctl_init_attrs *uproc) { int err = 0; struct fastrpc_ioctl_init *init = &uproc->init; VERIFY(err, init->filelen < INIT_FILELEN_MAX && init->memlen < INIT_MEMLEN_MAX); if (err) goto bail; err = fastrpc_channel_open(fl); if (err) goto bail; switch (init->flags) { case FASTRPC_INIT_ATTACH: case FASTRPC_INIT_ATTACH_SENSORS: err = fastrpc_init_attach_process(fl, init); break; case FASTRPC_INIT_CREATE: err = fastrpc_init_create_dynamic_process(fl, uproc); break; case FASTRPC_INIT_CREATE_STATIC: err = fastrpc_init_create_static_process(fl, init); break; default: err = -ENOTTY; break; } if (err) goto bail; fl->dsp_proc_init = 1; bail: return err; } Loading Loading @@ -4882,35 +4960,44 @@ static int fastrpc_pdr_notifier_cb(struct notifier_block *pdrnb, return NOTIFY_DONE; } /* * The service locator callback function where the PDR notification * callback functions are registered. * (like audioPD on ADSP, sensorPD on SLPI/ADSP) */ static int fastrpc_get_service_location_notify(struct notifier_block *nb, unsigned long opcode, void *data) { struct fastrpc_static_pd *spd; struct pd_qmi_client_data *pdr = data; int curr_state = 0, i = 0; char *cb_pdname = NULL, *subsys = NULL; uint32_t instance_id = 0; spd = container_of(nb, struct fastrpc_static_pd, get_service_nb); subsys = gcinfo[spd->cid].subsys; if (opcode == LOCATOR_DOWN) { pr_warn("adsprpc: %s: PDR notifier locator for %s is down for %s\n", __func__, gcinfo[spd->cid].subsys, spd->servloc_name); __func__, subsys, spd->servloc_name); return NOTIFY_DONE; } for (i = 0; i < pdr->total_domains; i++) { if ((!strcmp(spd->servloc_name, AUDIO_PDR_SERVICE_LOCATION_CLIENT_NAME)) && (!strcmp(pdr->domain_list[i].name, ADSP_AUDIOPD_NAME))) { goto pdr_register; } else if ((!strcmp(spd->servloc_name, SENSORS_PDR_ADSP_SERVICE_LOCATION_CLIENT_NAME)) && (!strcmp(pdr->domain_list[i].name, ADSP_SENSORPD_NAME))) { goto pdr_register; } else if ((!strcmp(spd->servloc_name, SENSORS_PDR_SLPI_SERVICE_LOCATION_CLIENT_NAME)) && (!strcmp(pdr->domain_list[i].name, SLPI_SENSORPD_NAME))) { cb_pdname = pdr->domain_list[i].name; instance_id = pdr->domain_list[i].instance_id; /* Check the client and staticPD in the callback */ if (COMPARE_SERVICE_LOCATOR_NAMES(spd->servloc_name, AUDIO_PDR_SERVICE_LOCATION_CLIENT_NAME, cb_pdname, ADSP_AUDIOPD_NAME) || COMPARE_SERVICE_LOCATOR_NAMES(spd->servloc_name, SENSORS_PDR_ADSP_SERVICE_LOCATION_CLIENT_NAME, cb_pdname, ADSP_SENSORPD_NAME) || COMPARE_SERVICE_LOCATOR_NAMES(spd->servloc_name, SENSORS_PDR_SLPI_SERVICE_LOCATION_CLIENT_NAME, cb_pdname, SLPI_SENSORPD_NAME)) { goto pdr_register; } } Loading @@ -4918,35 +5005,28 @@ static int fastrpc_get_service_location_notify(struct notifier_block *nb, pdr_register: if (!spd->pdrhandle) { spd->pdrhandle = service_notif_register_notifier( pdr->domain_list[i].name, pdr->domain_list[i].instance_id, &spd->pdrnb, &curr_state); /* Register the PDR notifier callback function */ spd->pdrhandle = service_notif_register_notifier(cb_pdname, instance_id, &spd->pdrnb, &curr_state); if (IS_ERR_OR_NULL(spd->pdrhandle)) pr_warn("adsprpc: %s: PDR notifier for %s register failed for %s (%s) with err %ld\n", __func__, gcinfo[spd->cid].subsys, pdr->domain_list[i].name, spd->servloc_name, __func__, subsys, cb_pdname, spd->servloc_name, PTR_ERR(spd->pdrhandle)); else pr_info("adsprpc: %s: PDR notifier for %s registered for %s (%s)\n", __func__, gcinfo[spd->cid].subsys, pdr->domain_list[i].name, spd->servloc_name); __func__, subsys, cb_pdname, spd->servloc_name); } else { pr_warn("adsprpc: %s: %s (%s) notifier is already registered for %s\n", __func__, pdr->domain_list[i].name, spd->servloc_name, gcinfo[spd->cid].subsys); __func__, cb_pdname, spd->servloc_name, subsys); } if (curr_state == SERVREG_NOTIF_SERVICE_STATE_UP_V01) { pr_info("adsprpc: %s: %s (%s) PDR service for %s is up\n", __func__, spd->servloc_name, pdr->domain_list[i].name, gcinfo[spd->cid].subsys); __func__, spd->servloc_name, cb_pdname, subsys); spd->ispdup = 1; } else if (curr_state == SERVREG_NOTIF_SERVICE_STATE_UNINIT_V01) { pr_info("adsprpc: %s: %s (%s) PDR service for %s is uninitialized\n", __func__, spd->servloc_name, pdr->domain_list[i].name, gcinfo[spd->cid].subsys); __func__, spd->servloc_name, cb_pdname, subsys); } return NOTIFY_DONE; } Loading Loading @@ -5146,6 +5226,36 @@ static void configure_secure_channels(uint32_t secure_domains) } } /* * This function is used to create the service locator required for * registering for remote process restart (PDR) notifications if that * PDR property has been enabled in the fastrpc node on the DTSI. */ static int fastrpc_setup_service_locator(struct device *dev, const char *propname, char *client_name, char *service_name) { int err = 0, session = -1, cid = -1; struct fastrpc_apps *me = &gfa; if (of_property_read_bool(dev->of_node, propname)) { err = fastrpc_get_spd_session(client_name, &session, &cid); if (err) goto bail; /* Register the service locator's callback function */ me->channel[cid].spd[session].get_service_nb.notifier_call = fastrpc_get_service_location_notify; err = get_service_location(client_name, service_name, &me->channel[cid].spd[session].get_service_nb); if (err) pr_warn("adsprpc: %s: get service location failed with %d for %s (%s)\n", __func__, err, service_name, client_name); else pr_info("adsprpc: %s: service location enabled for %s (%s)\n", __func__, service_name, client_name); } bail: return err; } static int fastrpc_probe(struct platform_device *pdev) { Loading @@ -5153,8 +5263,7 @@ static int fastrpc_probe(struct platform_device *pdev) struct fastrpc_apps *me = &gfa; struct device *dev = &pdev->dev; int ret = 0; uint32_t secure_domains; int session = -1, cid = -1; uint32_t secure_domains = 0; if (of_device_is_compatible(dev->of_node, "qcom,msm-fastrpc-compute")) { Loading Loading @@ -5192,70 +5301,17 @@ static int fastrpc_probe(struct platform_device *pdev) } me->legacy_remote_heap = of_property_read_bool(dev->of_node, "qcom,fastrpc-legacy-remote-heap"); if (of_property_read_bool(dev->of_node, "qcom,fastrpc-adsp-audio-pdr")) { err = fastrpc_get_spd_session( AUDIO_PDR_SERVICE_LOCATION_CLIENT_NAME, &session, &cid); if (err) goto spdbail; me->channel[cid].spd[session].get_service_nb.notifier_call = fastrpc_get_service_location_notify; ret = get_service_location( fastrpc_setup_service_locator(dev, AUDIO_PDR_ADSP_DTSI_PROPERTY_NAME, AUDIO_PDR_SERVICE_LOCATION_CLIENT_NAME, AUDIO_PDR_ADSP_SERVICE_NAME, &me->channel[cid].spd[session].get_service_nb); if (ret) pr_warn("adsprpc: %s: get service location failed with %d for %s (%s)\n", __func__, ret, AUDIO_PDR_ADSP_SERVICE_NAME, AUDIO_PDR_SERVICE_LOCATION_CLIENT_NAME); else pr_info("adsprpc: %s: service location enabled for %s (%s)\n", __func__, AUDIO_PDR_ADSP_SERVICE_NAME, AUDIO_PDR_SERVICE_LOCATION_CLIENT_NAME); } if (of_property_read_bool(dev->of_node, "qcom,fastrpc-adsp-sensors-pdr")) { err = fastrpc_get_spd_session( SENSORS_PDR_ADSP_SERVICE_LOCATION_CLIENT_NAME, &session, &cid); if (err) goto spdbail; me->channel[cid].spd[session].get_service_nb.notifier_call = fastrpc_get_service_location_notify; ret = get_service_location( AUDIO_PDR_ADSP_SERVICE_NAME); fastrpc_setup_service_locator(dev, SENSORS_PDR_ADSP_DTSI_PROPERTY_NAME, SENSORS_PDR_ADSP_SERVICE_LOCATION_CLIENT_NAME, SENSORS_PDR_ADSP_SERVICE_NAME, &me->channel[cid].spd[session].get_service_nb); if (ret) pr_warn("adsprpc: %s: get service location failed with %d for %s (%s)\n", __func__, ret, SENSORS_PDR_SLPI_SERVICE_NAME, SENSORS_PDR_ADSP_SERVICE_LOCATION_CLIENT_NAME); else pr_info("adsprpc: %s: service location enabled for %s (%s)\n", __func__, SENSORS_PDR_SLPI_SERVICE_NAME, SENSORS_PDR_ADSP_SERVICE_LOCATION_CLIENT_NAME); } if (of_property_read_bool(dev->of_node, "qcom,fastrpc-slpi-sensors-pdr")) { err = fastrpc_get_spd_session( SENSORS_PDR_SLPI_SERVICE_LOCATION_CLIENT_NAME, &session, &cid); if (err) goto spdbail; me->channel[cid].spd[session].get_service_nb.notifier_call = fastrpc_get_service_location_notify; ret = get_service_location( SENSORS_PDR_ADSP_SERVICE_NAME); fastrpc_setup_service_locator(dev, SENSORS_PDR_SLPI_DTSI_PROPERTY_NAME, SENSORS_PDR_SLPI_SERVICE_LOCATION_CLIENT_NAME, SENSORS_PDR_SLPI_SERVICE_NAME, &me->channel[cid].spd[session].get_service_nb); if (ret) pr_warn("adsprpc: %s: get service location failed with %d for %s (%s)\n", __func__, ret, SENSORS_PDR_SLPI_SERVICE_NAME, SENSORS_PDR_SLPI_SERVICE_LOCATION_CLIENT_NAME); else pr_info("adsprpc: %s: service location enabled for %s (%s)\n", __func__, SENSORS_PDR_SLPI_SERVICE_NAME, SENSORS_PDR_SLPI_SERVICE_LOCATION_CLIENT_NAME); } spdbail: SENSORS_PDR_SLPI_SERVICE_NAME); err = of_platform_populate(pdev->dev.of_node, fastrpc_match_table, NULL, &pdev->dev); Loading