Merge "msm: adsprpc: split init process function into smaller methods"

This commit is contained in:
qctecmdr 2020-04-25 12:11:03 -07:00 • committed by Gerrit - the friendly Code Review server
commit e323b2a635

View file

@ -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"
@ -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,
@ -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;
@ -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) {
@ -2747,256 +2752,164 @@ 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;
remote_arg_t ra[6];
int fds[6];
unsigned int gid = 0, one_mb = 1024*1024;
struct {
int pgid;
unsigned int namelen;
unsigned int filelen;
unsigned int pageslen;
int attrs;
int siglen;
} inbuf;
VERIFY(err, init->filelen >= 0 &&
init->filelen < INIT_FILELEN_MAX);
inbuf.pgid = fl->tgid;
inbuf.namelen = strlen(current->comm) + 1;
inbuf.filelen = init->filelen;
fl->pd = 1;
/* Check if file memory passed by userspace is valid */
VERIFY(err, access_ok((void __user *)init->file, init->filelen));
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 (init->filelen) {
/* Map the shell file buffer to remote subsystem */
mutex_lock(&fl->map_mutex);
err = fastrpc_mmap_create(fl, init->filefd, 0,
init->file, init->filelen, mflags, &file);
mutex_unlock(&fl->map_mutex);
if (err)
goto bail;
} else if (init->flags == FASTRPC_INIT_CREATE) {
int memlen;
}
inbuf.pageslen = 1;
remote_arg_t ra[6];
int fds[6];
int mflags = 0;
struct {
int pgid;
unsigned int namelen;
unsigned int filelen;
unsigned int pageslen;
int attrs;
int siglen;
} inbuf;
/* Disregard any privilege bits from userspace */
uproc->attrs &= (~FASTRPC_MODE_PRIVILEGED);
inbuf.pgid = fl->tgid;
inbuf.namelen = strlen(current->comm) + 1;
inbuf.filelen = init->filelen;
fl->pd = 1;
/*
* 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;
}
VERIFY(err, access_ok((void __user *)init->file,
init->filelen));
if (err)
goto bail;
if (init->filelen) {
mutex_lock(&fl->map_mutex);
VERIFY(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);
VERIFY(err, !init->mem);
if (err) {
err = -EINVAL;
pr_err("adsprpc: %s: %s: ERROR: donated memory allocated in userspace\n",
current->comm, __func__);
goto bail;
}
memlen = ALIGN(max(1024*1024*3, (int)init->filelen * 4),
1024*1024);
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;
inbuf.pageslen = 1;
ra[0].buf.pv = (void *)&inbuf;
ra[0].buf.len = sizeof(inbuf);
fds[0] = -1;
ra[1].buf.pv = (void *)current->comm;
ra[1].buf.len = inbuf.namelen;
fds[1] = -1;
ra[2].buf.pv = (void *)init->file;
ra[2].buf.len = inbuf.filelen;
fds[2] = init->filefd;
pages[0].addr = imem->phys;
pages[0].size = imem->size;
ra[3].buf.pv = (void *)pages;
ra[3].buf.len = 1 * sizeof(*pages);
fds[3] = -1;
inbuf.attrs = uproc->attrs;
ra[4].buf.pv = (void *)&(inbuf.attrs);
ra[4].buf.len = sizeof(inbuf.attrs);
fds[4] = -1;
inbuf.siglen = uproc->siglen;
ra[5].buf.pv = (void *)&(inbuf.siglen);
ra[5].buf.len = sizeof(inbuf.siglen);
fds[5] = -1;
ioctl.inv.handle = FASTRPC_STATIC_HANDLE_PROCESS_GROUP;
ioctl.inv.sc = REMOTE_SCALARS_MAKE(6, 4, 0);
if (uproc->attrs)
ioctl.inv.sc = REMOTE_SCALARS_MAKE(7, 6, 0);
ioctl.inv.pra = ra;
ioctl.fds = fds;
ioctl.attrs = NULL;
ioctl.crc = NULL;
ioctl.job = NULL;
VERIFY(err, !(err = fastrpc_internal_invoke(fl,
FASTRPC_MODE_PARALLEL, 1, &ioctl)));
if (err)
goto bail;
} else if (init->flags == FASTRPC_INIT_CREATE_STATIC) {
remote_arg_t ra[3];
uint64_t phys = 0;
size_t size = 0;
int fds[3];
struct {
int pgid;
unsigned int namelen;
unsigned int pageslen;
} inbuf;
if (!init->filelen)
goto bail;
proc_name = kzalloc(init->filelen, GFP_KERNEL);
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));
if (err)
goto bail;
fl->pd = 1;
inbuf.pgid = current->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));
if (err)
goto bail;
}
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);
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 (err) {
pr_err("adsprpc: %s: rh hyp assign failed with %d for phys 0x%llx, size %zd\n",
__func__, err, phys, size);
goto bail;
}
rh_hyp_done = 1;
}
me->staticpd_flags = 1;
}
ra[0].buf.pv = (void *)&inbuf;
ra[0].buf.len = sizeof(inbuf);
fds[0] = -1;
ra[1].buf.pv = (void *)proc_name;
ra[1].buf.len = inbuf.namelen;
fds[1] = -1;
pages[0].addr = phys;
pages[0].size = size;
ra[2].buf.pv = (void *)pages;
ra[2].buf.len = sizeof(*pages);
fds[2] = -1;
ioctl.inv.handle = FASTRPC_STATIC_HANDLE_PROCESS_GROUP;
ioctl.inv.sc = REMOTE_SCALARS_MAKE(8, 3, 0);
ioctl.inv.pra = ra;
ioctl.fds = NULL;
ioctl.attrs = NULL;
ioctl.crc = NULL;
ioctl.job = NULL;
VERIFY(err, !(err = fastrpc_internal_invoke(fl,
FASTRPC_MODE_PARALLEL, 1, &ioctl)));
if (err)
goto bail;
} else {
err = -ENOTTY;
/*
* 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;
pr_err("adsprpc: %s: %s: ERROR: donated memory allocated in userspace\n",
current->comm, __func__);
goto bail;
}
fl->dsp_proc_init = 1;
bail:
kfree(proc_name);
if (err && (init->flags == FASTRPC_INIT_CREATE_STATIC))
me->staticpd_flags = 0;
if (mem && err) {
if (mem->flags == ADSP_MMAP_REMOTE_HEAP_ADDR
&& me->channel[fl->cid].rhvm.vmid && rh_hyp_done) {
int hyp_err = 0;
/* Free any previous donated memory */
if (fl->init_mem)
fastrpc_buf_free(fl->init_mem, 0);
hyp_err = hyp_assign_phys(mem->phys,
(uint64_t)mem->size,
me->channel[fl->cid].rhvm.vmid,
me->channel[fl->cid].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",
__func__, current->comm,
hyp_err, mem->phys, mem->size);
}
/* 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;
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);
fds[0] = -1;
ra[1].buf.pv = (void *)current->comm;
ra[1].buf.len = inbuf.namelen;
fds[1] = -1;
ra[2].buf.pv = (void *)init->file;
ra[2].buf.len = inbuf.filelen;
fds[2] = init->filefd;
pages[0].addr = imem->phys;
pages[0].size = imem->size;
ra[3].buf.pv = (void *)pages;
ra[3].buf.len = 1 * sizeof(*pages);
fds[3] = -1;
inbuf.attrs = uproc->attrs;
ra[4].buf.pv = (void *)&(inbuf.attrs);
ra[4].buf.len = sizeof(inbuf.attrs);
fds[4] = -1;
inbuf.siglen = uproc->siglen;
ra[5].buf.pv = (void *)&(inbuf.siglen);
ra[5].buf.len = sizeof(inbuf.siglen);
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);
ioctl.inv.pra = ra;
ioctl.fds = fds;
ioctl.attrs = NULL;
ioctl.crc = NULL;
ioctl.job = NULL;
err = fastrpc_internal_invoke(fl, FASTRPC_MODE_PARALLEL, 1, &ioctl);
if (err)
goto bail;
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(mem, 0);
fastrpc_mmap_free(file, 0);
mutex_unlock(&fl->map_mutex);
}
if (err) {
@ -3005,14 +2918,179 @@ bail:
fl->init_mem = NULL;
}
}
if (file) {
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;
unsigned int pageslen;
} inbuf;
if (!init->filelen)
goto bail;
proc_name = kzalloc(init->filelen, GFP_KERNEL);
VERIFY(err, !IS_ERR_OR_NULL(proc_name));
if (err)
goto bail;
err = copy_from_user((void *)proc_name,
(void __user *)init->file, init->filelen);
if (err)
goto bail;
fl->pd = 1;
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;
/*
* 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) {
inbuf.pageslen = 1;
mutex_lock(&fl->map_mutex);
fastrpc_mmap_free(file, 0);
err = fastrpc_mmap_create(fl, -1, 0, init->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 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: %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;
}
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;
ra[1].buf.pv = (void *)proc_name;
ra[1].buf.len = inbuf.namelen;
fds[1] = -1;
pages[0].addr = phys;
pages[0].size = size;
ra[2].buf.pv = (void *)pages;
ra[2].buf.len = sizeof(*pages);
fds[2] = -1;
ioctl.inv.handle = FASTRPC_STATIC_HANDLE_PROCESS_GROUP;
ioctl.inv.sc = REMOTE_SCALARS_MAKE(8, 3, 0);
ioctl.inv.pra = ra;
ioctl.fds = NULL;
ioctl.attrs = NULL;
ioctl.crc = NULL;
ioctl.job = NULL;
err = fastrpc_internal_invoke(fl, FASTRPC_MODE_PARALLEL, 1, &ioctl);
if (err)
goto bail;
bail:
kfree(proc_name);
if (err) {
me->staticpd_flags = 0;
if (rh_hyp_done) {
int hyp_err = 0;
/* 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 %zu\n",
__func__, current->comm,
hyp_err, phys, size);
}
mutex_lock(&fl->map_mutex);
fastrpc_mmap_free(mem, 0);
mutex_unlock(&fl->map_mutex);
}
return err;
}
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;
}
static int fastrpc_kstat(const char *filename, struct kstat *stat)
{
int result;
@ -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;
}
}
@ -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;
}
@ -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)
{
@ -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")) {
@ -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(
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(
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_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:
fastrpc_setup_service_locator(dev, AUDIO_PDR_ADSP_DTSI_PROPERTY_NAME,
AUDIO_PDR_SERVICE_LOCATION_CLIENT_NAME,
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);
fastrpc_setup_service_locator(dev, SENSORS_PDR_SLPI_DTSI_PROPERTY_NAME,
SENSORS_PDR_SLPI_SERVICE_LOCATION_CLIENT_NAME,
SENSORS_PDR_SLPI_SERVICE_NAME);
err = of_platform_populate(pdev->dev.of_node,
fastrpc_match_table,
NULL, &pdev->dev);