Loading drivers/misc/qseecom.c +187 −135 Original line number Diff line number Diff line Loading @@ -131,6 +131,35 @@ static DEFINE_MUTEX(qsee_bw_mutex); static DEFINE_MUTEX(app_access_lock); static DEFINE_MUTEX(clk_access_lock); struct sglist_info { uint32_t indexAndFlags; uint32_t sizeOrCount; }; /* * The 31th bit indicates only one or multiple physical address inside * the request buffer. If it is set, the index locates a single physical addr * inside the request buffer, and `sizeOrCount` is the size of the memory being * shared at that physical address. * Otherwise, the index locates an array of {start, len} pairs (a * "scatter/gather list"), and `sizeOrCount` gives the number of entries in * that array. * * The 30th bit indicates 64 or 32bit address; when it is set, physical addr * and scatter gather entry sizes are 64-bit values. Otherwise, 32-bit values. * * The bits [0:29] of `indexAndFlags` hold an offset into the request buffer. */ #define SGLISTINFO_SET_INDEX_FLAG(c, s, i) \ ((uint32_t)(((c & 1) << 31) | ((s & 1) << 30) | (i & 0x3fffffff))) #define SGLISTINFO_TABLE_SIZE (sizeof(struct sglist_info) * MAX_ION_FD) #define FEATURE_ID_WHITELIST 15 /*whitelist feature id*/ #define MAKE_WHITELIST_VERSION(major, minor, patch) \ (((major & 0x3FF) << 22) | ((minor & 0x3FF) << 12) | (patch & 0xFFF)) struct qseecom_registered_listener_list { struct list_head list; struct qseecom_register_listener_req svc; Loading @@ -145,6 +174,8 @@ struct qseecom_registered_listener_list { bool listener_in_use; /* wq for thread blocked on this listener*/ wait_queue_head_t listener_block_app_wq; struct sglist_info sglistinfo_ptr[MAX_ION_FD]; uint32_t sglist_cnt; }; struct qseecom_registered_app_list { Loading Loading @@ -268,30 +299,6 @@ struct qseecom_listener_handle { static struct qseecom_control qseecom; struct sglist_info { uint32_t indexAndFlags; uint32_t sizeOrCount; }; /* * The 31th bit indicates only one or multiple physical address inside * the request buffer. If it is set, the index locates a single physical addr * inside the request buffer, and `sizeOrCount` is the size of the memory being * shared at that physical address. * Otherwise, the index locates an array of {start, len} pairs (a * "scatter/gather list"), and `sizeOrCount` gives the number of entries in * that array. * * The 30th bit indicates 64 or 32bit address; when it is set, physical addr * and scatter gather entry sizes are 64-bit values. Otherwise, 32-bit values. * * The bits [0:29] of `indexAndFlags` hold an offset into the request buffer. */ #define SGLISTINFO_SET_INDEX_FLAG(c, s, i) \ ((uint32_t)(((c & 1) << 31) | ((s & 1) << 30) | (i & 0x3fffffff))) #define SGLISTINFO_TABLE_SIZE (sizeof(struct sglist_info) * MAX_ION_FD) struct qseecom_dev_handle { enum qseecom_client_handle_type type; union { Loading @@ -305,8 +312,9 @@ struct qseecom_dev_handle { bool perf_enabled; bool fast_load_enabled; enum qseecom_bandwidth_request_mode mode; struct sglist_info *sglistinfo_ptr; struct sglist_info sglistinfo_ptr[MAX_ION_FD]; uint32_t sglist_cnt; bool use_legacy_cmd; }; struct qseecom_key_id_usage_desc { Loading Loading @@ -584,6 +592,34 @@ static int qseecom_scm_call2(uint32_t svc_id, uint32_t tz_cmd_id, ret = scm_call2(smc_id, &desc); break; } case QSEOS_LISTENER_DATA_RSP_COMMAND_WHITELIST: { struct qseecom_client_listener_data_irsp *req; struct qseecom_client_listener_data_64bit_irsp *req_64; smc_id = TZ_OS_LISTENER_RESPONSE_HANDLER_WITH_WHITELIST_ID; desc.arginfo = TZ_OS_LISTENER_RESPONSE_HANDLER_WITH_WHITELIST_PARAM_ID; if (qseecom.qsee_version < QSEE_VERSION_40) { req = (struct qseecom_client_listener_data_irsp *) req_buf; desc.args[0] = req->listener_id; desc.args[1] = req->status; desc.args[2] = req->sglistinfo_ptr; desc.args[3] = req->sglistinfo_len; } else { req_64 = (struct qseecom_client_listener_data_64bit_irsp *) req_buf; desc.args[0] = req_64->listener_id; desc.args[1] = req_64->status; desc.args[2] = req_64->sglistinfo_ptr; desc.args[3] = req_64->sglistinfo_len; } ret = scm_call2(smc_id, &desc); break; } case QSEOS_LOAD_EXTERNAL_ELF_COMMAND: { struct qseecom_load_app_ireq *req; struct qseecom_load_app_64bit_ireq *req_64bit; Loading Loading @@ -1128,7 +1164,7 @@ static int qseecom_register_listener(struct qseecom_dev_handle *data, return -EBUSY; } new_entry = kmalloc(sizeof(*new_entry), GFP_KERNEL); new_entry = kzalloc(sizeof(*new_entry), GFP_KERNEL); if (!new_entry) { pr_err("kmalloc failed\n"); return -ENOMEM; Loading Loading @@ -1593,6 +1629,16 @@ static int __qseecom_qseos_fail_return_resp_tz(struct qseecom_dev_handle *data, return ret; } static void __qseecom_clean_listener_sglistinfo( struct qseecom_registered_listener_list *ptr_svc) { if (ptr_svc->sglist_cnt) { memset(ptr_svc->sglistinfo_ptr, 0, SGLISTINFO_TABLE_SIZE); ptr_svc->sglist_cnt = 0; } } static int __qseecom_process_incomplete_cmd(struct qseecom_dev_handle *data, struct qseecom_command_scm_resp *resp) { Loading @@ -1601,9 +1647,14 @@ static int __qseecom_process_incomplete_cmd(struct qseecom_dev_handle *data, uint32_t lstnr; unsigned long flags; struct qseecom_client_listener_data_irsp send_data_rsp; struct qseecom_client_listener_data_64bit_irsp send_data_rsp_64bit; struct qseecom_registered_listener_list *ptr_svc = NULL; sigset_t new_sigset; sigset_t old_sigset; uint32_t status; void *cmd_buf = NULL; size_t cmd_len; struct sglist_info *table = NULL; while (resp->result == QSEOS_RESULT_INCOMPLETE) { lstnr = resp->data; Loading Loading @@ -1677,15 +1728,42 @@ static int __qseecom_process_incomplete_cmd(struct qseecom_dev_handle *data, pr_err("Abort clnt %d waiting on lstnr svc %d, ret %d", data->client.app_id, lstnr, ret); rc = -ENODEV; send_data_rsp.status = QSEOS_RESULT_FAILURE; status = QSEOS_RESULT_FAILURE; } else { send_data_rsp.status = QSEOS_RESULT_SUCCESS; status = QSEOS_RESULT_SUCCESS; } qseecom.send_resp_flag = 0; ptr_svc->send_resp_flag = 0; send_data_rsp.qsee_cmd_id = QSEOS_LISTENER_DATA_RSP_COMMAND; table = ptr_svc->sglistinfo_ptr; if (qseecom.qsee_version < QSEE_VERSION_40) { send_data_rsp.listener_id = lstnr; send_data_rsp.status = status; send_data_rsp.sglistinfo_ptr = (uint32_t)virt_to_phys(table); send_data_rsp.sglistinfo_len = SGLISTINFO_TABLE_SIZE; dmac_flush_range((void *)table, (void *)table + SGLISTINFO_TABLE_SIZE); cmd_buf = (void *)&send_data_rsp; cmd_len = sizeof(send_data_rsp); } else { send_data_rsp_64bit.listener_id = lstnr; send_data_rsp_64bit.status = status; send_data_rsp_64bit.sglistinfo_ptr = virt_to_phys(table); send_data_rsp_64bit.sglistinfo_len = SGLISTINFO_TABLE_SIZE; dmac_flush_range((void *)table, (void *)table + SGLISTINFO_TABLE_SIZE); cmd_buf = (void *)&send_data_rsp_64bit; cmd_len = sizeof(send_data_rsp_64bit); } if (qseecom.whitelist_support == false) *(uint32_t *)cmd_buf = QSEOS_LISTENER_DATA_RSP_COMMAND; else *(uint32_t *)cmd_buf = QSEOS_LISTENER_DATA_RSP_COMMAND_WHITELIST; if (ptr_svc) msm_ion_do_cache_op(qseecom.ion_clnt, ptr_svc->ihandle, ptr_svc->sb_virt, ptr_svc->sb_length, Loading @@ -1695,10 +1773,9 @@ static int __qseecom_process_incomplete_cmd(struct qseecom_dev_handle *data, __qseecom_enable_clk(CLK_QSEE); ret = qseecom_scm_call(SCM_SVC_TZSCHEDULER, 1, (const void *)&send_data_rsp, sizeof(send_data_rsp), resp, sizeof(*resp)); cmd_buf, cmd_len, resp, sizeof(*resp)); ptr_svc->listener_in_use = false; __qseecom_clean_listener_sglistinfo(ptr_svc); if (ret) { pr_err("scm_call() failed with err: %d (app_id = %d)\n", ret, data->client.app_id); Loading Loading @@ -1826,9 +1903,14 @@ static int __qseecom_reentrancy_process_incomplete_cmd( uint32_t lstnr = 0; unsigned long flags; struct qseecom_client_listener_data_irsp send_data_rsp; struct qseecom_client_listener_data_64bit_irsp send_data_rsp_64bit; struct qseecom_registered_listener_list *ptr_svc = NULL; sigset_t new_sigset; sigset_t old_sigset; uint32_t status; void *cmd_buf = NULL; size_t cmd_len; struct sglist_info *table = NULL; while (ret == 0 && rc == 0 && resp->result == QSEOS_RESULT_INCOMPLETE) { lstnr = resp->data; Loading Loading @@ -1891,13 +1973,38 @@ static int __qseecom_reentrancy_process_incomplete_cmd( pr_err("Abort clnt %d waiting on lstnr svc %d, ret %d", data->client.app_id, lstnr, ret); rc = -ENODEV; send_data_rsp.status = QSEOS_RESULT_FAILURE; status = QSEOS_RESULT_FAILURE; } else { send_data_rsp.status = QSEOS_RESULT_SUCCESS; status = QSEOS_RESULT_SUCCESS; } send_data_rsp.qsee_cmd_id = QSEOS_LISTENER_DATA_RSP_COMMAND; table = ptr_svc->sglistinfo_ptr; if (qseecom.qsee_version < QSEE_VERSION_40) { send_data_rsp.listener_id = lstnr; send_data_rsp.status = status; send_data_rsp.sglistinfo_ptr = (uint32_t)virt_to_phys(table); send_data_rsp.sglistinfo_len = SGLISTINFO_TABLE_SIZE; dmac_flush_range((void *)table, (void *)table + SGLISTINFO_TABLE_SIZE); cmd_buf = (void *)&send_data_rsp; cmd_len = sizeof(send_data_rsp); } else { send_data_rsp_64bit.listener_id = lstnr; send_data_rsp_64bit.status = status; send_data_rsp_64bit.sglistinfo_ptr = virt_to_phys(table); send_data_rsp_64bit.sglistinfo_len = SGLISTINFO_TABLE_SIZE; dmac_flush_range((void *)table, (void *)table + SGLISTINFO_TABLE_SIZE); cmd_buf = (void *)&send_data_rsp_64bit; cmd_len = sizeof(send_data_rsp_64bit); } if (qseecom.whitelist_support == false) *(uint32_t *)cmd_buf = QSEOS_LISTENER_DATA_RSP_COMMAND; else *(uint32_t *)cmd_buf = QSEOS_LISTENER_DATA_RSP_COMMAND_WHITELIST; if (ptr_svc) msm_ion_do_cache_op(qseecom.ion_clnt, ptr_svc->ihandle, ptr_svc->sb_virt, ptr_svc->sb_length, Loading @@ -1907,11 +2014,9 @@ static int __qseecom_reentrancy_process_incomplete_cmd( __qseecom_enable_clk(CLK_QSEE); ret = qseecom_scm_call(SCM_SVC_TZSCHEDULER, 1, (const void *)&send_data_rsp, sizeof(send_data_rsp), resp, sizeof(*resp)); cmd_buf, cmd_len, resp, sizeof(*resp)); ptr_svc->listener_in_use = false; __qseecom_clean_listener_sglistinfo(ptr_svc); wake_up_interruptible(&ptr_svc->listener_block_app_wq); if (ret) { Loading Loading @@ -2909,7 +3014,7 @@ static int __qseecom_send_cmd(struct qseecom_dev_handle *data, cmd_len = sizeof(struct qseecom_client_send_data_64bit_ireq); } if (qseecom.whitelist_support == false) if (qseecom.whitelist_support == false || data->use_legacy_cmd == true) *(uint32_t *)cmd_buf = QSEOS_CLIENT_SEND_DATA_COMMAND; else *(uint32_t *)cmd_buf = QSEOS_CLIENT_SEND_DATA_COMMAND_WHITELIST; Loading Loading @@ -3014,6 +3119,8 @@ static int __qseecom_update_cmd_buf(void *msg, bool cleanup, struct qseecom_send_modfd_cmd_req *req = NULL; struct qseecom_send_modfd_listener_resp *lstnr_resp = NULL; struct qseecom_registered_listener_list *this_lstnr = NULL; uint32_t offset; struct sg_table *sg_ptr; if ((data->type != QSEECOM_LISTENER_SERVICE) && (data->type != QSEECOM_CLIENT_APP)) Loading @@ -3035,7 +3142,6 @@ static int __qseecom_update_cmd_buf(void *msg, bool cleanup, } for (i = 0; i < MAX_ION_FD; i++) { struct sg_table *sg_ptr = NULL; if ((data->type != QSEECOM_LISTENER_SERVICE) && (req->ifd_data[i].fd > 0)) { ihandle = ion_import_dma_buf(qseecom.ion_clnt, Loading Loading @@ -3177,14 +3283,25 @@ static int __qseecom_update_cmd_buf(void *msg, bool cleanup, ihandle, NULL, len, ION_IOC_CLEAN_INV_CACHES); if (data->type == QSEECOM_CLIENT_APP) { offset = req->ifd_data[i].cmd_buf_offset; data->sglistinfo_ptr[i].indexAndFlags = SGLISTINFO_SET_INDEX_FLAG( (sg_ptr->nents == 1), 0, req->ifd_data[i].cmd_buf_offset); (sg_ptr->nents == 1), 0, offset); data->sglistinfo_ptr[i].sizeOrCount = (sg_ptr->nents == 1) ? sg->length : sg_ptr->nents; data->sglist_cnt = i + 1; } else { offset = (lstnr_resp->ifd_data[i].cmd_buf_offset + (uintptr_t)lstnr_resp->resp_buf_ptr - (uintptr_t)this_lstnr->sb_virt); this_lstnr->sglistinfo_ptr[i].indexAndFlags = SGLISTINFO_SET_INDEX_FLAG( (sg_ptr->nents == 1), 0, offset); this_lstnr->sglistinfo_ptr[i].sizeOrCount = (sg_ptr->nents == 1) ? sg->length : sg_ptr->nents; this_lstnr->sglist_cnt = i + 1; } } /* Deallocate the handle */ Loading Loading @@ -3257,6 +3374,8 @@ static int __qseecom_update_cmd_buf_64(void *msg, bool cleanup, struct qseecom_send_modfd_cmd_req *req = NULL; struct qseecom_send_modfd_listener_resp *lstnr_resp = NULL; struct qseecom_registered_listener_list *this_lstnr = NULL; uint32_t offset; struct sg_table *sg_ptr; if ((data->type != QSEECOM_LISTENER_SERVICE) && (data->type != QSEECOM_CLIENT_APP)) Loading @@ -3278,7 +3397,6 @@ static int __qseecom_update_cmd_buf_64(void *msg, bool cleanup, } for (i = 0; i < MAX_ION_FD; i++) { struct sg_table *sg_ptr = NULL; if ((data->type != QSEECOM_LISTENER_SERVICE) && (req->ifd_data[i].fd > 0)) { ihandle = ion_import_dma_buf(qseecom.ion_clnt, Loading Loading @@ -3395,14 +3513,25 @@ cleanup: ihandle, NULL, len, ION_IOC_CLEAN_INV_CACHES); if (data->type == QSEECOM_CLIENT_APP) { offset = req->ifd_data[i].cmd_buf_offset; data->sglistinfo_ptr[i].indexAndFlags = SGLISTINFO_SET_INDEX_FLAG( (sg_ptr->nents == 1), 1, req->ifd_data[i].cmd_buf_offset); (sg_ptr->nents == 1), 1, offset); data->sglistinfo_ptr[i].sizeOrCount = (sg_ptr->nents == 1) ? sg->length : sg_ptr->nents; data->sglist_cnt = i + 1; } else { offset = (lstnr_resp->ifd_data[i].cmd_buf_offset + (uintptr_t)lstnr_resp->resp_buf_ptr - (uintptr_t)this_lstnr->sb_virt); this_lstnr->sglistinfo_ptr[i].indexAndFlags = SGLISTINFO_SET_INDEX_FLAG( (sg_ptr->nents == 1), 1, offset); this_lstnr->sglistinfo_ptr[i].sizeOrCount = (sg_ptr->nents == 1) ? sg->length : sg_ptr->nents; this_lstnr->sglist_cnt = i + 1; } } /* Deallocate the handle */ Loading Loading @@ -4121,21 +4250,12 @@ int qseecom_start_app(struct qseecom_handle **handle, data->client.user_virt_sb_base = 0; data->client.ihandle = NULL; /* Allocate sglistinfo buffer for kernel client */ data->sglistinfo_ptr = kzalloc(SGLISTINFO_TABLE_SIZE, GFP_KERNEL); if (!(data->sglistinfo_ptr)) { kfree(data); kfree(*handle); *handle = NULL; return -ENOMEM; } init_waitqueue_head(&data->abort_wq); data->client.ihandle = ion_alloc(qseecom.ion_clnt, size, 4096, ION_HEAP(ION_QSECOM_HEAP_ID), 0); if (IS_ERR_OR_NULL(data->client.ihandle)) { pr_err("Ion client could not retrieve the handle\n"); kfree(data->sglistinfo_ptr); kfree(data); kfree(*handle); *handle = NULL; Loading Loading @@ -4238,7 +4358,6 @@ int qseecom_start_app(struct qseecom_handle **handle, return 0; err: kfree(data->sglistinfo_ptr); kfree(data); kfree(*handle); *handle = NULL; Loading Loading @@ -4286,7 +4405,6 @@ int qseecom_shutdown_app(struct qseecom_handle **handle) mutex_unlock(&app_access_lock); if (ret == 0) { kzfree(data->sglistinfo_ptr); kzfree(data); kzfree(*handle); kzfree(kclient); Loading Loading @@ -4352,8 +4470,11 @@ int qseecom_send_command(struct qseecom_handle *handle, void *send_buf, } perf_enabled = true; } if (!strcmp(data->client.app_name, "securemm")) data->use_legacy_cmd = true; ret = __qseecom_send_cmd(data, &req); data->use_legacy_cmd = false; if (qseecom.support_bus_scaling) __qseecom_add_bw_scale_down_timer( QSEECOM_SEND_CMD_CRYPTO_TIMEOUT); Loading Loading @@ -7025,6 +7146,7 @@ long qseecom_ioctl(struct file *file, unsigned cmd, unsigned long arg) wake_up_all(&data->abort_wq); if (ret) pr_err("failed qseecom_send_mod_resp: %d\n", ret); __qseecom_clean_data_sglistinfo(data); break; } case QSEECOM_QTEEC_IOCTL_OPEN_SESSION_REQ: { Loading Loading @@ -7174,12 +7296,6 @@ static int qseecom_open(struct inode *inode, struct file *file) data->mode = INACTIVE; init_waitqueue_head(&data->abort_wq); atomic_set(&data->ioctl_count, 0); data->sglistinfo_ptr = kzalloc(SGLISTINFO_TABLE_SIZE, GFP_KERNEL); if (!(data->sglistinfo_ptr)) { kzfree(data); return -ENOMEM; } return ret; } Loading Loading @@ -7234,7 +7350,6 @@ static int qseecom_release(struct inode *inode, struct file *file) if (data->perf_enabled == true) qsee_disable_clock_vote(data, CLK_DFAB); } kfree(data->sglistinfo_ptr); kfree(data); return ret; Loading Loading @@ -7983,73 +8098,14 @@ out: } /* * Check if whitelist feature is supported by making a test scm_call * to send a whitelist command to an invalid app ID 0 * Check whitelist feature, and if TZ feature version is < 1.0.0, * then whitelist feature is not supported. */ static int qseecom_check_whitelist_feature(void) { struct qseecom_client_send_data_ireq send_data_req = {0}; struct qseecom_client_send_data_64bit_ireq send_data_req_64bit = {0}; struct qseecom_command_scm_resp resp; uint32_t buf_size = 128; void *buf = NULL; void *cmd_buf = NULL; size_t cmd_len; int ret = 0; phys_addr_t pa; int version = scm_get_feat_version(FEATURE_ID_WHITELIST); buf = kzalloc(buf_size, GFP_KERNEL); if (!buf) return -ENOMEM; pa = virt_to_phys(buf); if (qseecom.qsee_version < QSEE_VERSION_40) { send_data_req.qsee_cmd_id = QSEOS_CLIENT_SEND_DATA_COMMAND_WHITELIST; send_data_req.app_id = 0; send_data_req.req_ptr = (uint32_t)pa; send_data_req.req_len = buf_size; send_data_req.rsp_ptr = (uint32_t)pa; send_data_req.rsp_len = buf_size; send_data_req.sglistinfo_ptr = (uint32_t)pa; send_data_req.sglistinfo_len = buf_size; cmd_buf = (void *)&send_data_req; cmd_len = sizeof(struct qseecom_client_send_data_ireq); } else { send_data_req_64bit.qsee_cmd_id = QSEOS_CLIENT_SEND_DATA_COMMAND_WHITELIST; send_data_req_64bit.app_id = 0; send_data_req_64bit.req_ptr = (uint64_t)pa; send_data_req_64bit.req_len = buf_size; send_data_req_64bit.rsp_ptr = (uint64_t)pa; send_data_req_64bit.rsp_len = buf_size; send_data_req_64bit.sglistinfo_ptr = (uint64_t)pa; send_data_req_64bit.sglistinfo_len = buf_size; cmd_buf = (void *)&send_data_req_64bit; cmd_len = sizeof(struct qseecom_client_send_data_64bit_ireq); } ret = qseecom_scm_call(SCM_SVC_TZSCHEDULER, 1, cmd_buf, cmd_len, &resp, sizeof(resp)); /* * If this cmd exists and whitelist is supported, scm_call return -2 (scm * driver remap it to -EINVAL) and resp.result 0xFFFFFFED(-19); Otherwise, * scm_call return -1 (remap to -EIO). */ if (ret == -EIO) { qseecom.whitelist_support = false; ret = 0; } else if (ret == -EINVAL && resp.result == QSEOS_RESULT_FAIL_SEND_CMD_NO_THREAD) { qseecom.whitelist_support = true; ret = 0; } else { pr_info("Check whitelist with ret = %d, result = 0x%x\n", ret, resp.result); qseecom.whitelist_support = false; ret = 0; } kfree(buf); return ret; return version >= MAKE_WHITELIST_VERSION(1, 0, 0); } static int qseecom_probe(struct platform_device *pdev) Loading Loading @@ -8300,11 +8356,7 @@ static int qseecom_probe(struct platform_device *pdev) qseecom.qsee_perf_client = msm_bus_scale_register_client( qseecom_platform_support); rc = qseecom_check_whitelist_feature(); if (rc) { rc = -EINVAL; goto exit_destroy_ion_client; } qseecom.whitelist_support = qseecom_check_whitelist_feature(); pr_warn("qseecom.whitelist_support = %d\n", qseecom.whitelist_support); Loading include/soc/qcom/qseecomi.h +19 −0 Original line number Diff line number Diff line Loading @@ -68,6 +68,7 @@ enum qseecom_qceos_cmd_id { QSEOS_CLIENT_SEND_DATA_COMMAND_WHITELIST = 0x1C, QSEOS_TEE_OPEN_SESSION_WHITELIST = 0x1D, QSEOS_TEE_INVOKE_COMMAND_WHITELIST = 0x1E, QSEOS_LISTENER_DATA_RSP_COMMAND_WHITELIST = 0x1F, QSEOS_FSM_LTEOTA_REQ_CMD = 0x109, QSEOS_FSM_LTEOTA_REQ_RSP_CMD = 0x110, QSEOS_FSM_IKE_REQ_CMD = 0x203, Loading Loading @@ -217,6 +218,16 @@ __packed struct qseecom_client_listener_data_irsp { uint32_t qsee_cmd_id; uint32_t listener_id; uint32_t status; uint32_t sglistinfo_ptr; uint32_t sglistinfo_len; }; __packed struct qseecom_client_listener_data_64bit_irsp { uint32_t qsee_cmd_id; uint32_t listener_id; uint32_t status; uint64_t sglistinfo_ptr; uint32_t sglistinfo_len; }; /* Loading Loading @@ -703,4 +714,12 @@ __packed struct qseecom_continue_blocked_request_ireq { TZ_SYSCALL_PARAM_TYPE_VAL, TZ_SYSCALL_PARAM_TYPE_BUF_RW, \ TZ_SYSCALL_PARAM_TYPE_VAL) #define TZ_OS_LISTENER_RESPONSE_HANDLER_WITH_WHITELIST_ID \ TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_QSEE_OS, TZ_SVC_LISTENER, 0x05) #define TZ_OS_LISTENER_RESPONSE_HANDLER_WITH_WHITELIST_PARAM_ID \ TZ_SYSCALL_CREATE_PARAM_ID_4( \ TZ_SYSCALL_PARAM_TYPE_VAL, TZ_SYSCALL_PARAM_TYPE_VAL, \ TZ_SYSCALL_PARAM_TYPE_BUF_RW, TZ_SYSCALL_PARAM_TYPE_VAL) #endif /* __QSEECOMI_H_ */ Loading
drivers/misc/qseecom.c +187 −135 Original line number Diff line number Diff line Loading @@ -131,6 +131,35 @@ static DEFINE_MUTEX(qsee_bw_mutex); static DEFINE_MUTEX(app_access_lock); static DEFINE_MUTEX(clk_access_lock); struct sglist_info { uint32_t indexAndFlags; uint32_t sizeOrCount; }; /* * The 31th bit indicates only one or multiple physical address inside * the request buffer. If it is set, the index locates a single physical addr * inside the request buffer, and `sizeOrCount` is the size of the memory being * shared at that physical address. * Otherwise, the index locates an array of {start, len} pairs (a * "scatter/gather list"), and `sizeOrCount` gives the number of entries in * that array. * * The 30th bit indicates 64 or 32bit address; when it is set, physical addr * and scatter gather entry sizes are 64-bit values. Otherwise, 32-bit values. * * The bits [0:29] of `indexAndFlags` hold an offset into the request buffer. */ #define SGLISTINFO_SET_INDEX_FLAG(c, s, i) \ ((uint32_t)(((c & 1) << 31) | ((s & 1) << 30) | (i & 0x3fffffff))) #define SGLISTINFO_TABLE_SIZE (sizeof(struct sglist_info) * MAX_ION_FD) #define FEATURE_ID_WHITELIST 15 /*whitelist feature id*/ #define MAKE_WHITELIST_VERSION(major, minor, patch) \ (((major & 0x3FF) << 22) | ((minor & 0x3FF) << 12) | (patch & 0xFFF)) struct qseecom_registered_listener_list { struct list_head list; struct qseecom_register_listener_req svc; Loading @@ -145,6 +174,8 @@ struct qseecom_registered_listener_list { bool listener_in_use; /* wq for thread blocked on this listener*/ wait_queue_head_t listener_block_app_wq; struct sglist_info sglistinfo_ptr[MAX_ION_FD]; uint32_t sglist_cnt; }; struct qseecom_registered_app_list { Loading Loading @@ -268,30 +299,6 @@ struct qseecom_listener_handle { static struct qseecom_control qseecom; struct sglist_info { uint32_t indexAndFlags; uint32_t sizeOrCount; }; /* * The 31th bit indicates only one or multiple physical address inside * the request buffer. If it is set, the index locates a single physical addr * inside the request buffer, and `sizeOrCount` is the size of the memory being * shared at that physical address. * Otherwise, the index locates an array of {start, len} pairs (a * "scatter/gather list"), and `sizeOrCount` gives the number of entries in * that array. * * The 30th bit indicates 64 or 32bit address; when it is set, physical addr * and scatter gather entry sizes are 64-bit values. Otherwise, 32-bit values. * * The bits [0:29] of `indexAndFlags` hold an offset into the request buffer. */ #define SGLISTINFO_SET_INDEX_FLAG(c, s, i) \ ((uint32_t)(((c & 1) << 31) | ((s & 1) << 30) | (i & 0x3fffffff))) #define SGLISTINFO_TABLE_SIZE (sizeof(struct sglist_info) * MAX_ION_FD) struct qseecom_dev_handle { enum qseecom_client_handle_type type; union { Loading @@ -305,8 +312,9 @@ struct qseecom_dev_handle { bool perf_enabled; bool fast_load_enabled; enum qseecom_bandwidth_request_mode mode; struct sglist_info *sglistinfo_ptr; struct sglist_info sglistinfo_ptr[MAX_ION_FD]; uint32_t sglist_cnt; bool use_legacy_cmd; }; struct qseecom_key_id_usage_desc { Loading Loading @@ -584,6 +592,34 @@ static int qseecom_scm_call2(uint32_t svc_id, uint32_t tz_cmd_id, ret = scm_call2(smc_id, &desc); break; } case QSEOS_LISTENER_DATA_RSP_COMMAND_WHITELIST: { struct qseecom_client_listener_data_irsp *req; struct qseecom_client_listener_data_64bit_irsp *req_64; smc_id = TZ_OS_LISTENER_RESPONSE_HANDLER_WITH_WHITELIST_ID; desc.arginfo = TZ_OS_LISTENER_RESPONSE_HANDLER_WITH_WHITELIST_PARAM_ID; if (qseecom.qsee_version < QSEE_VERSION_40) { req = (struct qseecom_client_listener_data_irsp *) req_buf; desc.args[0] = req->listener_id; desc.args[1] = req->status; desc.args[2] = req->sglistinfo_ptr; desc.args[3] = req->sglistinfo_len; } else { req_64 = (struct qseecom_client_listener_data_64bit_irsp *) req_buf; desc.args[0] = req_64->listener_id; desc.args[1] = req_64->status; desc.args[2] = req_64->sglistinfo_ptr; desc.args[3] = req_64->sglistinfo_len; } ret = scm_call2(smc_id, &desc); break; } case QSEOS_LOAD_EXTERNAL_ELF_COMMAND: { struct qseecom_load_app_ireq *req; struct qseecom_load_app_64bit_ireq *req_64bit; Loading Loading @@ -1128,7 +1164,7 @@ static int qseecom_register_listener(struct qseecom_dev_handle *data, return -EBUSY; } new_entry = kmalloc(sizeof(*new_entry), GFP_KERNEL); new_entry = kzalloc(sizeof(*new_entry), GFP_KERNEL); if (!new_entry) { pr_err("kmalloc failed\n"); return -ENOMEM; Loading Loading @@ -1593,6 +1629,16 @@ static int __qseecom_qseos_fail_return_resp_tz(struct qseecom_dev_handle *data, return ret; } static void __qseecom_clean_listener_sglistinfo( struct qseecom_registered_listener_list *ptr_svc) { if (ptr_svc->sglist_cnt) { memset(ptr_svc->sglistinfo_ptr, 0, SGLISTINFO_TABLE_SIZE); ptr_svc->sglist_cnt = 0; } } static int __qseecom_process_incomplete_cmd(struct qseecom_dev_handle *data, struct qseecom_command_scm_resp *resp) { Loading @@ -1601,9 +1647,14 @@ static int __qseecom_process_incomplete_cmd(struct qseecom_dev_handle *data, uint32_t lstnr; unsigned long flags; struct qseecom_client_listener_data_irsp send_data_rsp; struct qseecom_client_listener_data_64bit_irsp send_data_rsp_64bit; struct qseecom_registered_listener_list *ptr_svc = NULL; sigset_t new_sigset; sigset_t old_sigset; uint32_t status; void *cmd_buf = NULL; size_t cmd_len; struct sglist_info *table = NULL; while (resp->result == QSEOS_RESULT_INCOMPLETE) { lstnr = resp->data; Loading Loading @@ -1677,15 +1728,42 @@ static int __qseecom_process_incomplete_cmd(struct qseecom_dev_handle *data, pr_err("Abort clnt %d waiting on lstnr svc %d, ret %d", data->client.app_id, lstnr, ret); rc = -ENODEV; send_data_rsp.status = QSEOS_RESULT_FAILURE; status = QSEOS_RESULT_FAILURE; } else { send_data_rsp.status = QSEOS_RESULT_SUCCESS; status = QSEOS_RESULT_SUCCESS; } qseecom.send_resp_flag = 0; ptr_svc->send_resp_flag = 0; send_data_rsp.qsee_cmd_id = QSEOS_LISTENER_DATA_RSP_COMMAND; table = ptr_svc->sglistinfo_ptr; if (qseecom.qsee_version < QSEE_VERSION_40) { send_data_rsp.listener_id = lstnr; send_data_rsp.status = status; send_data_rsp.sglistinfo_ptr = (uint32_t)virt_to_phys(table); send_data_rsp.sglistinfo_len = SGLISTINFO_TABLE_SIZE; dmac_flush_range((void *)table, (void *)table + SGLISTINFO_TABLE_SIZE); cmd_buf = (void *)&send_data_rsp; cmd_len = sizeof(send_data_rsp); } else { send_data_rsp_64bit.listener_id = lstnr; send_data_rsp_64bit.status = status; send_data_rsp_64bit.sglistinfo_ptr = virt_to_phys(table); send_data_rsp_64bit.sglistinfo_len = SGLISTINFO_TABLE_SIZE; dmac_flush_range((void *)table, (void *)table + SGLISTINFO_TABLE_SIZE); cmd_buf = (void *)&send_data_rsp_64bit; cmd_len = sizeof(send_data_rsp_64bit); } if (qseecom.whitelist_support == false) *(uint32_t *)cmd_buf = QSEOS_LISTENER_DATA_RSP_COMMAND; else *(uint32_t *)cmd_buf = QSEOS_LISTENER_DATA_RSP_COMMAND_WHITELIST; if (ptr_svc) msm_ion_do_cache_op(qseecom.ion_clnt, ptr_svc->ihandle, ptr_svc->sb_virt, ptr_svc->sb_length, Loading @@ -1695,10 +1773,9 @@ static int __qseecom_process_incomplete_cmd(struct qseecom_dev_handle *data, __qseecom_enable_clk(CLK_QSEE); ret = qseecom_scm_call(SCM_SVC_TZSCHEDULER, 1, (const void *)&send_data_rsp, sizeof(send_data_rsp), resp, sizeof(*resp)); cmd_buf, cmd_len, resp, sizeof(*resp)); ptr_svc->listener_in_use = false; __qseecom_clean_listener_sglistinfo(ptr_svc); if (ret) { pr_err("scm_call() failed with err: %d (app_id = %d)\n", ret, data->client.app_id); Loading Loading @@ -1826,9 +1903,14 @@ static int __qseecom_reentrancy_process_incomplete_cmd( uint32_t lstnr = 0; unsigned long flags; struct qseecom_client_listener_data_irsp send_data_rsp; struct qseecom_client_listener_data_64bit_irsp send_data_rsp_64bit; struct qseecom_registered_listener_list *ptr_svc = NULL; sigset_t new_sigset; sigset_t old_sigset; uint32_t status; void *cmd_buf = NULL; size_t cmd_len; struct sglist_info *table = NULL; while (ret == 0 && rc == 0 && resp->result == QSEOS_RESULT_INCOMPLETE) { lstnr = resp->data; Loading Loading @@ -1891,13 +1973,38 @@ static int __qseecom_reentrancy_process_incomplete_cmd( pr_err("Abort clnt %d waiting on lstnr svc %d, ret %d", data->client.app_id, lstnr, ret); rc = -ENODEV; send_data_rsp.status = QSEOS_RESULT_FAILURE; status = QSEOS_RESULT_FAILURE; } else { send_data_rsp.status = QSEOS_RESULT_SUCCESS; status = QSEOS_RESULT_SUCCESS; } send_data_rsp.qsee_cmd_id = QSEOS_LISTENER_DATA_RSP_COMMAND; table = ptr_svc->sglistinfo_ptr; if (qseecom.qsee_version < QSEE_VERSION_40) { send_data_rsp.listener_id = lstnr; send_data_rsp.status = status; send_data_rsp.sglistinfo_ptr = (uint32_t)virt_to_phys(table); send_data_rsp.sglistinfo_len = SGLISTINFO_TABLE_SIZE; dmac_flush_range((void *)table, (void *)table + SGLISTINFO_TABLE_SIZE); cmd_buf = (void *)&send_data_rsp; cmd_len = sizeof(send_data_rsp); } else { send_data_rsp_64bit.listener_id = lstnr; send_data_rsp_64bit.status = status; send_data_rsp_64bit.sglistinfo_ptr = virt_to_phys(table); send_data_rsp_64bit.sglistinfo_len = SGLISTINFO_TABLE_SIZE; dmac_flush_range((void *)table, (void *)table + SGLISTINFO_TABLE_SIZE); cmd_buf = (void *)&send_data_rsp_64bit; cmd_len = sizeof(send_data_rsp_64bit); } if (qseecom.whitelist_support == false) *(uint32_t *)cmd_buf = QSEOS_LISTENER_DATA_RSP_COMMAND; else *(uint32_t *)cmd_buf = QSEOS_LISTENER_DATA_RSP_COMMAND_WHITELIST; if (ptr_svc) msm_ion_do_cache_op(qseecom.ion_clnt, ptr_svc->ihandle, ptr_svc->sb_virt, ptr_svc->sb_length, Loading @@ -1907,11 +2014,9 @@ static int __qseecom_reentrancy_process_incomplete_cmd( __qseecom_enable_clk(CLK_QSEE); ret = qseecom_scm_call(SCM_SVC_TZSCHEDULER, 1, (const void *)&send_data_rsp, sizeof(send_data_rsp), resp, sizeof(*resp)); cmd_buf, cmd_len, resp, sizeof(*resp)); ptr_svc->listener_in_use = false; __qseecom_clean_listener_sglistinfo(ptr_svc); wake_up_interruptible(&ptr_svc->listener_block_app_wq); if (ret) { Loading Loading @@ -2909,7 +3014,7 @@ static int __qseecom_send_cmd(struct qseecom_dev_handle *data, cmd_len = sizeof(struct qseecom_client_send_data_64bit_ireq); } if (qseecom.whitelist_support == false) if (qseecom.whitelist_support == false || data->use_legacy_cmd == true) *(uint32_t *)cmd_buf = QSEOS_CLIENT_SEND_DATA_COMMAND; else *(uint32_t *)cmd_buf = QSEOS_CLIENT_SEND_DATA_COMMAND_WHITELIST; Loading Loading @@ -3014,6 +3119,8 @@ static int __qseecom_update_cmd_buf(void *msg, bool cleanup, struct qseecom_send_modfd_cmd_req *req = NULL; struct qseecom_send_modfd_listener_resp *lstnr_resp = NULL; struct qseecom_registered_listener_list *this_lstnr = NULL; uint32_t offset; struct sg_table *sg_ptr; if ((data->type != QSEECOM_LISTENER_SERVICE) && (data->type != QSEECOM_CLIENT_APP)) Loading @@ -3035,7 +3142,6 @@ static int __qseecom_update_cmd_buf(void *msg, bool cleanup, } for (i = 0; i < MAX_ION_FD; i++) { struct sg_table *sg_ptr = NULL; if ((data->type != QSEECOM_LISTENER_SERVICE) && (req->ifd_data[i].fd > 0)) { ihandle = ion_import_dma_buf(qseecom.ion_clnt, Loading Loading @@ -3177,14 +3283,25 @@ static int __qseecom_update_cmd_buf(void *msg, bool cleanup, ihandle, NULL, len, ION_IOC_CLEAN_INV_CACHES); if (data->type == QSEECOM_CLIENT_APP) { offset = req->ifd_data[i].cmd_buf_offset; data->sglistinfo_ptr[i].indexAndFlags = SGLISTINFO_SET_INDEX_FLAG( (sg_ptr->nents == 1), 0, req->ifd_data[i].cmd_buf_offset); (sg_ptr->nents == 1), 0, offset); data->sglistinfo_ptr[i].sizeOrCount = (sg_ptr->nents == 1) ? sg->length : sg_ptr->nents; data->sglist_cnt = i + 1; } else { offset = (lstnr_resp->ifd_data[i].cmd_buf_offset + (uintptr_t)lstnr_resp->resp_buf_ptr - (uintptr_t)this_lstnr->sb_virt); this_lstnr->sglistinfo_ptr[i].indexAndFlags = SGLISTINFO_SET_INDEX_FLAG( (sg_ptr->nents == 1), 0, offset); this_lstnr->sglistinfo_ptr[i].sizeOrCount = (sg_ptr->nents == 1) ? sg->length : sg_ptr->nents; this_lstnr->sglist_cnt = i + 1; } } /* Deallocate the handle */ Loading Loading @@ -3257,6 +3374,8 @@ static int __qseecom_update_cmd_buf_64(void *msg, bool cleanup, struct qseecom_send_modfd_cmd_req *req = NULL; struct qseecom_send_modfd_listener_resp *lstnr_resp = NULL; struct qseecom_registered_listener_list *this_lstnr = NULL; uint32_t offset; struct sg_table *sg_ptr; if ((data->type != QSEECOM_LISTENER_SERVICE) && (data->type != QSEECOM_CLIENT_APP)) Loading @@ -3278,7 +3397,6 @@ static int __qseecom_update_cmd_buf_64(void *msg, bool cleanup, } for (i = 0; i < MAX_ION_FD; i++) { struct sg_table *sg_ptr = NULL; if ((data->type != QSEECOM_LISTENER_SERVICE) && (req->ifd_data[i].fd > 0)) { ihandle = ion_import_dma_buf(qseecom.ion_clnt, Loading Loading @@ -3395,14 +3513,25 @@ cleanup: ihandle, NULL, len, ION_IOC_CLEAN_INV_CACHES); if (data->type == QSEECOM_CLIENT_APP) { offset = req->ifd_data[i].cmd_buf_offset; data->sglistinfo_ptr[i].indexAndFlags = SGLISTINFO_SET_INDEX_FLAG( (sg_ptr->nents == 1), 1, req->ifd_data[i].cmd_buf_offset); (sg_ptr->nents == 1), 1, offset); data->sglistinfo_ptr[i].sizeOrCount = (sg_ptr->nents == 1) ? sg->length : sg_ptr->nents; data->sglist_cnt = i + 1; } else { offset = (lstnr_resp->ifd_data[i].cmd_buf_offset + (uintptr_t)lstnr_resp->resp_buf_ptr - (uintptr_t)this_lstnr->sb_virt); this_lstnr->sglistinfo_ptr[i].indexAndFlags = SGLISTINFO_SET_INDEX_FLAG( (sg_ptr->nents == 1), 1, offset); this_lstnr->sglistinfo_ptr[i].sizeOrCount = (sg_ptr->nents == 1) ? sg->length : sg_ptr->nents; this_lstnr->sglist_cnt = i + 1; } } /* Deallocate the handle */ Loading Loading @@ -4121,21 +4250,12 @@ int qseecom_start_app(struct qseecom_handle **handle, data->client.user_virt_sb_base = 0; data->client.ihandle = NULL; /* Allocate sglistinfo buffer for kernel client */ data->sglistinfo_ptr = kzalloc(SGLISTINFO_TABLE_SIZE, GFP_KERNEL); if (!(data->sglistinfo_ptr)) { kfree(data); kfree(*handle); *handle = NULL; return -ENOMEM; } init_waitqueue_head(&data->abort_wq); data->client.ihandle = ion_alloc(qseecom.ion_clnt, size, 4096, ION_HEAP(ION_QSECOM_HEAP_ID), 0); if (IS_ERR_OR_NULL(data->client.ihandle)) { pr_err("Ion client could not retrieve the handle\n"); kfree(data->sglistinfo_ptr); kfree(data); kfree(*handle); *handle = NULL; Loading Loading @@ -4238,7 +4358,6 @@ int qseecom_start_app(struct qseecom_handle **handle, return 0; err: kfree(data->sglistinfo_ptr); kfree(data); kfree(*handle); *handle = NULL; Loading Loading @@ -4286,7 +4405,6 @@ int qseecom_shutdown_app(struct qseecom_handle **handle) mutex_unlock(&app_access_lock); if (ret == 0) { kzfree(data->sglistinfo_ptr); kzfree(data); kzfree(*handle); kzfree(kclient); Loading Loading @@ -4352,8 +4470,11 @@ int qseecom_send_command(struct qseecom_handle *handle, void *send_buf, } perf_enabled = true; } if (!strcmp(data->client.app_name, "securemm")) data->use_legacy_cmd = true; ret = __qseecom_send_cmd(data, &req); data->use_legacy_cmd = false; if (qseecom.support_bus_scaling) __qseecom_add_bw_scale_down_timer( QSEECOM_SEND_CMD_CRYPTO_TIMEOUT); Loading Loading @@ -7025,6 +7146,7 @@ long qseecom_ioctl(struct file *file, unsigned cmd, unsigned long arg) wake_up_all(&data->abort_wq); if (ret) pr_err("failed qseecom_send_mod_resp: %d\n", ret); __qseecom_clean_data_sglistinfo(data); break; } case QSEECOM_QTEEC_IOCTL_OPEN_SESSION_REQ: { Loading Loading @@ -7174,12 +7296,6 @@ static int qseecom_open(struct inode *inode, struct file *file) data->mode = INACTIVE; init_waitqueue_head(&data->abort_wq); atomic_set(&data->ioctl_count, 0); data->sglistinfo_ptr = kzalloc(SGLISTINFO_TABLE_SIZE, GFP_KERNEL); if (!(data->sglistinfo_ptr)) { kzfree(data); return -ENOMEM; } return ret; } Loading Loading @@ -7234,7 +7350,6 @@ static int qseecom_release(struct inode *inode, struct file *file) if (data->perf_enabled == true) qsee_disable_clock_vote(data, CLK_DFAB); } kfree(data->sglistinfo_ptr); kfree(data); return ret; Loading Loading @@ -7983,73 +8098,14 @@ out: } /* * Check if whitelist feature is supported by making a test scm_call * to send a whitelist command to an invalid app ID 0 * Check whitelist feature, and if TZ feature version is < 1.0.0, * then whitelist feature is not supported. */ static int qseecom_check_whitelist_feature(void) { struct qseecom_client_send_data_ireq send_data_req = {0}; struct qseecom_client_send_data_64bit_ireq send_data_req_64bit = {0}; struct qseecom_command_scm_resp resp; uint32_t buf_size = 128; void *buf = NULL; void *cmd_buf = NULL; size_t cmd_len; int ret = 0; phys_addr_t pa; int version = scm_get_feat_version(FEATURE_ID_WHITELIST); buf = kzalloc(buf_size, GFP_KERNEL); if (!buf) return -ENOMEM; pa = virt_to_phys(buf); if (qseecom.qsee_version < QSEE_VERSION_40) { send_data_req.qsee_cmd_id = QSEOS_CLIENT_SEND_DATA_COMMAND_WHITELIST; send_data_req.app_id = 0; send_data_req.req_ptr = (uint32_t)pa; send_data_req.req_len = buf_size; send_data_req.rsp_ptr = (uint32_t)pa; send_data_req.rsp_len = buf_size; send_data_req.sglistinfo_ptr = (uint32_t)pa; send_data_req.sglistinfo_len = buf_size; cmd_buf = (void *)&send_data_req; cmd_len = sizeof(struct qseecom_client_send_data_ireq); } else { send_data_req_64bit.qsee_cmd_id = QSEOS_CLIENT_SEND_DATA_COMMAND_WHITELIST; send_data_req_64bit.app_id = 0; send_data_req_64bit.req_ptr = (uint64_t)pa; send_data_req_64bit.req_len = buf_size; send_data_req_64bit.rsp_ptr = (uint64_t)pa; send_data_req_64bit.rsp_len = buf_size; send_data_req_64bit.sglistinfo_ptr = (uint64_t)pa; send_data_req_64bit.sglistinfo_len = buf_size; cmd_buf = (void *)&send_data_req_64bit; cmd_len = sizeof(struct qseecom_client_send_data_64bit_ireq); } ret = qseecom_scm_call(SCM_SVC_TZSCHEDULER, 1, cmd_buf, cmd_len, &resp, sizeof(resp)); /* * If this cmd exists and whitelist is supported, scm_call return -2 (scm * driver remap it to -EINVAL) and resp.result 0xFFFFFFED(-19); Otherwise, * scm_call return -1 (remap to -EIO). */ if (ret == -EIO) { qseecom.whitelist_support = false; ret = 0; } else if (ret == -EINVAL && resp.result == QSEOS_RESULT_FAIL_SEND_CMD_NO_THREAD) { qseecom.whitelist_support = true; ret = 0; } else { pr_info("Check whitelist with ret = %d, result = 0x%x\n", ret, resp.result); qseecom.whitelist_support = false; ret = 0; } kfree(buf); return ret; return version >= MAKE_WHITELIST_VERSION(1, 0, 0); } static int qseecom_probe(struct platform_device *pdev) Loading Loading @@ -8300,11 +8356,7 @@ static int qseecom_probe(struct platform_device *pdev) qseecom.qsee_perf_client = msm_bus_scale_register_client( qseecom_platform_support); rc = qseecom_check_whitelist_feature(); if (rc) { rc = -EINVAL; goto exit_destroy_ion_client; } qseecom.whitelist_support = qseecom_check_whitelist_feature(); pr_warn("qseecom.whitelist_support = %d\n", qseecom.whitelist_support); Loading
include/soc/qcom/qseecomi.h +19 −0 Original line number Diff line number Diff line Loading @@ -68,6 +68,7 @@ enum qseecom_qceos_cmd_id { QSEOS_CLIENT_SEND_DATA_COMMAND_WHITELIST = 0x1C, QSEOS_TEE_OPEN_SESSION_WHITELIST = 0x1D, QSEOS_TEE_INVOKE_COMMAND_WHITELIST = 0x1E, QSEOS_LISTENER_DATA_RSP_COMMAND_WHITELIST = 0x1F, QSEOS_FSM_LTEOTA_REQ_CMD = 0x109, QSEOS_FSM_LTEOTA_REQ_RSP_CMD = 0x110, QSEOS_FSM_IKE_REQ_CMD = 0x203, Loading Loading @@ -217,6 +218,16 @@ __packed struct qseecom_client_listener_data_irsp { uint32_t qsee_cmd_id; uint32_t listener_id; uint32_t status; uint32_t sglistinfo_ptr; uint32_t sglistinfo_len; }; __packed struct qseecom_client_listener_data_64bit_irsp { uint32_t qsee_cmd_id; uint32_t listener_id; uint32_t status; uint64_t sglistinfo_ptr; uint32_t sglistinfo_len; }; /* Loading Loading @@ -703,4 +714,12 @@ __packed struct qseecom_continue_blocked_request_ireq { TZ_SYSCALL_PARAM_TYPE_VAL, TZ_SYSCALL_PARAM_TYPE_BUF_RW, \ TZ_SYSCALL_PARAM_TYPE_VAL) #define TZ_OS_LISTENER_RESPONSE_HANDLER_WITH_WHITELIST_ID \ TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_QSEE_OS, TZ_SVC_LISTENER, 0x05) #define TZ_OS_LISTENER_RESPONSE_HANDLER_WITH_WHITELIST_PARAM_ID \ TZ_SYSCALL_CREATE_PARAM_ID_4( \ TZ_SYSCALL_PARAM_TYPE_VAL, TZ_SYSCALL_PARAM_TYPE_VAL, \ TZ_SYSCALL_PARAM_TYPE_BUF_RW, TZ_SYSCALL_PARAM_TYPE_VAL) #endif /* __QSEECOMI_H_ */