Loading drivers/misc/qseecom.c +54 −28 Original line number Diff line number Diff line /* * QTI Secure Execution Environment Communicator (QSEECOM) driver * * Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -2418,7 +2418,7 @@ static void __qseecom_reentrancy_check_if_this_app_blocked( } } static int __qseecom_check_app_exists(struct qseecom_check_app_ireq req, static int __qseecom_check_app_exists(struct qseecom_check_app_ireq *req, uint32_t *app_id) { int32_t ret; Loading @@ -2437,7 +2437,7 @@ static int __qseecom_check_app_exists(struct qseecom_check_app_ireq req, spin_lock_irqsave(&qseecom.registered_app_list_lock, flags); list_for_each_entry(entry, &qseecom.registered_app_list_head, list) { if (!strcmp(entry->app_name, req.app_name)) { if (!strcmp(entry->app_name, req->app_name)) { found_app = true; break; } Loading @@ -2452,7 +2452,7 @@ static int __qseecom_check_app_exists(struct qseecom_check_app_ireq req, memset((void *)&resp, 0, sizeof(resp)); /* SCM_CALL to check if app_id for the mentioned app exists */ ret = qseecom_scm_call(SCM_SVC_TZSCHEDULER, 1, &req, ret = qseecom_scm_call(SCM_SVC_TZSCHEDULER, 1, req, sizeof(struct qseecom_check_app_ireq), &resp, sizeof(resp)); if (ret) { Loading Loading @@ -2493,19 +2493,24 @@ static int qseecom_load_app(struct qseecom_dev_handle *data, void __user *argp) size_t len; struct qseecom_command_scm_resp resp; struct qseecom_check_app_ireq req; struct qseecom_check_app_ireq *req = NULL; struct qseecom_load_app_ireq load_req; struct qseecom_load_app_64bit_ireq load_req_64bit; void *cmd_buf = NULL; size_t cmd_len; bool first_time = false; req = kzalloc(sizeof(*req), GFP_KERNEL); if (!req) return -ENOMEM; /* Copy the relevant information needed for loading the image */ if (copy_from_user(&load_img_req, (void __user *)argp, sizeof(struct qseecom_load_img_req))) { pr_err("copy_from_user failed\n"); return -EFAULT; ret = -EFAULT; goto req_free; } /* Check and load cmnlib */ Loading @@ -2515,7 +2520,8 @@ static int qseecom_load_app(struct qseecom_dev_handle *data, void __user *argp) ret = qseecom_load_commonlib_image(data, "cmnlib"); if (ret) { pr_err("failed to load cmnlib\n"); return -EIO; ret = -EIO; goto req_free; } qseecom.commonlib_loaded = true; pr_debug("cmnlib is loaded\n"); Loading @@ -2526,7 +2532,8 @@ static int qseecom_load_app(struct qseecom_dev_handle *data, void __user *argp) ret = qseecom_load_commonlib_image(data, "cmnlib64"); if (ret) { pr_err("failed to load cmnlib64\n"); return -EIO; ret = -EIO; goto req_free; } qseecom.commonlib64_loaded = true; pr_debug("cmnlib64 is loaded\n"); Loading @@ -2538,7 +2545,7 @@ static int qseecom_load_app(struct qseecom_dev_handle *data, void __user *argp) ret = __qseecom_register_bus_bandwidth_needs(data, MEDIUM); mutex_unlock(&qsee_bw_mutex); if (ret) return ret; goto req_free; } /* Vote for the SFPB clock */ Loading @@ -2546,9 +2553,9 @@ static int qseecom_load_app(struct qseecom_dev_handle *data, void __user *argp) if (ret) goto enable_clk_err; req.qsee_cmd_id = QSEOS_APP_LOOKUP_COMMAND; req->qsee_cmd_id = QSEOS_APP_LOOKUP_COMMAND; load_img_req.img_name[MAX_APP_NAME_SIZE-1] = '\0'; strlcpy(req.app_name, load_img_req.img_name, MAX_APP_NAME_SIZE); strlcpy(req->app_name, load_img_req.img_name, MAX_APP_NAME_SIZE); ret = __qseecom_check_app_exists(req, &app_id); if (ret < 0) Loading @@ -2556,14 +2563,14 @@ static int qseecom_load_app(struct qseecom_dev_handle *data, void __user *argp) if (app_id) { pr_debug("App id %d (%s) already exists\n", app_id, (char *)(req.app_name)); (char *)(req->app_name)); spin_lock_irqsave(&qseecom.registered_app_list_lock, flags); list_for_each_entry(entry, &qseecom.registered_app_list_head, list){ if (entry->app_id == app_id) { if (entry->ref_cnt == U32_MAX) { pr_err("App %d (%s) ref_cnt overflow\n", app_id, req.app_name); app_id, req->app_name); ret = -EINVAL; goto loadapp_err; } Loading Loading @@ -2725,6 +2732,8 @@ static int qseecom_load_app(struct qseecom_dev_handle *data, void __user *argp) qseecom_unregister_bus_bandwidth_needs(data); mutex_unlock(&qsee_bw_mutex); } req_free: kfree(req); return ret; } Loading Loading @@ -4559,7 +4568,7 @@ int qseecom_start_app(struct qseecom_handle **handle, int32_t ret = 0; unsigned long flags = 0; struct qseecom_dev_handle *data = NULL; struct qseecom_check_app_ireq app_ireq; struct qseecom_check_app_ireq *app_ireq = NULL; struct qseecom_registered_app_list *entry = NULL; struct qseecom_registered_kclient_list *kclient_entry = NULL; bool found_app = false; Loading Loading @@ -4608,25 +4617,31 @@ int qseecom_start_app(struct qseecom_handle **handle, mutex_lock(&app_access_lock); app_ireq.qsee_cmd_id = QSEOS_APP_LOOKUP_COMMAND; strlcpy(app_ireq.app_name, app_name, MAX_APP_NAME_SIZE); app_ireq = kzalloc(sizeof(*app_ireq), GFP_KERNEL); if (!app_ireq) { ret = -ENOMEM; goto err; } app_ireq->qsee_cmd_id = QSEOS_APP_LOOKUP_COMMAND; strlcpy(app_ireq->app_name, app_name, MAX_APP_NAME_SIZE); ret = __qseecom_check_app_exists(app_ireq, &app_id); if (ret) goto err; goto app_ireq_free; strlcpy(data->client.app_name, app_name, MAX_APP_NAME_SIZE); if (app_id) { pr_warn("App id %d for [%s] app exists\n", app_id, (char *)app_ireq.app_name); (char *)app_ireq->app_name); spin_lock_irqsave(&qseecom.registered_app_list_lock, flags); list_for_each_entry(entry, &qseecom.registered_app_list_head, list){ if (entry->app_id == app_id) { if (entry->ref_cnt == U32_MAX) { pr_err("App %d (%s) ref_cnt overflow\n", app_id, app_ireq.app_name); app_id, app_ireq->app_name); ret = -EINVAL; goto err; goto app_ireq_free; } entry->ref_cnt++; found_app = true; Loading @@ -4637,15 +4652,16 @@ int qseecom_start_app(struct qseecom_handle **handle, &qseecom.registered_app_list_lock, flags); if (!found_app) pr_warn("App_id %d [%s] was loaded but not registered\n", ret, (char *)app_ireq.app_name); ret, (char *)app_ireq->app_name); } else { /* load the app and get the app_id */ pr_debug("%s: Loading app for the first time'\n", qseecom.pdev->init_name); ret = __qseecom_load_fw(data, app_name, &app_id); if (ret < 0) goto err; goto app_ireq_free; } kfree(app_ireq); data->client.app_id = app_id; if (!found_app) { entry = kmalloc(sizeof(*entry), GFP_KERNEL); Loading Loading @@ -4702,6 +4718,8 @@ int qseecom_start_app(struct qseecom_handle **handle, mutex_unlock(&app_access_lock); return 0; app_ireq_free: kfree(app_ireq); err: if (va) __qseecom_free_coherent_buf(size, va, pa); Loading Loading @@ -5510,8 +5528,8 @@ static int qseecom_query_app_loaded(struct qseecom_dev_handle *data, { int32_t ret = 0; struct qseecom_qseos_app_load_query *query_req; struct qseecom_check_app_ireq req; struct qseecom_qseos_app_load_query *query_req = NULL; struct qseecom_check_app_ireq *req = NULL; struct qseecom_registered_app_list *entry = NULL; unsigned long flags = 0; uint32_t app_arch = 0, app_id = 0; Loading @@ -5522,6 +5540,12 @@ static int qseecom_query_app_loaded(struct qseecom_dev_handle *data, if (!query_req) return -ENOMEM; req = kzalloc(sizeof(*req), GFP_KERNEL); if (!req) { ret = -ENOMEM; goto query_req_exit; } /* Copy the relevant information needed for loading the image */ if (copy_from_user(query_req, (void __user *)argp, sizeof(struct qseecom_qseos_app_load_query))) { Loading @@ -5530,9 +5554,9 @@ static int qseecom_query_app_loaded(struct qseecom_dev_handle *data, goto exit_free; } req.qsee_cmd_id = QSEOS_APP_LOOKUP_COMMAND; req->qsee_cmd_id = QSEOS_APP_LOOKUP_COMMAND; query_req->app_name[MAX_APP_NAME_SIZE-1] = '\0'; strlcpy(req.app_name, query_req->app_name, MAX_APP_NAME_SIZE); strlcpy(req->app_name, query_req->app_name, MAX_APP_NAME_SIZE); ret = __qseecom_check_app_exists(req, &app_id); if (ret) { Loading @@ -5541,7 +5565,7 @@ static int qseecom_query_app_loaded(struct qseecom_dev_handle *data, } if (app_id) { pr_debug("App id %d (%s) already exists\n", app_id, (char *)(req.app_name)); (char *)(req->app_name)); spin_lock_irqsave(&qseecom.registered_app_list_lock, flags); list_for_each_entry(entry, &qseecom.registered_app_list_head, list){ Loading @@ -5549,7 +5573,7 @@ static int qseecom_query_app_loaded(struct qseecom_dev_handle *data, app_arch = entry->app_arch; if (entry->ref_cnt == U32_MAX) { pr_err("App %d (%s) ref_cnt overflow\n", app_id, req.app_name); app_id, req->app_name); ret = -EINVAL; goto exit_free; } Loading Loading @@ -5609,6 +5633,8 @@ static int qseecom_query_app_loaded(struct qseecom_dev_handle *data, } exit_free: kfree(req); query_req_exit: kfree(query_req); return ret; /* app not loaded */ Loading Loading
drivers/misc/qseecom.c +54 −28 Original line number Diff line number Diff line /* * QTI Secure Execution Environment Communicator (QSEECOM) driver * * Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -2418,7 +2418,7 @@ static void __qseecom_reentrancy_check_if_this_app_blocked( } } static int __qseecom_check_app_exists(struct qseecom_check_app_ireq req, static int __qseecom_check_app_exists(struct qseecom_check_app_ireq *req, uint32_t *app_id) { int32_t ret; Loading @@ -2437,7 +2437,7 @@ static int __qseecom_check_app_exists(struct qseecom_check_app_ireq req, spin_lock_irqsave(&qseecom.registered_app_list_lock, flags); list_for_each_entry(entry, &qseecom.registered_app_list_head, list) { if (!strcmp(entry->app_name, req.app_name)) { if (!strcmp(entry->app_name, req->app_name)) { found_app = true; break; } Loading @@ -2452,7 +2452,7 @@ static int __qseecom_check_app_exists(struct qseecom_check_app_ireq req, memset((void *)&resp, 0, sizeof(resp)); /* SCM_CALL to check if app_id for the mentioned app exists */ ret = qseecom_scm_call(SCM_SVC_TZSCHEDULER, 1, &req, ret = qseecom_scm_call(SCM_SVC_TZSCHEDULER, 1, req, sizeof(struct qseecom_check_app_ireq), &resp, sizeof(resp)); if (ret) { Loading Loading @@ -2493,19 +2493,24 @@ static int qseecom_load_app(struct qseecom_dev_handle *data, void __user *argp) size_t len; struct qseecom_command_scm_resp resp; struct qseecom_check_app_ireq req; struct qseecom_check_app_ireq *req = NULL; struct qseecom_load_app_ireq load_req; struct qseecom_load_app_64bit_ireq load_req_64bit; void *cmd_buf = NULL; size_t cmd_len; bool first_time = false; req = kzalloc(sizeof(*req), GFP_KERNEL); if (!req) return -ENOMEM; /* Copy the relevant information needed for loading the image */ if (copy_from_user(&load_img_req, (void __user *)argp, sizeof(struct qseecom_load_img_req))) { pr_err("copy_from_user failed\n"); return -EFAULT; ret = -EFAULT; goto req_free; } /* Check and load cmnlib */ Loading @@ -2515,7 +2520,8 @@ static int qseecom_load_app(struct qseecom_dev_handle *data, void __user *argp) ret = qseecom_load_commonlib_image(data, "cmnlib"); if (ret) { pr_err("failed to load cmnlib\n"); return -EIO; ret = -EIO; goto req_free; } qseecom.commonlib_loaded = true; pr_debug("cmnlib is loaded\n"); Loading @@ -2526,7 +2532,8 @@ static int qseecom_load_app(struct qseecom_dev_handle *data, void __user *argp) ret = qseecom_load_commonlib_image(data, "cmnlib64"); if (ret) { pr_err("failed to load cmnlib64\n"); return -EIO; ret = -EIO; goto req_free; } qseecom.commonlib64_loaded = true; pr_debug("cmnlib64 is loaded\n"); Loading @@ -2538,7 +2545,7 @@ static int qseecom_load_app(struct qseecom_dev_handle *data, void __user *argp) ret = __qseecom_register_bus_bandwidth_needs(data, MEDIUM); mutex_unlock(&qsee_bw_mutex); if (ret) return ret; goto req_free; } /* Vote for the SFPB clock */ Loading @@ -2546,9 +2553,9 @@ static int qseecom_load_app(struct qseecom_dev_handle *data, void __user *argp) if (ret) goto enable_clk_err; req.qsee_cmd_id = QSEOS_APP_LOOKUP_COMMAND; req->qsee_cmd_id = QSEOS_APP_LOOKUP_COMMAND; load_img_req.img_name[MAX_APP_NAME_SIZE-1] = '\0'; strlcpy(req.app_name, load_img_req.img_name, MAX_APP_NAME_SIZE); strlcpy(req->app_name, load_img_req.img_name, MAX_APP_NAME_SIZE); ret = __qseecom_check_app_exists(req, &app_id); if (ret < 0) Loading @@ -2556,14 +2563,14 @@ static int qseecom_load_app(struct qseecom_dev_handle *data, void __user *argp) if (app_id) { pr_debug("App id %d (%s) already exists\n", app_id, (char *)(req.app_name)); (char *)(req->app_name)); spin_lock_irqsave(&qseecom.registered_app_list_lock, flags); list_for_each_entry(entry, &qseecom.registered_app_list_head, list){ if (entry->app_id == app_id) { if (entry->ref_cnt == U32_MAX) { pr_err("App %d (%s) ref_cnt overflow\n", app_id, req.app_name); app_id, req->app_name); ret = -EINVAL; goto loadapp_err; } Loading Loading @@ -2725,6 +2732,8 @@ static int qseecom_load_app(struct qseecom_dev_handle *data, void __user *argp) qseecom_unregister_bus_bandwidth_needs(data); mutex_unlock(&qsee_bw_mutex); } req_free: kfree(req); return ret; } Loading Loading @@ -4559,7 +4568,7 @@ int qseecom_start_app(struct qseecom_handle **handle, int32_t ret = 0; unsigned long flags = 0; struct qseecom_dev_handle *data = NULL; struct qseecom_check_app_ireq app_ireq; struct qseecom_check_app_ireq *app_ireq = NULL; struct qseecom_registered_app_list *entry = NULL; struct qseecom_registered_kclient_list *kclient_entry = NULL; bool found_app = false; Loading Loading @@ -4608,25 +4617,31 @@ int qseecom_start_app(struct qseecom_handle **handle, mutex_lock(&app_access_lock); app_ireq.qsee_cmd_id = QSEOS_APP_LOOKUP_COMMAND; strlcpy(app_ireq.app_name, app_name, MAX_APP_NAME_SIZE); app_ireq = kzalloc(sizeof(*app_ireq), GFP_KERNEL); if (!app_ireq) { ret = -ENOMEM; goto err; } app_ireq->qsee_cmd_id = QSEOS_APP_LOOKUP_COMMAND; strlcpy(app_ireq->app_name, app_name, MAX_APP_NAME_SIZE); ret = __qseecom_check_app_exists(app_ireq, &app_id); if (ret) goto err; goto app_ireq_free; strlcpy(data->client.app_name, app_name, MAX_APP_NAME_SIZE); if (app_id) { pr_warn("App id %d for [%s] app exists\n", app_id, (char *)app_ireq.app_name); (char *)app_ireq->app_name); spin_lock_irqsave(&qseecom.registered_app_list_lock, flags); list_for_each_entry(entry, &qseecom.registered_app_list_head, list){ if (entry->app_id == app_id) { if (entry->ref_cnt == U32_MAX) { pr_err("App %d (%s) ref_cnt overflow\n", app_id, app_ireq.app_name); app_id, app_ireq->app_name); ret = -EINVAL; goto err; goto app_ireq_free; } entry->ref_cnt++; found_app = true; Loading @@ -4637,15 +4652,16 @@ int qseecom_start_app(struct qseecom_handle **handle, &qseecom.registered_app_list_lock, flags); if (!found_app) pr_warn("App_id %d [%s] was loaded but not registered\n", ret, (char *)app_ireq.app_name); ret, (char *)app_ireq->app_name); } else { /* load the app and get the app_id */ pr_debug("%s: Loading app for the first time'\n", qseecom.pdev->init_name); ret = __qseecom_load_fw(data, app_name, &app_id); if (ret < 0) goto err; goto app_ireq_free; } kfree(app_ireq); data->client.app_id = app_id; if (!found_app) { entry = kmalloc(sizeof(*entry), GFP_KERNEL); Loading Loading @@ -4702,6 +4718,8 @@ int qseecom_start_app(struct qseecom_handle **handle, mutex_unlock(&app_access_lock); return 0; app_ireq_free: kfree(app_ireq); err: if (va) __qseecom_free_coherent_buf(size, va, pa); Loading Loading @@ -5510,8 +5528,8 @@ static int qseecom_query_app_loaded(struct qseecom_dev_handle *data, { int32_t ret = 0; struct qseecom_qseos_app_load_query *query_req; struct qseecom_check_app_ireq req; struct qseecom_qseos_app_load_query *query_req = NULL; struct qseecom_check_app_ireq *req = NULL; struct qseecom_registered_app_list *entry = NULL; unsigned long flags = 0; uint32_t app_arch = 0, app_id = 0; Loading @@ -5522,6 +5540,12 @@ static int qseecom_query_app_loaded(struct qseecom_dev_handle *data, if (!query_req) return -ENOMEM; req = kzalloc(sizeof(*req), GFP_KERNEL); if (!req) { ret = -ENOMEM; goto query_req_exit; } /* Copy the relevant information needed for loading the image */ if (copy_from_user(query_req, (void __user *)argp, sizeof(struct qseecom_qseos_app_load_query))) { Loading @@ -5530,9 +5554,9 @@ static int qseecom_query_app_loaded(struct qseecom_dev_handle *data, goto exit_free; } req.qsee_cmd_id = QSEOS_APP_LOOKUP_COMMAND; req->qsee_cmd_id = QSEOS_APP_LOOKUP_COMMAND; query_req->app_name[MAX_APP_NAME_SIZE-1] = '\0'; strlcpy(req.app_name, query_req->app_name, MAX_APP_NAME_SIZE); strlcpy(req->app_name, query_req->app_name, MAX_APP_NAME_SIZE); ret = __qseecom_check_app_exists(req, &app_id); if (ret) { Loading @@ -5541,7 +5565,7 @@ static int qseecom_query_app_loaded(struct qseecom_dev_handle *data, } if (app_id) { pr_debug("App id %d (%s) already exists\n", app_id, (char *)(req.app_name)); (char *)(req->app_name)); spin_lock_irqsave(&qseecom.registered_app_list_lock, flags); list_for_each_entry(entry, &qseecom.registered_app_list_head, list){ Loading @@ -5549,7 +5573,7 @@ static int qseecom_query_app_loaded(struct qseecom_dev_handle *data, app_arch = entry->app_arch; if (entry->ref_cnt == U32_MAX) { pr_err("App %d (%s) ref_cnt overflow\n", app_id, req.app_name); app_id, req->app_name); ret = -EINVAL; goto exit_free; } Loading Loading @@ -5609,6 +5633,8 @@ static int qseecom_query_app_loaded(struct qseecom_dev_handle *data, } exit_free: kfree(req); query_req_exit: kfree(query_req); return ret; /* app not loaded */ Loading