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;
}
diff --git a/include/linux/qseecom.h b/include/linux/qseecom.h
index 62b5efe..0fcf96f 100644
--- a/include/linux/qseecom.h
+++ b/include/linux/qseecom.h
@@ -107,6 +107,14 @@
unsigned int qseos_version; /* in */
};
+/*
+ * struct qseecom_qseos_app_load_query - verify if app is loaded in qsee
+ * @app_name[MAX_APP_NAME_SIZE]- name of the app.
+ */
+struct qseecom_qseos_app_load_query {
+ char app_name[MAX_APP_NAME_SIZE]; /* in */
+};
+
#define QSEECOM_IOC_MAGIC 0x97
@@ -152,4 +160,8 @@
#define QSEECOM_IOCTL_UNLOAD_EXTERNAL_ELF_REQ \
_IO(QSEECOM_IOC_MAGIC, 14)
+#define QSEECOM_IOCTL_APP_LOADED_QUERY_REQ \
+ _IOWR(QSEECOM_IOC_MAGIC, 15, struct qseecom_qseos_app_load_query)
+
+
#endif /* __QSEECOM_H_ */