qseecom: return app_id correctly when looking up and loading app

When __qseecom_check_app_exsits() and __qseecom_load_fw() get app_id
from TZ, they save it to function's return value then return back.
But "app_id" is of type uint32, "ret" is int32, this will return
incorrect app_id to the caller if app_id is larger than 0x7FFFFFFF.
Thus make change to return app_id correctly.

Change-Id: I2ef98d64490c480d5416ee24ec6ca9aca9c8ca8a
Signed-off-by: Zhen Kong <zkong@codeaurora.org>
This commit is contained in:
Zhen Kong 2017-02-07 17:15:54 -08:00
parent 59a631bcac
commit c83a067a9a
4 changed files with 48 additions and 33 deletions

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
/* Copyright (c) 2014-2015,2017 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
@ -52,7 +52,7 @@ static int compat_get_qseecom_load_img_req(
compat_ulong_t img_len;
compat_long_t ifd_data_fd;
compat_ulong_t app_arch;
compat_int_t app_id;
compat_uint_t app_id;
err = get_user(mdt_len, &data32->mdt_len);
err |= put_user(mdt_len, &data->mdt_len);
@ -164,7 +164,7 @@ static int compat_get_qseecom_qseos_app_load_query(
{
int err = 0;
unsigned int i;
compat_int_t app_id;
compat_uint_t app_id;
char app_name;
compat_ulong_t app_arch;

View file

@ -93,7 +93,7 @@ struct compat_qseecom_load_img_req {
compat_long_t ifd_data_fd; /* in */
char img_name[MAX_APP_NAME_SIZE]; /* in */
compat_ulong_t app_arch; /* in */
compat_int_t app_id; /* out*/
compat_uint_t app_id; /* out*/
};
struct compat_qseecom_set_sb_mem_param_req {
@ -117,7 +117,7 @@ struct compat_qseecom_qseos_version_req {
*/
struct compat_qseecom_qseos_app_load_query {
char app_name[MAX_APP_NAME_SIZE]; /* in */
compat_int_t app_id; /* out */
compat_uint_t app_id; /* out */
compat_ulong_t app_arch;
};

View file

@ -2167,7 +2167,8 @@ 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;
struct qseecom_command_scm_resp resp;
@ -2175,6 +2176,12 @@ static int __qseecom_check_app_exists(struct qseecom_check_app_ireq req)
struct qseecom_registered_app_list *entry = NULL;
unsigned long flags = 0;
if (!app_id) {
pr_err("Null pointer to app_id\n");
return -EINVAL;
}
*app_id = 0;
/* check if app exists and has been registered locally */
spin_lock_irqsave(&qseecom.registered_app_list_lock, flags);
list_for_each_entry(entry,
@ -2187,7 +2194,8 @@ static int __qseecom_check_app_exists(struct qseecom_check_app_ireq req)
spin_unlock_irqrestore(&qseecom.registered_app_list_lock, flags);
if (found_app) {
pr_debug("Found app with id %d\n", entry->app_id);
return entry->app_id;
*app_id = entry->app_id;
return 0;
}
memset((void *)&resp, 0, sizeof(resp));
@ -2210,7 +2218,8 @@ static int __qseecom_check_app_exists(struct qseecom_check_app_ireq req)
pr_err("resp type is of listener type instead of app");
return -EINVAL;
case QSEOS_APP_ID:
return resp.data;
*app_id = resp.data;
return 0;
default:
pr_err("invalid resp type (%d) from qsee",
resp.resp_type);
@ -2286,11 +2295,10 @@ static int qseecom_load_app(struct qseecom_dev_handle *data, void __user *argp)
load_img_req.img_name[MAX_APP_NAME_SIZE-1] = '\0';
strlcpy(req.app_name, load_img_req.img_name, MAX_APP_NAME_SIZE);
ret = __qseecom_check_app_exists(req);
ret = __qseecom_check_app_exists(req, &app_id);
if (ret < 0)
goto loadapp_err;
app_id = ret;
if (app_id) {
pr_debug("App id %d (%s) already exists\n", app_id,
(char *)(req.app_name));
@ -4038,7 +4046,8 @@ static void __qseecom_free_img_data(struct ion_handle **ihandle)
*ihandle = NULL;
}
static int __qseecom_load_fw(struct qseecom_dev_handle *data, char *appname)
static int __qseecom_load_fw(struct qseecom_dev_handle *data, char *appname,
uint32_t *app_id)
{
int ret = -1;
uint32_t fw_size = 0;
@ -4052,6 +4061,11 @@ static int __qseecom_load_fw(struct qseecom_dev_handle *data, char *appname)
size_t cmd_len;
uint32_t app_arch = 0;
if (!data || !appname || !app_id) {
pr_err("Null pointer to data or appname or appid\n");
return -EINVAL;
}
*app_id = 0;
if (__qseecom_get_fw_size(appname, &fw_size, &app_arch))
return -EIO;
data->client.app_arch = app_arch;
@ -4143,14 +4157,14 @@ static int __qseecom_load_fw(struct qseecom_dev_handle *data, char *appname)
switch (resp.result) {
case QSEOS_RESULT_SUCCESS:
ret = resp.data;
*app_id = resp.data;
break;
case QSEOS_RESULT_INCOMPLETE:
ret = __qseecom_process_incomplete_cmd(data, &resp);
if (ret)
pr_err("process_incomplete_cmd FAILED\n");
else
ret = resp.data;
*app_id = resp.data;
break;
case QSEOS_RESULT_FAILURE:
pr_err("scm call failed with response QSEOS_RESULT FAILURE\n");
@ -4343,6 +4357,7 @@ int qseecom_start_app(struct qseecom_handle **handle,
size_t len;
ion_phys_addr_t pa;
uint32_t fw_size, app_arch;
uint32_t app_id = 0;
if (atomic_read(&qseecom.qseecom_state) != QSEECOM_STATE_READY) {
pr_err("Not allowed to be called in %d state\n",
@ -4397,18 +4412,18 @@ int qseecom_start_app(struct qseecom_handle **handle,
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);
if (ret < 0)
ret = __qseecom_check_app_exists(app_ireq, &app_id);
if (ret)
goto err;
strlcpy(data->client.app_name, app_name, MAX_APP_NAME_SIZE);
if (ret > 0) {
pr_warn("App id %d for [%s] app exists\n", ret,
if (app_id) {
pr_warn("App id %d for [%s] app exists\n", app_id,
(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 == ret) {
if (entry->app_id == app_id) {
entry->ref_cnt++;
found_app = true;
break;
@ -4423,11 +4438,11 @@ int qseecom_start_app(struct qseecom_handle **handle,
/* 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);
ret = __qseecom_load_fw(data, app_name, &app_id);
if (ret < 0)
goto err;
}
data->client.app_id = ret;
data->client.app_id = app_id;
if (!found_app) {
entry = kmalloc(sizeof(*entry), GFP_KERNEL);
if (!entry) {
@ -4435,7 +4450,7 @@ int qseecom_start_app(struct qseecom_handle **handle,
ret = -ENOMEM;
goto err;
}
entry->app_id = ret;
entry->app_id = app_id;
entry->ref_cnt = 1;
strlcpy(entry->app_name, app_name, MAX_APP_NAME_SIZE);
if (__qseecom_get_fw_size(app_name, &fw_size, &app_arch)) {
@ -5272,7 +5287,7 @@ static int qseecom_query_app_loaded(struct qseecom_dev_handle *data,
struct qseecom_check_app_ireq req;
struct qseecom_registered_app_list *entry = NULL;
unsigned long flags = 0;
uint32_t app_arch = 0;
uint32_t app_arch = 0, app_id = 0;
bool found_app = false;
/* Copy the relevant information needed for loading the image */
@ -5287,18 +5302,18 @@ static int qseecom_query_app_loaded(struct qseecom_dev_handle *data,
query_req.app_name[MAX_APP_NAME_SIZE-1] = '\0';
strlcpy(req.app_name, query_req.app_name, MAX_APP_NAME_SIZE);
ret = __qseecom_check_app_exists(req);
if ((ret == -EINVAL) || (ret == -ENODEV)) {
ret = __qseecom_check_app_exists(req, &app_id);
if (ret) {
pr_err(" scm call to check if app is loaded failed");
return ret; /* scm call failed */
} else if (ret > 0) {
pr_debug("App id %d (%s) already exists\n", ret,
}
if (app_id) {
pr_debug("App id %d (%s) already exists\n", app_id,
(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 == ret) {
if (entry->app_id == app_id) {
app_arch = entry->app_arch;
entry->ref_cnt++;
found_app = true;
@ -5307,8 +5322,8 @@ static int qseecom_query_app_loaded(struct qseecom_dev_handle *data,
}
spin_unlock_irqrestore(
&qseecom.registered_app_list_lock, flags);
data->client.app_id = ret;
query_req.app_id = ret;
data->client.app_id = app_id;
query_req.app_id = app_id;
if (app_arch) {
data->client.app_arch = app_arch;
query_req.app_arch = app_arch;
@ -5330,7 +5345,7 @@ static int qseecom_query_app_loaded(struct qseecom_dev_handle *data,
pr_err("kmalloc for app entry failed\n");
return -ENOMEM;
}
entry->app_id = ret;
entry->app_id = app_id;
entry->ref_cnt = 1;
entry->app_arch = data->client.app_arch;
strlcpy(entry->app_name, data->client.app_name,

View file

@ -92,7 +92,7 @@ struct qseecom_load_img_req {
int32_t ifd_data_fd; /* in */
char img_name[MAX_APP_NAME_SIZE]; /* in */
uint32_t app_arch; /* in */
int app_id; /* out*/
uint32_t app_id; /* out*/
};
struct qseecom_set_sb_mem_param_req {
@ -116,7 +116,7 @@ struct qseecom_qseos_version_req {
*/
struct qseecom_qseos_app_load_query {
char app_name[MAX_APP_NAME_SIZE]; /* in */
int app_id; /* out */
uint32_t app_id; /* out */
uint32_t app_arch;
};