Loading drivers/misc/qseecom.c +80 −81 Original line number Diff line number Diff line Loading @@ -198,6 +198,7 @@ struct qseecom_registered_listener_list { wait_queue_head_t listener_block_app_wq; struct sglist_info sglistinfo_ptr[MAX_ION_FD]; uint32_t sglist_cnt; int abort; }; struct qseecom_registered_app_list { Loading Loading @@ -1367,6 +1368,23 @@ static int qseecom_register_listener(struct qseecom_dev_handle *data, return ret; } static void __qseecom_listener_abort_all(int abort) { struct qseecom_registered_listener_list *entry = NULL; unsigned long flags; spin_lock_irqsave(&qseecom.registered_listener_list_lock, flags); list_for_each_entry(entry, &qseecom.registered_listener_list_head, list) { pr_debug("set abort %d for listener %d\n", abort, entry->svc.listener_id); entry->abort = abort; } if (abort) wake_up_interruptible_all(&qseecom.send_resp_wq); spin_unlock_irqrestore(&qseecom.registered_listener_list_lock, flags); } static int qseecom_unregister_listener(struct qseecom_dev_handle *data) { int ret = 0; Loading Loading @@ -1399,6 +1417,7 @@ static int qseecom_unregister_listener(struct qseecom_dev_handle *data) } data->abort = 1; ptr_svc->abort = 1; wake_up_all(&ptr_svc->rcv_req_wq); while (atomic_read(&data->ioctl_count) > 1) { Loading Loading @@ -1718,12 +1737,13 @@ static int qseecom_set_client_mem_param(struct qseecom_dev_handle *data, return ret; } static int __qseecom_listener_has_sent_rsp(struct qseecom_dev_handle *data) static int __qseecom_listener_has_sent_rsp(struct qseecom_dev_handle *data, struct qseecom_registered_listener_list *ptr_svc) { int ret; ret = (qseecom.send_resp_flag != 0); return ret || data->abort; return ret || data->abort || ptr_svc->abort; } static int __qseecom_reentrancy_listener_has_sent_rsp( Loading @@ -1733,62 +1753,7 @@ static int __qseecom_reentrancy_listener_has_sent_rsp( int ret; ret = (ptr_svc->send_resp_flag != 0); return ret || data->abort; } static int __qseecom_qseos_fail_return_resp_tz(struct qseecom_dev_handle *data, struct qseecom_command_scm_resp *resp, struct qseecom_client_listener_data_irsp *send_data_rsp, struct qseecom_registered_listener_list *ptr_svc, uint32_t lstnr) { int ret = 0; send_data_rsp->status = QSEOS_RESULT_FAILURE; qseecom.send_resp_flag = 0; send_data_rsp->qsee_cmd_id = QSEOS_LISTENER_DATA_RSP_COMMAND; send_data_rsp->listener_id = lstnr; if (ptr_svc) pr_warn("listener_id:%x, lstnr: %x\n", ptr_svc->svc.listener_id, lstnr); if (lstnr == RPMB_SERVICE) { ret = __qseecom_enable_clk(CLK_QSEE); if (ret) return ret; } if (ptr_svc && ptr_svc->dmabuf) { ret = qseecom_dmabuf_cache_operations(ptr_svc->dmabuf, QSEECOM_CACHE_CLEAN); if (ret) goto exit; } ret = qseecom_scm_call(SCM_SVC_TZSCHEDULER, 1, send_data_rsp, sizeof(send_data_rsp), resp, sizeof(*resp)); if (ret) { pr_err("scm_call() failed with err: %d (app_id = %d)\n", ret, data->client.app_id); goto exit; } if (ptr_svc && ptr_svc->dmabuf) { ret = qseecom_dmabuf_cache_operations(ptr_svc->dmabuf, QSEECOM_CACHE_INVALIDATE); if (ret) goto exit; } if ((resp->result != QSEOS_RESULT_SUCCESS) && (resp->result != QSEOS_RESULT_INCOMPLETE)) { pr_err("fail:resp res= %d,app_id = %d,lstr = %d\n", resp->result, data->client.app_id, lstnr); ret = -EINVAL; } exit: if (lstnr == RPMB_SERVICE) __qseecom_disable_clk(CLK_QSEE); return ret; return ret || data->abort || ptr_svc->abort; } static void __qseecom_clean_listener_sglistinfo( Loading Loading @@ -1839,23 +1804,33 @@ static int __qseecom_process_incomplete_cmd(struct qseecom_dev_handle *data, if (ptr_svc == NULL) { pr_err("Listener Svc %d does not exist\n", lstnr); __qseecom_qseos_fail_return_resp_tz(data, resp, &send_data_rsp, ptr_svc, lstnr); return -EINVAL; rc = -EINVAL; status = QSEOS_RESULT_FAILURE; goto err_resp; } if (!ptr_svc->dmabuf) { pr_err("Client dmabuf is not initialized\n"); __qseecom_qseos_fail_return_resp_tz(data, resp, &send_data_rsp, ptr_svc, lstnr); return -EINVAL; rc = -EINVAL; status = QSEOS_RESULT_FAILURE; goto err_resp; } if (ptr_svc->svc.listener_id != lstnr) { pr_warn("Service requested does not exist\n"); __qseecom_qseos_fail_return_resp_tz(data, resp, &send_data_rsp, NULL, lstnr); return -ERESTARTSYS; pr_err("Service %d does not exist\n", lstnr); rc = -ERESTARTSYS; ptr_svc = NULL; status = QSEOS_RESULT_FAILURE; goto err_resp; } if (ptr_svc->abort == 1) { pr_err("Service %d abort %d\n", lstnr, ptr_svc->abort); rc = -ENODEV; status = QSEOS_RESULT_FAILURE; goto err_resp; } pr_debug("waking up rcv_req_wq and waiting for send_resp_wq\n"); Loading @@ -1872,7 +1847,8 @@ static int __qseecom_process_incomplete_cmd(struct qseecom_dev_handle *data, */ if (!qseecom.qsee_reentrancy_support && !wait_event_freezable(qseecom.send_resp_wq, __qseecom_listener_has_sent_rsp(data))) { __qseecom_listener_has_sent_rsp( data, ptr_svc))) { break; } Loading @@ -1886,7 +1862,7 @@ static int __qseecom_process_incomplete_cmd(struct qseecom_dev_handle *data, /* restore signal mask */ sigprocmask(SIG_SETMASK, &old_sigset, NULL); if (data->abort) { if (data->abort || ptr_svc->abort) { pr_err("Abort clnt %d waiting on lstnr svc %d, ret %d", data->client.app_id, lstnr, ret); rc = -ENODEV; Loading @@ -1894,7 +1870,7 @@ static int __qseecom_process_incomplete_cmd(struct qseecom_dev_handle *data, } else { status = QSEOS_RESULT_SUCCESS; } err_resp: qseecom.send_resp_flag = 0; ptr_svc->send_resp_flag = 0; table = ptr_svc->sglistinfo_ptr; Loading Loading @@ -1957,6 +1933,8 @@ static int __qseecom_process_incomplete_cmd(struct qseecom_dev_handle *data, if (ret) return ret; pr_debug("resp status %d, res= %d, app_id = %d, lstr = %d\n", status, resp->result, data->client.app_id, lstnr); if ((resp->result != QSEOS_RESULT_SUCCESS) && (resp->result != QSEOS_RESULT_INCOMPLETE)) { pr_err("fail:resp res= %d,app_id = %d,lstr = %d\n", Loading Loading @@ -2107,7 +2085,7 @@ static int __qseecom_reentrancy_process_incomplete_cmd( size_t cmd_len; struct sglist_info *table = NULL; while (ret == 0 && rc == 0 && resp->result == QSEOS_RESULT_INCOMPLETE) { while (ret == 0 && resp->result == QSEOS_RESULT_INCOMPLETE) { lstnr = resp->data; /* * Wake up blocking lsitener service with the lstnr id Loading @@ -2128,17 +2106,33 @@ static int __qseecom_reentrancy_process_incomplete_cmd( if (ptr_svc == NULL) { pr_err("Listener Svc %d does not exist\n", lstnr); return -EINVAL; rc = -EINVAL; status = QSEOS_RESULT_FAILURE; goto err_resp; } if (!ptr_svc->dmabuf) { pr_err("Client dmabuf is not initialized\n"); return -EINVAL; rc = -EINVAL; status = QSEOS_RESULT_FAILURE; goto err_resp; } if (ptr_svc->svc.listener_id != lstnr) { pr_warn("Service requested does not exist\n"); return -ERESTARTSYS; pr_err("Service %d does not exist\n", lstnr); rc = -ERESTARTSYS; ptr_svc = NULL; status = QSEOS_RESULT_FAILURE; goto err_resp; } if (ptr_svc->abort == 1) { pr_err("Service %d abort %d\n", lstnr, ptr_svc->abort); rc = -ENODEV; status = QSEOS_RESULT_FAILURE; goto err_resp; } pr_debug("waking up rcv_req_wq and waiting for send_resp_wq\n"); Loading @@ -2164,7 +2158,7 @@ static int __qseecom_reentrancy_process_incomplete_cmd( /* restore signal mask */ sigprocmask(SIG_SETMASK, &old_sigset, NULL); if (data->abort) { if (data->abort || ptr_svc->abort) { pr_err("Abort clnt %d waiting on lstnr svc %d, ret %d", data->client.app_id, lstnr, ret); rc = -ENODEV; Loading @@ -2172,6 +2166,7 @@ static int __qseecom_reentrancy_process_incomplete_cmd( } else { status = QSEOS_RESULT_SUCCESS; } err_resp: table = ptr_svc->sglistinfo_ptr; if (qseecom.qsee_version < QSEE_VERSION_40) { send_data_rsp.listener_id = lstnr; Loading Loading @@ -3907,7 +3902,7 @@ static int __qseecom_listener_has_rcvd_req(struct qseecom_dev_handle *data, int ret; ret = (svc->rcv_req_flag != 0); return ret || data->abort; return ret || data->abort || svc->abort; } static int qseecom_receive_req(struct qseecom_dev_handle *data) Loading @@ -3931,7 +3926,7 @@ static int qseecom_receive_req(struct qseecom_dev_handle *data) return -ERESTARTSYS; } if (data->abort) { if (data->abort || this_lstnr->abort) { pr_err("Aborting Listener Service = %d\n", (uint32_t)data->listener.id); return -ENODEV; Loading Loading @@ -6189,7 +6184,7 @@ static int qseecom_update_key_user_info(struct qseecom_dev_handle *data, } static int qseecom_is_es_activated(void __user *argp) { struct qseecom_is_es_activated_req req; struct qseecom_is_es_activated_req req = {0}; struct qseecom_command_scm_resp resp; int ret; Loading Loading @@ -7012,12 +7007,14 @@ static inline long qseecom_ioctl(struct file *file, break; } pr_debug("ioctl unregister_listener_req()\n"); __qseecom_listener_abort_all(1); mutex_lock(&app_access_lock); atomic_inc(&data->ioctl_count); ret = qseecom_unregister_listener(data); atomic_dec(&data->ioctl_count); wake_up_all(&data->abort_wq); mutex_unlock(&app_access_lock); __qseecom_listener_abort_all(0); if (ret) pr_err("failed qseecom_unregister_listener: %d\n", ret); break; Loading Loading @@ -7684,9 +7681,11 @@ static int qseecom_release(struct inode *inode, struct file *file) data->type, data->mode, data); switch (data->type) { case QSEECOM_LISTENER_SERVICE: __qseecom_listener_abort_all(1); mutex_lock(&app_access_lock); ret = qseecom_unregister_listener(data); mutex_unlock(&app_access_lock); __qseecom_listener_abort_all(0); break; case QSEECOM_CLIENT_APP: mutex_lock(&app_access_lock); Loading Loading
drivers/misc/qseecom.c +80 −81 Original line number Diff line number Diff line Loading @@ -198,6 +198,7 @@ struct qseecom_registered_listener_list { wait_queue_head_t listener_block_app_wq; struct sglist_info sglistinfo_ptr[MAX_ION_FD]; uint32_t sglist_cnt; int abort; }; struct qseecom_registered_app_list { Loading Loading @@ -1367,6 +1368,23 @@ static int qseecom_register_listener(struct qseecom_dev_handle *data, return ret; } static void __qseecom_listener_abort_all(int abort) { struct qseecom_registered_listener_list *entry = NULL; unsigned long flags; spin_lock_irqsave(&qseecom.registered_listener_list_lock, flags); list_for_each_entry(entry, &qseecom.registered_listener_list_head, list) { pr_debug("set abort %d for listener %d\n", abort, entry->svc.listener_id); entry->abort = abort; } if (abort) wake_up_interruptible_all(&qseecom.send_resp_wq); spin_unlock_irqrestore(&qseecom.registered_listener_list_lock, flags); } static int qseecom_unregister_listener(struct qseecom_dev_handle *data) { int ret = 0; Loading Loading @@ -1399,6 +1417,7 @@ static int qseecom_unregister_listener(struct qseecom_dev_handle *data) } data->abort = 1; ptr_svc->abort = 1; wake_up_all(&ptr_svc->rcv_req_wq); while (atomic_read(&data->ioctl_count) > 1) { Loading Loading @@ -1718,12 +1737,13 @@ static int qseecom_set_client_mem_param(struct qseecom_dev_handle *data, return ret; } static int __qseecom_listener_has_sent_rsp(struct qseecom_dev_handle *data) static int __qseecom_listener_has_sent_rsp(struct qseecom_dev_handle *data, struct qseecom_registered_listener_list *ptr_svc) { int ret; ret = (qseecom.send_resp_flag != 0); return ret || data->abort; return ret || data->abort || ptr_svc->abort; } static int __qseecom_reentrancy_listener_has_sent_rsp( Loading @@ -1733,62 +1753,7 @@ static int __qseecom_reentrancy_listener_has_sent_rsp( int ret; ret = (ptr_svc->send_resp_flag != 0); return ret || data->abort; } static int __qseecom_qseos_fail_return_resp_tz(struct qseecom_dev_handle *data, struct qseecom_command_scm_resp *resp, struct qseecom_client_listener_data_irsp *send_data_rsp, struct qseecom_registered_listener_list *ptr_svc, uint32_t lstnr) { int ret = 0; send_data_rsp->status = QSEOS_RESULT_FAILURE; qseecom.send_resp_flag = 0; send_data_rsp->qsee_cmd_id = QSEOS_LISTENER_DATA_RSP_COMMAND; send_data_rsp->listener_id = lstnr; if (ptr_svc) pr_warn("listener_id:%x, lstnr: %x\n", ptr_svc->svc.listener_id, lstnr); if (lstnr == RPMB_SERVICE) { ret = __qseecom_enable_clk(CLK_QSEE); if (ret) return ret; } if (ptr_svc && ptr_svc->dmabuf) { ret = qseecom_dmabuf_cache_operations(ptr_svc->dmabuf, QSEECOM_CACHE_CLEAN); if (ret) goto exit; } ret = qseecom_scm_call(SCM_SVC_TZSCHEDULER, 1, send_data_rsp, sizeof(send_data_rsp), resp, sizeof(*resp)); if (ret) { pr_err("scm_call() failed with err: %d (app_id = %d)\n", ret, data->client.app_id); goto exit; } if (ptr_svc && ptr_svc->dmabuf) { ret = qseecom_dmabuf_cache_operations(ptr_svc->dmabuf, QSEECOM_CACHE_INVALIDATE); if (ret) goto exit; } if ((resp->result != QSEOS_RESULT_SUCCESS) && (resp->result != QSEOS_RESULT_INCOMPLETE)) { pr_err("fail:resp res= %d,app_id = %d,lstr = %d\n", resp->result, data->client.app_id, lstnr); ret = -EINVAL; } exit: if (lstnr == RPMB_SERVICE) __qseecom_disable_clk(CLK_QSEE); return ret; return ret || data->abort || ptr_svc->abort; } static void __qseecom_clean_listener_sglistinfo( Loading Loading @@ -1839,23 +1804,33 @@ static int __qseecom_process_incomplete_cmd(struct qseecom_dev_handle *data, if (ptr_svc == NULL) { pr_err("Listener Svc %d does not exist\n", lstnr); __qseecom_qseos_fail_return_resp_tz(data, resp, &send_data_rsp, ptr_svc, lstnr); return -EINVAL; rc = -EINVAL; status = QSEOS_RESULT_FAILURE; goto err_resp; } if (!ptr_svc->dmabuf) { pr_err("Client dmabuf is not initialized\n"); __qseecom_qseos_fail_return_resp_tz(data, resp, &send_data_rsp, ptr_svc, lstnr); return -EINVAL; rc = -EINVAL; status = QSEOS_RESULT_FAILURE; goto err_resp; } if (ptr_svc->svc.listener_id != lstnr) { pr_warn("Service requested does not exist\n"); __qseecom_qseos_fail_return_resp_tz(data, resp, &send_data_rsp, NULL, lstnr); return -ERESTARTSYS; pr_err("Service %d does not exist\n", lstnr); rc = -ERESTARTSYS; ptr_svc = NULL; status = QSEOS_RESULT_FAILURE; goto err_resp; } if (ptr_svc->abort == 1) { pr_err("Service %d abort %d\n", lstnr, ptr_svc->abort); rc = -ENODEV; status = QSEOS_RESULT_FAILURE; goto err_resp; } pr_debug("waking up rcv_req_wq and waiting for send_resp_wq\n"); Loading @@ -1872,7 +1847,8 @@ static int __qseecom_process_incomplete_cmd(struct qseecom_dev_handle *data, */ if (!qseecom.qsee_reentrancy_support && !wait_event_freezable(qseecom.send_resp_wq, __qseecom_listener_has_sent_rsp(data))) { __qseecom_listener_has_sent_rsp( data, ptr_svc))) { break; } Loading @@ -1886,7 +1862,7 @@ static int __qseecom_process_incomplete_cmd(struct qseecom_dev_handle *data, /* restore signal mask */ sigprocmask(SIG_SETMASK, &old_sigset, NULL); if (data->abort) { if (data->abort || ptr_svc->abort) { pr_err("Abort clnt %d waiting on lstnr svc %d, ret %d", data->client.app_id, lstnr, ret); rc = -ENODEV; Loading @@ -1894,7 +1870,7 @@ static int __qseecom_process_incomplete_cmd(struct qseecom_dev_handle *data, } else { status = QSEOS_RESULT_SUCCESS; } err_resp: qseecom.send_resp_flag = 0; ptr_svc->send_resp_flag = 0; table = ptr_svc->sglistinfo_ptr; Loading Loading @@ -1957,6 +1933,8 @@ static int __qseecom_process_incomplete_cmd(struct qseecom_dev_handle *data, if (ret) return ret; pr_debug("resp status %d, res= %d, app_id = %d, lstr = %d\n", status, resp->result, data->client.app_id, lstnr); if ((resp->result != QSEOS_RESULT_SUCCESS) && (resp->result != QSEOS_RESULT_INCOMPLETE)) { pr_err("fail:resp res= %d,app_id = %d,lstr = %d\n", Loading Loading @@ -2107,7 +2085,7 @@ static int __qseecom_reentrancy_process_incomplete_cmd( size_t cmd_len; struct sglist_info *table = NULL; while (ret == 0 && rc == 0 && resp->result == QSEOS_RESULT_INCOMPLETE) { while (ret == 0 && resp->result == QSEOS_RESULT_INCOMPLETE) { lstnr = resp->data; /* * Wake up blocking lsitener service with the lstnr id Loading @@ -2128,17 +2106,33 @@ static int __qseecom_reentrancy_process_incomplete_cmd( if (ptr_svc == NULL) { pr_err("Listener Svc %d does not exist\n", lstnr); return -EINVAL; rc = -EINVAL; status = QSEOS_RESULT_FAILURE; goto err_resp; } if (!ptr_svc->dmabuf) { pr_err("Client dmabuf is not initialized\n"); return -EINVAL; rc = -EINVAL; status = QSEOS_RESULT_FAILURE; goto err_resp; } if (ptr_svc->svc.listener_id != lstnr) { pr_warn("Service requested does not exist\n"); return -ERESTARTSYS; pr_err("Service %d does not exist\n", lstnr); rc = -ERESTARTSYS; ptr_svc = NULL; status = QSEOS_RESULT_FAILURE; goto err_resp; } if (ptr_svc->abort == 1) { pr_err("Service %d abort %d\n", lstnr, ptr_svc->abort); rc = -ENODEV; status = QSEOS_RESULT_FAILURE; goto err_resp; } pr_debug("waking up rcv_req_wq and waiting for send_resp_wq\n"); Loading @@ -2164,7 +2158,7 @@ static int __qseecom_reentrancy_process_incomplete_cmd( /* restore signal mask */ sigprocmask(SIG_SETMASK, &old_sigset, NULL); if (data->abort) { if (data->abort || ptr_svc->abort) { pr_err("Abort clnt %d waiting on lstnr svc %d, ret %d", data->client.app_id, lstnr, ret); rc = -ENODEV; Loading @@ -2172,6 +2166,7 @@ static int __qseecom_reentrancy_process_incomplete_cmd( } else { status = QSEOS_RESULT_SUCCESS; } err_resp: table = ptr_svc->sglistinfo_ptr; if (qseecom.qsee_version < QSEE_VERSION_40) { send_data_rsp.listener_id = lstnr; Loading Loading @@ -3907,7 +3902,7 @@ static int __qseecom_listener_has_rcvd_req(struct qseecom_dev_handle *data, int ret; ret = (svc->rcv_req_flag != 0); return ret || data->abort; return ret || data->abort || svc->abort; } static int qseecom_receive_req(struct qseecom_dev_handle *data) Loading @@ -3931,7 +3926,7 @@ static int qseecom_receive_req(struct qseecom_dev_handle *data) return -ERESTARTSYS; } if (data->abort) { if (data->abort || this_lstnr->abort) { pr_err("Aborting Listener Service = %d\n", (uint32_t)data->listener.id); return -ENODEV; Loading Loading @@ -6189,7 +6184,7 @@ static int qseecom_update_key_user_info(struct qseecom_dev_handle *data, } static int qseecom_is_es_activated(void __user *argp) { struct qseecom_is_es_activated_req req; struct qseecom_is_es_activated_req req = {0}; struct qseecom_command_scm_resp resp; int ret; Loading Loading @@ -7012,12 +7007,14 @@ static inline long qseecom_ioctl(struct file *file, break; } pr_debug("ioctl unregister_listener_req()\n"); __qseecom_listener_abort_all(1); mutex_lock(&app_access_lock); atomic_inc(&data->ioctl_count); ret = qseecom_unregister_listener(data); atomic_dec(&data->ioctl_count); wake_up_all(&data->abort_wq); mutex_unlock(&app_access_lock); __qseecom_listener_abort_all(0); if (ret) pr_err("failed qseecom_unregister_listener: %d\n", ret); break; Loading Loading @@ -7684,9 +7681,11 @@ static int qseecom_release(struct inode *inode, struct file *file) data->type, data->mode, data); switch (data->type) { case QSEECOM_LISTENER_SERVICE: __qseecom_listener_abort_all(1); mutex_lock(&app_access_lock); ret = qseecom_unregister_listener(data); mutex_unlock(&app_access_lock); __qseecom_listener_abort_all(0); break; case QSEECOM_CLIENT_APP: mutex_lock(&app_access_lock); Loading