qseecom: Add new ioctl call.
Currently, qseecom user-space library does not have a way to
verify if a particular secure application is loaded in the
qsee or not. This new ioctl solves this issue.
Change-Id: Ia96459f3b8aadee2f6a3af564bb1cc83695759b5
Signed-off-by: Ramesh Masavarapu <rameshm@codeaurora.org>
diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c
index e8e56b8..f2ed62d 100644
--- a/drivers/misc/qseecom.c
+++ b/drivers/misc/qseecom.c
@@ -593,6 +593,26 @@
return ret;
}
+static int __qseecom_check_app_exists(struct qseecom_check_app_ireq req)
+{
+ int32_t ret;
+ struct qseecom_command_scm_resp resp;
+
+ /* SCM_CALL to check if app_id for the mentioned app exists */
+ ret = scm_call(SCM_SVC_TZSCHEDULER, 1, &req,
+ sizeof(struct qseecom_check_app_ireq),
+ &resp, sizeof(resp));
+ if (ret) {
+ pr_err("scm_call to check if app is already loaded failed\n");
+ return -EINVAL;
+ }
+
+ if (resp.result == QSEOS_RESULT_FAILURE)
+ return 0;
+ else
+ return resp.data;
+}
+
static int qseecom_load_app(struct qseecom_dev_handle *data, void __user *argp)
{
struct qseecom_registered_app_list *entry = NULL;
@@ -620,19 +640,11 @@
req.qsee_cmd_id = QSEOS_APP_LOOKUP_COMMAND;
memcpy(req.app_name, load_img_req.img_name, MAX_APP_NAME_SIZE);
- /* SCM_CALL to check if app_id for the mentioned app exists */
- ret = scm_call(SCM_SVC_TZSCHEDULER, 1, &req,
- sizeof(struct qseecom_check_app_ireq),
- &resp, sizeof(resp));
- if (ret) {
- pr_err("scm_call to check if app is already loaded failed\n");
- return -EINVAL;
- }
-
- if (resp.result == QSEOS_RESULT_FAILURE)
- app_id = 0;
+ ret = __qseecom_check_app_exists(req);
+ if (ret < 0)
+ return ret;
else
- app_id = resp.data;
+ app_id = ret;
if (app_id) {
pr_warn("App id %d (%s) already exists\n", app_id,
@@ -1411,6 +1423,37 @@
return ret;
}
+static int qseecom_query_app_loaded(struct qseecom_dev_handle *data,
+ void __user *argp)
+{
+
+ int32_t ret;
+ struct qseecom_qseos_app_load_query query_req;
+ struct qseecom_check_app_ireq req;
+
+ /* 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))) {
+ pr_err("copy_from_user failed\n");
+ return -EFAULT;
+ }
+
+ req.qsee_cmd_id = QSEOS_APP_LOOKUP_COMMAND;
+ memcpy(req.app_name, query_req.app_name, MAX_APP_NAME_SIZE);
+
+ ret = __qseecom_check_app_exists(req);
+ if (ret == -EINVAL) {
+ pr_err(" scm call to check if app is loaded failed");
+ return ret; /* scm call failed */
+ } else if (ret > 0) {
+ pr_err("app is already loaded in QSEE");
+ return -EEXIST; /* app already loaded */
+ } else {
+ return 0; /* app not loaded */
+ }
+}
+
static long qseecom_ioctl(struct file *file, unsigned cmd,
unsigned long arg)
{
@@ -1567,6 +1610,14 @@
pr_err("failed unload_app request: %d\n", ret);
break;
}
+ case QSEECOM_IOCTL_APP_LOADED_QUERY_REQ: {
+ mutex_lock(&app_access_lock);
+ atomic_inc(&data->ioctl_count);
+ ret = qseecom_query_app_loaded(data, argp);
+ atomic_dec(&data->ioctl_count);
+ mutex_unlock(&app_access_lock);
+ break;
+ }
default:
return -EINVAL;
}