qseecom: Fix kernel panic
When qseecom_unload_app() is invoked, wait_event_freezable() is called
in an atomic context (within a spinlock). wait_event_freezable() allows
sleep and should not be called in an atomic context where sleep is not
allowed.
Change-Id: I8c9c6d28f9e492fbbf2ac74a5ee3d1067c7733ad
Signed-off-by: Mona Hossain <mhossain@codeaurora.org>
diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c
index 8354aa8..696f16d 100644
--- a/drivers/misc/qseecom.c
+++ b/drivers/misc/qseecom.c
@@ -522,7 +522,6 @@
return 0;
}
-
static int __qseecom_listener_has_sent_rsp(struct qseecom_dev_handle *data)
{
int ret;
@@ -771,21 +770,20 @@
int ret = 0;
struct qseecom_command_scm_resp resp;
struct qseecom_registered_app_list *ptr_app;
- uint32_t unload = 0;
+ bool unload = false;
+ bool found_app = false;
if (qseecom.qseos_version == QSEOS_VERSION_14) {
spin_lock_irqsave(&qseecom.registered_app_list_lock, flags);
list_for_each_entry(ptr_app, &qseecom.registered_app_list_head,
list) {
if (ptr_app->app_id == data->client.app_id) {
+ found_app = true;
if (ptr_app->ref_cnt == 1) {
- unload = __qseecom_cleanup_app(data);
- list_del(&ptr_app->list);
- kzfree(ptr_app);
+ unload = true;
break;
} else {
ptr_app->ref_cnt--;
- data->released = true;
pr_warn("Can't unload app with id %d (it is inuse)\n",
ptr_app->app_id);
break;
@@ -795,14 +793,20 @@
spin_unlock_irqrestore(&qseecom.registered_app_list_lock,
flags);
}
- if (!IS_ERR_OR_NULL(data->client.ihandle)) {
- ion_unmap_kernel(qseecom.ion_clnt, data->client.ihandle);
- ion_free(qseecom.ion_clnt, data->client.ihandle);
+ if (found_app == false) {
+ pr_err("Cannot find app with id = %d\n", data->client.app_id);
+ return -EINVAL;
}
if ((unload) && (qseecom.qseos_version == QSEOS_VERSION_14)) {
struct qseecom_unload_app_ireq req;
+ __qseecom_cleanup_app(data);
+ spin_lock_irqsave(&qseecom.registered_app_list_lock, flags);
+ list_del(&ptr_app->list);
+ kzfree(ptr_app);
+ spin_unlock_irqrestore(&qseecom.registered_app_list_lock,
+ flags);
/* Populate the structure for sending scm call to load image */
req.qsee_cmd_id = QSEOS_APP_SHUTDOWN_COMMAND;
req.app_id = data->client.app_id;
@@ -840,6 +844,11 @@
}
}
}
+ if (!IS_ERR_OR_NULL(data->client.ihandle)) {
+ ion_unmap_kernel(qseecom.ion_clnt, data->client.ihandle);
+ ion_free(qseecom.ion_clnt, data->client.ihandle);
+ data->client.ihandle = NULL;
+ }
data->released = true;
return ret;
}