diff --git a/dsp/adsprpc.c b/dsp/adsprpc.c index 3f8603c4f0..199c41731d 100644 --- a/dsp/adsprpc.c +++ b/dsp/adsprpc.c @@ -106,9 +106,6 @@ #define M_KERNEL_PERF_LIST (PERF_KEY_MAX) #define M_DSP_PERF_LIST (12) -#define SESSION_ID_INDEX (30) -#define SESSION_ID_MASK (1 << SESSION_ID_INDEX) -#define PROCESS_ID_MASK ((2^SESSION_ID_INDEX) - 1) #define FASTRPC_CTX_MAGIC (0xbeeddeed) /* Process status notifications from DSP will be sent with this unique context */ @@ -203,6 +200,9 @@ /* Max no. of persistent headers pre-allocated per process */ #define MAX_PERSISTENT_HEADERS (25) +/* Max value of unique fastrpc tgid */ +#define MAX_FRPC_TGID 65 + #define PERF_CAPABILITY_SUPPORT (1 << 1) #define KERNEL_ERROR_CODE_V1_SUPPORT 1 #define USERSPACE_ALLOCATION_SUPPORT 1 @@ -229,6 +229,9 @@ /* Unique index flag used for mini dump */ static int md_unique_index_flag[MAX_UNIQUE_ID] = { 0, 0, 0, 0, 0 }; +/* Array to keep track unique tgid_frpc usage */ +static bool frpc_tgid_usage_array[NUM_CHANNELS][MAX_FRPC_TGID] = {0}; + /* Fastrpc remote process attributes */ enum fastrpc_proc_attr { /* Macro for Debug attr */ @@ -1836,6 +1839,7 @@ static int context_alloc(struct fastrpc_file *fl, uint32_t kernel, } ctx->retval = -1; ctx->pid = current->pid; + /* Store HLOS PID in context, it is not being sent to DSP */ ctx->tgid = fl->tgid; init_completion(&ctx->work); ctx->magic = FASTRPC_CTX_MAGIC; @@ -1854,6 +1858,7 @@ static int context_alloc(struct fastrpc_file *fl, uint32_t kernel, goto bail; } memset(ctx->perf, 0, sizeof(*(ctx->perf))); + /* Use HLOS PID, as perf tid is not being sent to DSP and is used to log in traces */ ctx->perf->tid = fl->tgid; } if (invokefd->job) { @@ -2033,13 +2038,11 @@ static void fastrpc_notif_find_process(int domain, struct smq_notif_rspv3 *notif struct fastrpc_file *fl = NULL; struct hlist_node *n; bool is_process_found = false; - int sessionid = 0; unsigned long irq_flags = 0; spin_lock_irqsave(&me->hlock, irq_flags); hlist_for_each_entry_safe(fl, n, &me->drivers, hn) { - if (fl->tgid == notif->pid || - (fl->tgid == (notif->pid & PROCESS_ID_MASK))) { + if (fl->tgid_frpc == notif->pid) { is_process_found = true; break; } @@ -2048,9 +2051,7 @@ static void fastrpc_notif_find_process(int domain, struct smq_notif_rspv3 *notif if (!is_process_found) return; - if (notif->pid & SESSION_ID_MASK) - sessionid = 1; - fastrpc_queue_pd_status(fl, domain, notif->status, sessionid); + fastrpc_queue_pd_status(fl, domain, notif->status, fl->sessionid); } static void context_notify_user(struct smq_invoke_ctx *ctx, @@ -2896,10 +2897,9 @@ static int fastrpc_invoke_send(struct smq_invoke_ctx *ctx, channel_ctx = &fl->apps->channel[cid]; mutex_lock(&channel_ctx->smd_mutex); - msg->pid = fl->tgid; + /* Send unique fastrpc process ID to dsp */ + msg->pid = fl->tgid_frpc; msg->tid = current->pid; - if (fl->sessionid) - msg->tid |= SESSION_ID_MASK; if (kernel == KERNEL_MSG_WITH_ZERO_PID) msg->pid = 0; msg->invoke.header.ctx = ctx->ctxid | fl->pd; @@ -2997,6 +2997,7 @@ static void fastrpc_init(struct fastrpc_apps *me) spin_lock_init(&me->hlock); me->channel = &gcinfo[0]; mutex_init(&me->mut_uid); + me->max_sess_per_proc = DEFAULT_MAX_SESS_PER_PROC; for (i = 0; i < NUM_CHANNELS; i++) { init_completion(&me->channel[i].work); init_completion(&me->channel[i].workport); @@ -3576,6 +3577,16 @@ static int fastrpc_set_session_info( // Processes attaching to Sensor Static PD, share context bank. if (sess_info->pd_type == SENSORS_STATICPD) fl->sharedcb = 1; + if (sess_info->session_id >= me->max_sess_per_proc) { + ADSPRPC_ERR( + "Session ID %u cannot be beyond %u\n", + sess_info->session_id, me->max_sess_per_proc); + err = -EBADR; + goto bail; + } + fl->sessionid = sess_info->session_id; + // Set multi_session_support, to disable old way of setting session_id + fl->multi_session_support = true; VERIFY(err, 0 == (err = fastrpc_get_info(fl, &(sess_info->domain_id)))); if (err) goto bail; @@ -3826,7 +3837,7 @@ static int fastrpc_mmap_remove_ssr(struct fastrpc_file *fl, int locked); static int fastrpc_init_attach_process(struct fastrpc_file *fl, struct fastrpc_ioctl_init *init) { - int err = 0, tgid = fl->tgid; + int err = 0, tgid = fl->tgid_frpc; remote_arg_t ra[1]; struct fastrpc_ioctl_invoke_async ioctl; @@ -3839,6 +3850,7 @@ static int fastrpc_init_attach_process(struct fastrpc_file *fl, /* * Prepare remote arguments for creating thread group * in guestOS/staticPD on the remote subsystem. + * Send unique fastrpc id to dsp */ ra[0].buf.pv = (void *)&tgid; ra[0].buf.len = sizeof(tgid); @@ -3922,7 +3934,7 @@ static int fastrpc_init_create_dynamic_process(struct fastrpc_file *fl, spin_unlock(&fl->hlock); - inbuf.pgid = fl->tgid; + inbuf.pgid = fl->tgid_frpc; inbuf.namelen = strlen(current->comm) + 1; inbuf.filelen = init->filelen; fl->pd = FASTRPC_USER_PD; @@ -4183,7 +4195,7 @@ static int fastrpc_init_create_static_process(struct fastrpc_file *fl, } fl->pd = FASTRPC_USER_PD; - inbuf.pgid = fl->tgid; + inbuf.pgid = fl->tgid_frpc; inbuf.namelen = init->filelen; inbuf.pageslen = 0; @@ -4623,7 +4635,8 @@ static int fastrpc_release_current_dsp_process(struct fastrpc_file *fl) err = -ECONNRESET; goto bail; } - tgid = fl->tgid; + /* Send unique fastrpc process ID to dsp */ + tgid = fl->tgid_frpc; ra[0].buf.pv = (void *)&tgid; ra[0].buf.len = sizeof(tgid); ioctl.inv.handle = FASTRPC_STATIC_HANDLE_PROCESS_GROUP; @@ -4682,7 +4695,8 @@ static int fastrpc_mem_map_to_dsp(struct fastrpc_file *fl, int fd, int offset, uint64_t vaddrout; } routargs; - inargs.pid = fl->tgid; + /* Send unique fastrpc process ID to dsp */ + inargs.pid = fl->tgid_frpc; inargs.fd = fd; inargs.offset = offset; inargs.vaddrin = (uintptr_t)va; @@ -4733,7 +4747,8 @@ static int fastrpc_mem_unmap_to_dsp(struct fastrpc_file *fl, int fd, uint64_t len; } inargs; - inargs.pid = fl->tgid; + /* Send unique fastrpc process ID to dsp */ + inargs.pid = fl->tgid_frpc; inargs.fd = fd; inargs.vaddrin = (uint64_t)va; inargs.len = (uint64_t)size; @@ -4769,7 +4784,8 @@ static int fastrpc_unmap_on_dsp(struct fastrpc_file *fl, size_t size; } inargs; - inargs.pid = fl->tgid; + /* Send unique fastrpc process ID to dsp */ + inargs.pid = fl->tgid_frpc; inargs.size = size; inargs.vaddrout = raddr; ra[0].buf.pv = (void *)&inargs; @@ -4821,7 +4837,8 @@ static int fastrpc_mmap_on_dsp(struct fastrpc_file *fl, uint32_t flags, goto bail; } cid = fl->cid; - inargs.pid = fl->tgid; + /* Send unique fastrpc process ID to dsp */ + inargs.pid = fl->tgid_frpc; inargs.vaddrin = (uintptr_t)va; inargs.flags = flags; inargs.num = fl->apps->compat ? num * sizeof(page) : num; @@ -4926,7 +4943,8 @@ static int fastrpc_munmap_on_dsp_rh(struct fastrpc_file *fl, uint64_t phys, goto bail; } - tgid = fl->tgid; + /* Send unique fastrpc process ID to dsp */ + tgid = fl->tgid_frpc; ra[0].buf.pv = (void *)&tgid; ra[0].buf.len = sizeof(tgid); ra[1].buf.pv = (void *)&routargs; @@ -5566,7 +5584,8 @@ static void handle_remote_signal(uint64_t msg, int cid) spin_lock_irqsave(&me->hlock, irq_flags); hlist_for_each_entry_safe(fl, n, &me->drivers, hn) { - if ((fl->tgid == pid) && (fl->cid == cid)) { + /* Response from DSP contains unique fastrpc process id, use unique fastrpc process ID to compare */ + if ((fl->tgid_frpc == pid) && (fl->cid == cid)) { unsigned long fflags = 0; spin_lock_irqsave(&fl->dspsignals_lock, fflags); @@ -5797,6 +5816,10 @@ skip_dump_wait: fl->is_ramdump_pend = false; fl->is_dma_invoke_pend = false; fl->dsp_process_state = PROCESS_CREATE_DEFAULT; + VERIFY(err, VALID_FASTRPC_CID(cid)); + /* Reset the tgid usage to false */ + if (!err) + frpc_tgid_usage_array[cid][fl->tgid_frpc] = false; is_locked = false; spin_unlock_irqrestore(&fl->apps->hlock, irq_flags); @@ -6247,6 +6270,7 @@ static int fastrpc_device_open(struct inode *inode, struct file *filp) fl->apps = me; fl->mode = FASTRPC_MODE_SERIAL; fl->cid = -1; + fl->tgid_frpc = -1; fl->tvm_remote_domain = -1; fl->dev_minor = dev_minor; fl->init_mem = NULL; @@ -6258,6 +6282,7 @@ static int fastrpc_device_open(struct inode *inode, struct file *filp) fl->is_compat = false; fl->exit_notif = false; fl->exit_async = false; + fl->multi_session_support = false; init_completion(&fl->work); init_completion(&fl->dma_invoke); fl->file_close = FASTRPC_PROCESS_DEFAULT_STATE; @@ -6306,6 +6331,25 @@ bail: return err; } +// Generate a unique process ID to DSP process +static int get_unique_hlos_process_id(uint32_t cid) +{ + int tgid_frpc = -1, tgid_index = 1; + struct fastrpc_apps *me = &gfa; + + spin_lock(&me->hlock); + for (tgid_index = 1; tgid_index < MAX_FRPC_TGID; tgid_index++) { + if (!frpc_tgid_usage_array[cid][tgid_index]) { + tgid_frpc = tgid_index; + /* Set the tgid usage to false */ + frpc_tgid_usage_array[cid][tgid_index] = true; + break; + } + } + spin_unlock(&me->hlock); + return tgid_frpc; +} + static int fastrpc_set_process_info(struct fastrpc_file *fl, uint32_t cid) { int err = 0, buf_size = 0; @@ -6315,6 +6359,13 @@ static int fastrpc_set_process_info(struct fastrpc_file *fl, uint32_t cid) memcpy(cur_comm, current->comm, TASK_COMM_LEN); cur_comm[TASK_COMM_LEN-1] = '\0'; fl->tgid = current->tgid; + fl->tgid_frpc = get_unique_hlos_process_id(cid); + VERIFY(err, fl->tgid_frpc != -1); + if (err) { + ADSPRPC_ERR("too many fastrpc clients, max %u allowed\n", MAX_FRPC_TGID); + err = -EUSERS; + goto bail; + } /* * Third-party apps don't have permission to open the fastrpc device, so @@ -6347,8 +6398,11 @@ static int fastrpc_set_process_info(struct fastrpc_file *fl, uint32_t cid) err = -ENOMEM; return err; } - snprintf(fl->debug_buf, buf_size, "%.10s%s%d%s%d", - cur_comm, "_", current->pid, "_", cid); + /* Use HLOS PID, unique fastrpc PID, CID in debugfs filename, + * for better ability to debug + */ + snprintf(fl->debug_buf, buf_size, "%.10s%s%d%s%d%s%d", + cur_comm, "_", current->pid, "_", fl->tgid_frpc, "_", cid); fl->debugfs_file = debugfs_create_file(fl->debug_buf, 0644, debugfs_root, fl, &debugfs_fops); if (IS_ERR_OR_NULL(fl->debugfs_file)) { @@ -6374,6 +6428,11 @@ int fastrpc_get_info(struct fastrpc_file *fl, uint32_t *info) err = -EBADF; goto bail; } + VERIFY(err, VALID_FASTRPC_CID(cid)); + if (err) { + err = -ECHRNG; + goto bail; + } fastrpc_get_process_gids(&fl->gidlist); err = fastrpc_set_process_info(fl, cid); @@ -6383,11 +6442,6 @@ int fastrpc_get_info(struct fastrpc_file *fl, uint32_t *info) if (fl->cid == -1) { struct fastrpc_channel_ctx *chan = NULL; - VERIFY(err, cid < NUM_CHANNELS); - if (err) { - err = -ECHRNG; - goto bail; - } chan = &me->channel[cid]; /* Check to see if the device node is non-secure */ if (fl->dev_minor == MINOR_NUM_DEV) { @@ -6468,7 +6522,6 @@ int fastrpc_internal_control(struct fastrpc_file *fl, int err = 0; unsigned int latency; struct fastrpc_apps *me = &gfa; - int sessionid = 0; unsigned int cpu; unsigned long flags = 0; @@ -6564,9 +6617,7 @@ int fastrpc_internal_control(struct fastrpc_file *fl, break; case FASTRPC_CONTROL_DSPPROCESS_CLEAN: (void)fastrpc_release_current_dsp_process(fl); - if (fl->tgid & SESSION_ID_MASK) - sessionid = 1; - fastrpc_queue_pd_status(fl, fl->cid, FASTRPC_USER_PD_FORCE_KILL, sessionid); + fastrpc_queue_pd_status(fl, fl->cid, FASTRPC_USER_PD_FORCE_KILL, fl->sessionid); break; case FASTRPC_CONTROL_RPC_POLL: err = fastrpc_manage_poll_mode(fl, cp->lp.enable, cp->lp.latency); @@ -6648,8 +6699,8 @@ int fastrpc_setmode(unsigned long ioctl_param, "multiple sessions not allowed for untrusted apps\n"); goto bail; } - fl->sessionid = 1; - fl->tgid |= SESSION_ID_MASK; + if (!fl->multi_session_support) + fl->sessionid = 1; break; default: err = -ENOTTY; @@ -6720,8 +6771,9 @@ int fastrpc_dspsignal_signal(struct fastrpc_file *fl, // track outgoing signals in the driver. The userspace library does a // basic sanity check and any security validation needs to be done by // the recipient. - DSPSIGNAL_VERBOSE("Send signal PID %u, signal %u\n", - (unsigned int)fl->tgid, (unsigned int)sig->signal_id); + DSPSIGNAL_VERBOSE("Send signal PID %u, unique fastrpc pid %u signal %u\n", + (unsigned int)fl->tgid, (unsigned int)fl->tgid_frpc, + (unsigned int)sig->signal_id); VERIFY(err, sig->signal_id < DSPSIGNAL_NUM_SIGNALS); if (err) { ADSPRPC_ERR("Sending bad signal %u for PID %u", @@ -6745,7 +6797,8 @@ int fastrpc_dspsignal_signal(struct fastrpc_file *fl, goto bail; } - msg = (((uint64_t)fl->tgid) << 32) | ((uint64_t)sig->signal_id); + /* Use unique fastrpc pid, to signal DSP process */ + msg = (((uint64_t)fl->tgid_frpc) << 32) | ((uint64_t)sig->signal_id); err = fastrpc_transport_send(cid, (void *)&msg, sizeof(msg), fl->tvm_remote_domain); mutex_unlock(&channel_ctx->smd_mutex); @@ -7793,10 +7846,10 @@ static int fastrpc_cb_probe(struct device *dev) if (of_get_property(dev->of_node, "pd-type", NULL) != NULL) { err = of_property_read_u32(dev->of_node, "pd-type", &(sess->smmu.pd_type)); + /* Set cb_pd_type, if the process type is set for context banks */ + me->cb_pd_type = true; if (err) goto bail; - // Set cb_pd_type, if the process type is configured for context banks - me->cb_pd_type = true; } if (of_get_property(dev->of_node, "shared-cb", NULL) != NULL) { sess->smmu.sharedcb = 1; @@ -8131,6 +8184,8 @@ static int fastrpc_probe(struct platform_device *pdev) me->lowest_capacity_core_count = 1; of_property_read_u32(dev->of_node, "qcom,rpc-latency-us", &me->latency); + of_property_read_u32(dev->of_node, "qcom,max-sessions", + &me->max_sess_per_proc); if (of_get_property(dev->of_node, "qcom,secure-domains", NULL) != NULL) { VERIFY(err, !of_property_read_u32(dev->of_node, @@ -8564,17 +8619,23 @@ static int fastrpc_device_create(struct fastrpc_file *fl) frpc_dev->dev.parent = &fastrpc_bus; frpc_dev->dev.bus = &fastrpc_bus_type; - dev_set_name(&frpc_dev->dev, "%s-%d-%d", - dev_name(frpc_dev->dev.parent), fl->tgid, fl->cid); + /* Use HLOS PID, unique fastrpc process ID and CID to create device file, + * Else names would conflict for multiple sessions + * And also for better ability to debug + */ + dev_set_name(&frpc_dev->dev, "%s-%d-%d-%d", + dev_name(frpc_dev->dev.parent), fl->tgid, fl->tgid_frpc, fl->cid); frpc_dev->dev.release = fastrpc_dev_release; frpc_dev->fl = fl; - frpc_dev->handle = fl->tgid; + /* Use unique fastrpc tgid as handle */ + frpc_dev->handle = fl->tgid_frpc; err = device_register(&frpc_dev->dev); if (err) { put_device(&frpc_dev->dev); - ADSPRPC_ERR("fastrpc device register failed for process %d with error %d\n", - fl->tgid, err); + ADSPRPC_ERR( + "fastrpc device register failed for process %d unique fastrpc tgid %d session %d with error %d\n", + fl->tgid, fl->tgid_frpc, fl->sessionid, err); goto bail; } fl->device = frpc_dev; diff --git a/dsp/adsprpc_shared.h b/dsp/adsprpc_shared.h index cb48e2e87b..3ee534c460 100644 --- a/dsp/adsprpc_shared.h +++ b/dsp/adsprpc_shared.h @@ -88,6 +88,9 @@ #define NUM_CHANNELS 4 /* adsp, mdsp, slpi, cdsp*/ #define NUM_SESSIONS 14 /* max 11 compute, 3 cpz */ +/* Default maximum sessions allowed per process */ +#define DEFAULT_MAX_SESS_PER_PROC 4 + #define VALID_FASTRPC_CID(cid) \ (cid >= ADSP_DOMAIN_ID && cid < NUM_CHANNELS) @@ -753,6 +756,8 @@ struct fastrpc_apps { unsigned int lowest_capacity_core_count; /* Flag to check if PM QoS vote needs to be done for only one core */ bool single_core_latency_vote; + /* Maximum sessions allowed to be created per process */ + uint32_t max_sess_per_proc; }; struct fastrpc_mmap { @@ -846,6 +851,8 @@ struct fastrpc_file { int sessionid; int tgid_open; /* Process ID during device open */ int tgid; /* Process ID that uses device for RPC calls */ + /* Unique HLOS process ID created by fastrpc for each client */ + int tgid_frpc; int cid; int tvm_remote_domain; uint64_t ssrcount; @@ -914,6 +921,8 @@ struct fastrpc_file { * config paramters. */ struct fastrpc_proc_sharedbuf_info sharedbuf_info; + /* Flag to indicate 4 session support available */ + bool multi_session_support; }; int fastrpc_internal_invoke(struct fastrpc_file *fl, uint32_t mode,