qseecom: whitelist support for kernel client and listener

Add whitelist support for listener to send modified resp to TZ;
also add whitelist support for kernel client; and change the method
to check whitelist feature.

Change-Id: I0030b0008d6224cda3fdc1f80308a7e9bcfe4405
Signed-off-by: Zhen Kong <zkong@codeaurora.org>
Signed-off-by: Mallikarjuna Reddy Amireddy <mamire@codeaurora.org>
This commit is contained in:
Zhen Kong 2016-09-02 22:09:23 -07:00 committed by Mallikarjuna Reddy Amireddy
parent 0f3d8c9101
commit 6c3d41026e
2 changed files with 209 additions and 135 deletions

View File

@ -119,6 +119,35 @@ static DEFINE_MUTEX(qsee_bw_mutex);
static DEFINE_MUTEX(app_access_lock);
static DEFINE_MUTEX(clk_access_lock);
struct sglist_info {
uint32_t indexAndFlags;
uint32_t sizeOrCount;
};
/*
* The 31th bit indicates only one or multiple physical address inside
* the request buffer. If it is set, the index locates a single physical addr
* inside the request buffer, and `sizeOrCount` is the size of the memory being
* shared at that physical address.
* Otherwise, the index locates an array of {start, len} pairs (a
* "scatter/gather list"), and `sizeOrCount` gives the number of entries in
* that array.
*
* The 30th bit indicates 64 or 32bit address; when it is set, physical addr
* and scatter gather entry sizes are 64-bit values. Otherwise, 32-bit values.
*
* The bits [0:29] of `indexAndFlags` hold an offset into the request buffer.
*/
#define SGLISTINFO_SET_INDEX_FLAG(c, s, i) \
((uint32_t)(((c & 1) << 31) | ((s & 1) << 30) | (i & 0x3fffffff)))
#define SGLISTINFO_TABLE_SIZE (sizeof(struct sglist_info) * MAX_ION_FD)
#define FEATURE_ID_WHITELIST 15 /*whitelist feature id*/
#define MAKE_WHITELIST_VERSION(major, minor, patch) \
(((major & 0x3FF) << 22) | ((minor & 0x3FF) << 12) | (patch & 0xFFF))
struct qseecom_registered_listener_list {
struct list_head list;
struct qseecom_register_listener_req svc;
@ -133,6 +162,8 @@ struct qseecom_registered_listener_list {
bool listener_in_use;
/* wq for thread blocked on this listener*/
wait_queue_head_t listener_block_app_wq;
struct sglist_info sglistinfo_ptr[MAX_ION_FD];
uint32_t sglist_cnt;
};
struct qseecom_registered_app_list {
@ -246,30 +277,6 @@ struct qseecom_listener_handle {
static struct qseecom_control qseecom;
struct sglist_info {
uint32_t indexAndFlags;
uint32_t sizeOrCount;
};
/*
* The 31th bit indicates only one or multiple physical address inside
* the request buffer. If it is set, the index locates a single physical addr
* inside the request buffer, and `sizeOrCount` is the size of the memory being
* shared at that physical address.
* Otherwise, the index locates an array of {start, len} pairs (a
* "scatter/gather list"), and `sizeOrCount` gives the number of entries in
* that array.
*
* The 30th bit indicates 64 or 32bit address; when it is set, physical addr
* and scatter gather entry sizes are 64-bit values. Otherwise, 32-bit values.
*
* The bits [0:29] of `indexAndFlags` hold an offset into the request buffer.
*/
#define SGLISTINFO_SET_INDEX_FLAG(c, s, i) \
((uint32_t)(((c & 1) << 31) | ((s & 1) << 30) | (i & 0x3fffffff)))
#define SGLISTINFO_TABLE_SIZE (sizeof(struct sglist_info) * MAX_ION_FD)
struct qseecom_dev_handle {
enum qseecom_client_handle_type type;
union {
@ -283,8 +290,9 @@ struct qseecom_dev_handle {
bool perf_enabled;
bool fast_load_enabled;
enum qseecom_bandwidth_request_mode mode;
struct sglist_info *sglistinfo_ptr;
struct sglist_info sglistinfo_ptr[MAX_ION_FD];
uint32_t sglist_cnt;
bool use_legacy_cmd;
};
struct qseecom_key_id_usage_desc {
@ -542,6 +550,34 @@ static int qseecom_scm_call2(uint32_t svc_id, uint32_t tz_cmd_id,
ret = scm_call2(smc_id, &desc);
break;
}
case QSEOS_LISTENER_DATA_RSP_COMMAND_WHITELIST: {
struct qseecom_client_listener_data_irsp *req;
struct qseecom_client_listener_data_64bit_irsp *req_64;
smc_id =
TZ_OS_LISTENER_RESPONSE_HANDLER_WITH_WHITELIST_ID;
desc.arginfo =
TZ_OS_LISTENER_RESPONSE_HANDLER_WITH_WHITELIST_PARAM_ID;
if (qseecom.qsee_version < QSEE_VERSION_40) {
req =
(struct qseecom_client_listener_data_irsp *)
req_buf;
desc.args[0] = req->listener_id;
desc.args[1] = req->status;
desc.args[2] = req->sglistinfo_ptr;
desc.args[3] = req->sglistinfo_len;
} else {
req_64 =
(struct qseecom_client_listener_data_64bit_irsp *)
req_buf;
desc.args[0] = req_64->listener_id;
desc.args[1] = req_64->status;
desc.args[2] = req_64->sglistinfo_ptr;
desc.args[3] = req_64->sglistinfo_len;
}
ret = scm_call2(smc_id, &desc);
break;
}
case QSEOS_LOAD_EXTERNAL_ELF_COMMAND: {
struct qseecom_load_app_ireq *req;
struct qseecom_load_app_64bit_ireq *req_64bit;
@ -1052,7 +1088,7 @@ static int qseecom_register_listener(struct qseecom_dev_handle *data,
return -EBUSY;
}
new_entry = kmalloc(sizeof(*new_entry), GFP_KERNEL);
new_entry = kzalloc(sizeof(*new_entry), GFP_KERNEL);
if (!new_entry) {
pr_err("kmalloc failed\n");
return -ENOMEM;
@ -1508,6 +1544,16 @@ static int __qseecom_qseos_fail_return_resp_tz(struct qseecom_dev_handle *data,
return ret;
}
static void __qseecom_clean_listener_sglistinfo(
struct qseecom_registered_listener_list *ptr_svc)
{
if (ptr_svc->sglist_cnt) {
memset(ptr_svc->sglistinfo_ptr, 0,
SGLISTINFO_TABLE_SIZE);
ptr_svc->sglist_cnt = 0;
}
}
static int __qseecom_process_incomplete_cmd(struct qseecom_dev_handle *data,
struct qseecom_command_scm_resp *resp)
{
@ -1516,9 +1562,14 @@ static int __qseecom_process_incomplete_cmd(struct qseecom_dev_handle *data,
uint32_t lstnr;
unsigned long flags;
struct qseecom_client_listener_data_irsp send_data_rsp;
struct qseecom_client_listener_data_64bit_irsp send_data_rsp_64bit;
struct qseecom_registered_listener_list *ptr_svc = NULL;
sigset_t new_sigset;
sigset_t old_sigset;
uint32_t status;
void *cmd_buf = NULL;
size_t cmd_len;
struct sglist_info *table = NULL;
while (resp->result == QSEOS_RESULT_INCOMPLETE) {
lstnr = resp->data;
@ -1530,6 +1581,7 @@ static int __qseecom_process_incomplete_cmd(struct qseecom_dev_handle *data,
list_for_each_entry(ptr_svc,
&qseecom.registered_listener_list_head, list) {
if (ptr_svc->svc.listener_id == lstnr) {
ptr_svc->listener_in_use = true;
ptr_svc->rcv_req_flag = 1;
wake_up_interruptible(&ptr_svc->rcv_req_wq);
break;
@ -1577,14 +1629,42 @@ static int __qseecom_process_incomplete_cmd(struct qseecom_dev_handle *data,
pr_err("Abort clnt %d waiting on lstnr svc %d, ret %d",
data->client.app_id, lstnr, ret);
rc = -ENODEV;
send_data_rsp.status = QSEOS_RESULT_FAILURE;
status = QSEOS_RESULT_FAILURE;
} else {
send_data_rsp.status = QSEOS_RESULT_SUCCESS;
status = QSEOS_RESULT_SUCCESS;
}
qseecom.send_resp_flag = 0;
send_data_rsp.qsee_cmd_id = QSEOS_LISTENER_DATA_RSP_COMMAND;
send_data_rsp.listener_id = lstnr;
ptr_svc->send_resp_flag = 0;
table = ptr_svc->sglistinfo_ptr;
if (qseecom.qsee_version < QSEE_VERSION_40) {
send_data_rsp.listener_id = lstnr;
send_data_rsp.status = status;
send_data_rsp.sglistinfo_ptr =
(uint32_t)virt_to_phys(table);
send_data_rsp.sglistinfo_len =
SGLISTINFO_TABLE_SIZE;
dmac_flush_range((void *)table,
(void *)table + SGLISTINFO_TABLE_SIZE);
cmd_buf = (void *)&send_data_rsp;
cmd_len = sizeof(send_data_rsp);
} else {
send_data_rsp_64bit.listener_id = lstnr;
send_data_rsp_64bit.status = status;
send_data_rsp_64bit.sglistinfo_ptr =
virt_to_phys(table);
send_data_rsp_64bit.sglistinfo_len =
SGLISTINFO_TABLE_SIZE;
dmac_flush_range((void *)table,
(void *)table + SGLISTINFO_TABLE_SIZE);
cmd_buf = (void *)&send_data_rsp_64bit;
cmd_len = sizeof(send_data_rsp_64bit);
}
if (qseecom.whitelist_support == false)
*(uint32_t *)cmd_buf = QSEOS_LISTENER_DATA_RSP_COMMAND;
else
*(uint32_t *)cmd_buf =
QSEOS_LISTENER_DATA_RSP_COMMAND_WHITELIST;
if (ptr_svc)
msm_ion_do_cache_op(qseecom.ion_clnt, ptr_svc->ihandle,
ptr_svc->sb_virt, ptr_svc->sb_length,
@ -1594,9 +1674,9 @@ static int __qseecom_process_incomplete_cmd(struct qseecom_dev_handle *data,
__qseecom_enable_clk(CLK_QSEE);
ret = qseecom_scm_call(SCM_SVC_TZSCHEDULER, 1,
(const void *)&send_data_rsp,
sizeof(send_data_rsp), resp,
sizeof(*resp));
cmd_buf, cmd_len, resp, sizeof(*resp));
ptr_svc->listener_in_use = false;
__qseecom_clean_listener_sglistinfo(ptr_svc);
if (ret) {
pr_err("scm_call() failed with err: %d (app_id = %d)\n",
ret, data->client.app_id);
@ -1629,9 +1709,14 @@ static int __qseecom_reentrancy_process_incomplete_cmd(
uint32_t lstnr;
unsigned long flags;
struct qseecom_client_listener_data_irsp send_data_rsp;
struct qseecom_client_listener_data_64bit_irsp send_data_rsp_64bit;
struct qseecom_registered_listener_list *ptr_svc = NULL;
sigset_t new_sigset;
sigset_t old_sigset;
uint32_t status;
void *cmd_buf = NULL;
size_t cmd_len;
struct sglist_info *table = NULL;
while (resp->result == QSEOS_RESULT_INCOMPLETE) {
lstnr = resp->data;
@ -1694,13 +1779,38 @@ static int __qseecom_reentrancy_process_incomplete_cmd(
pr_err("Abort clnt %d waiting on lstnr svc %d, ret %d",
data->client.app_id, lstnr, ret);
rc = -ENODEV;
send_data_rsp.status = QSEOS_RESULT_FAILURE;
status = QSEOS_RESULT_FAILURE;
} else {
send_data_rsp.status = QSEOS_RESULT_SUCCESS;
status = QSEOS_RESULT_SUCCESS;
}
send_data_rsp.qsee_cmd_id = QSEOS_LISTENER_DATA_RSP_COMMAND;
send_data_rsp.listener_id = lstnr;
table = ptr_svc->sglistinfo_ptr;
if (qseecom.qsee_version < QSEE_VERSION_40) {
send_data_rsp.listener_id = lstnr;
send_data_rsp.status = status;
send_data_rsp.sglistinfo_ptr =
(uint32_t)virt_to_phys(table);
send_data_rsp.sglistinfo_len = SGLISTINFO_TABLE_SIZE;
dmac_flush_range((void *)table,
(void *)table + SGLISTINFO_TABLE_SIZE);
cmd_buf = (void *)&send_data_rsp;
cmd_len = sizeof(send_data_rsp);
} else {
send_data_rsp_64bit.listener_id = lstnr;
send_data_rsp_64bit.status = status;
send_data_rsp_64bit.sglistinfo_ptr =
virt_to_phys(table);
send_data_rsp_64bit.sglistinfo_len =
SGLISTINFO_TABLE_SIZE;
dmac_flush_range((void *)table,
(void *)table + SGLISTINFO_TABLE_SIZE);
cmd_buf = (void *)&send_data_rsp_64bit;
cmd_len = sizeof(send_data_rsp_64bit);
}
if (qseecom.whitelist_support == false)
*(uint32_t *)cmd_buf = QSEOS_LISTENER_DATA_RSP_COMMAND;
else
*(uint32_t *)cmd_buf =
QSEOS_LISTENER_DATA_RSP_COMMAND_WHITELIST;
if (ptr_svc)
msm_ion_do_cache_op(qseecom.ion_clnt, ptr_svc->ihandle,
ptr_svc->sb_virt, ptr_svc->sb_length,
@ -1710,11 +1820,9 @@ static int __qseecom_reentrancy_process_incomplete_cmd(
__qseecom_enable_clk(CLK_QSEE);
ret = qseecom_scm_call(SCM_SVC_TZSCHEDULER, 1,
(const void *)&send_data_rsp,
sizeof(send_data_rsp), resp,
sizeof(*resp));
cmd_buf, cmd_len, resp, sizeof(*resp));
ptr_svc->listener_in_use = false;
__qseecom_clean_listener_sglistinfo(ptr_svc);
wake_up_interruptible(&ptr_svc->listener_block_app_wq);
if (ret) {
@ -2708,7 +2816,7 @@ static int __qseecom_send_cmd(struct qseecom_dev_handle *data,
cmd_len = sizeof(struct qseecom_client_send_data_64bit_ireq);
}
if (qseecom.whitelist_support == false)
if (qseecom.whitelist_support == false || data->use_legacy_cmd == true)
*(uint32_t *)cmd_buf = QSEOS_CLIENT_SEND_DATA_COMMAND;
else
*(uint32_t *)cmd_buf = QSEOS_CLIENT_SEND_DATA_COMMAND_WHITELIST;
@ -2813,6 +2921,8 @@ static int __qseecom_update_cmd_buf(void *msg, bool cleanup,
struct qseecom_send_modfd_cmd_req *req = NULL;
struct qseecom_send_modfd_listener_resp *lstnr_resp = NULL;
struct qseecom_registered_listener_list *this_lstnr = NULL;
uint32_t offset;
struct sg_table *sg_ptr;
if ((data->type != QSEECOM_LISTENER_SERVICE) &&
(data->type != QSEECOM_CLIENT_APP))
@ -2834,7 +2944,6 @@ static int __qseecom_update_cmd_buf(void *msg, bool cleanup,
}
for (i = 0; i < MAX_ION_FD; i++) {
struct sg_table *sg_ptr = NULL;
if ((data->type != QSEECOM_LISTENER_SERVICE) &&
(req->ifd_data[i].fd > 0)) {
ihandle = ion_import_dma_buf(qseecom.ion_clnt,
@ -2976,14 +3085,25 @@ static int __qseecom_update_cmd_buf(void *msg, bool cleanup,
ihandle, NULL, len,
ION_IOC_CLEAN_INV_CACHES);
if (data->type == QSEECOM_CLIENT_APP) {
offset = req->ifd_data[i].cmd_buf_offset;
data->sglistinfo_ptr[i].indexAndFlags =
SGLISTINFO_SET_INDEX_FLAG(
(sg_ptr->nents == 1), 0,
req->ifd_data[i].cmd_buf_offset);
(sg_ptr->nents == 1), 0, offset);
data->sglistinfo_ptr[i].sizeOrCount =
(sg_ptr->nents == 1) ?
sg->length : sg_ptr->nents;
data->sglist_cnt = i + 1;
} else {
offset = (lstnr_resp->ifd_data[i].cmd_buf_offset
+ (uintptr_t)lstnr_resp->resp_buf_ptr -
(uintptr_t)this_lstnr->sb_virt);
this_lstnr->sglistinfo_ptr[i].indexAndFlags =
SGLISTINFO_SET_INDEX_FLAG(
(sg_ptr->nents == 1), 0, offset);
this_lstnr->sglistinfo_ptr[i].sizeOrCount =
(sg_ptr->nents == 1) ?
sg->length : sg_ptr->nents;
this_lstnr->sglist_cnt = i + 1;
}
}
/* Deallocate the handle */
@ -3056,6 +3176,8 @@ static int __qseecom_update_cmd_buf_64(void *msg, bool cleanup,
struct qseecom_send_modfd_cmd_req *req = NULL;
struct qseecom_send_modfd_listener_resp *lstnr_resp = NULL;
struct qseecom_registered_listener_list *this_lstnr = NULL;
uint32_t offset;
struct sg_table *sg_ptr;
if ((data->type != QSEECOM_LISTENER_SERVICE) &&
(data->type != QSEECOM_CLIENT_APP))
@ -3077,7 +3199,6 @@ static int __qseecom_update_cmd_buf_64(void *msg, bool cleanup,
}
for (i = 0; i < MAX_ION_FD; i++) {
struct sg_table *sg_ptr = NULL;
if ((data->type != QSEECOM_LISTENER_SERVICE) &&
(req->ifd_data[i].fd > 0)) {
ihandle = ion_import_dma_buf(qseecom.ion_clnt,
@ -3194,14 +3315,25 @@ cleanup:
ihandle, NULL, len,
ION_IOC_CLEAN_INV_CACHES);
if (data->type == QSEECOM_CLIENT_APP) {
offset = req->ifd_data[i].cmd_buf_offset;
data->sglistinfo_ptr[i].indexAndFlags =
SGLISTINFO_SET_INDEX_FLAG(
(sg_ptr->nents == 1), 1,
req->ifd_data[i].cmd_buf_offset);
(sg_ptr->nents == 1), 1, offset);
data->sglistinfo_ptr[i].sizeOrCount =
(sg_ptr->nents == 1) ?
sg->length : sg_ptr->nents;
data->sglist_cnt = i + 1;
} else {
offset = (lstnr_resp->ifd_data[i].cmd_buf_offset
+ (uintptr_t)lstnr_resp->resp_buf_ptr -
(uintptr_t)this_lstnr->sb_virt);
this_lstnr->sglistinfo_ptr[i].indexAndFlags =
SGLISTINFO_SET_INDEX_FLAG(
(sg_ptr->nents == 1), 1, offset);
this_lstnr->sglistinfo_ptr[i].sizeOrCount =
(sg_ptr->nents == 1) ?
sg->length : sg_ptr->nents;
this_lstnr->sglist_cnt = i + 1;
}
}
/* Deallocate the handle */
@ -3916,21 +4048,12 @@ int qseecom_start_app(struct qseecom_handle **handle,
data->client.user_virt_sb_base = 0;
data->client.ihandle = NULL;
/* Allocate sglistinfo buffer for kernel client */
data->sglistinfo_ptr = kzalloc(SGLISTINFO_TABLE_SIZE, GFP_KERNEL);
if (!(data->sglistinfo_ptr)) {
kfree(data);
kfree(*handle);
*handle = NULL;
return -ENOMEM;
}
init_waitqueue_head(&data->abort_wq);
data->client.ihandle = ion_alloc(qseecom.ion_clnt, size, 4096,
ION_HEAP(ION_QSECOM_HEAP_ID), 0);
if (IS_ERR_OR_NULL(data->client.ihandle)) {
pr_err("Ion client could not retrieve the handle\n");
kfree(data->sglistinfo_ptr);
kfree(data);
kfree(*handle);
*handle = NULL;
@ -4033,7 +4156,6 @@ int qseecom_start_app(struct qseecom_handle **handle,
return 0;
err:
kfree(data->sglistinfo_ptr);
kfree(data);
kfree(*handle);
*handle = NULL;
@ -4075,7 +4197,6 @@ int qseecom_shutdown_app(struct qseecom_handle **handle)
mutex_unlock(&app_access_lock);
if (ret == 0) {
kzfree(data->sglistinfo_ptr);
kzfree(data);
kzfree(*handle);
kzfree(kclient);
@ -4135,8 +4256,11 @@ int qseecom_send_command(struct qseecom_handle *handle, void *send_buf,
}
perf_enabled = true;
}
if (!strcmp(data->client.app_name, "securemm"))
data->use_legacy_cmd = true;
ret = __qseecom_send_cmd(data, &req);
data->use_legacy_cmd = false;
if (qseecom.support_bus_scaling)
__qseecom_add_bw_scale_down_timer(
QSEECOM_SEND_CMD_CRYPTO_TIMEOUT);
@ -6776,6 +6900,7 @@ long qseecom_ioctl(struct file *file, unsigned cmd, unsigned long arg)
wake_up_all(&data->abort_wq);
if (ret)
pr_err("failed qseecom_send_mod_resp: %d\n", ret);
__qseecom_clean_data_sglistinfo(data);
break;
}
case QSEECOM_QTEEC_IOCTL_OPEN_SESSION_REQ: {
@ -6901,12 +7026,6 @@ static int qseecom_open(struct inode *inode, struct file *file)
data->mode = INACTIVE;
init_waitqueue_head(&data->abort_wq);
atomic_set(&data->ioctl_count, 0);
data->sglistinfo_ptr = kzalloc(SGLISTINFO_TABLE_SIZE, GFP_KERNEL);
if (!(data->sglistinfo_ptr)) {
kzfree(data);
return -ENOMEM;
}
return ret;
}
@ -6961,7 +7080,6 @@ static int qseecom_release(struct inode *inode, struct file *file)
if (data->perf_enabled == true)
qsee_disable_clock_vote(data, CLK_DFAB);
}
kfree(data->sglistinfo_ptr);
kfree(data);
return ret;
@ -7103,73 +7221,14 @@ static void __qseecom_deinit_clk(enum qseecom_ce_hw_instance ce)
}
/*
* Check if whitelist feature is supported by making a test scm_call
* to send a whitelist command to an invalid app ID 0
* Check whitelist feature, and if TZ feature version is < 1.0.0,
* then whitelist feature is not supported.
*/
static int qseecom_check_whitelist_feature(void)
{
struct qseecom_client_send_data_ireq send_data_req = {0};
struct qseecom_client_send_data_64bit_ireq send_data_req_64bit = {0};
struct qseecom_command_scm_resp resp;
uint32_t buf_size = 128;
void *buf = NULL;
void *cmd_buf = NULL;
size_t cmd_len;
int ret = 0;
phys_addr_t pa;
int version = scm_get_feat_version(FEATURE_ID_WHITELIST);
buf = kzalloc(buf_size, GFP_KERNEL);
if (!buf)
return -ENOMEM;
pa = virt_to_phys(buf);
if (qseecom.qsee_version < QSEE_VERSION_40) {
send_data_req.qsee_cmd_id =
QSEOS_CLIENT_SEND_DATA_COMMAND_WHITELIST;
send_data_req.app_id = 0;
send_data_req.req_ptr = (uint32_t)pa;
send_data_req.req_len = buf_size;
send_data_req.rsp_ptr = (uint32_t)pa;
send_data_req.rsp_len = buf_size;
send_data_req.sglistinfo_ptr = (uint32_t)pa;
send_data_req.sglistinfo_len = buf_size;
cmd_buf = (void *)&send_data_req;
cmd_len = sizeof(struct qseecom_client_send_data_ireq);
} else {
send_data_req_64bit.qsee_cmd_id =
QSEOS_CLIENT_SEND_DATA_COMMAND_WHITELIST;
send_data_req_64bit.app_id = 0;
send_data_req_64bit.req_ptr = (uint64_t)pa;
send_data_req_64bit.req_len = buf_size;
send_data_req_64bit.rsp_ptr = (uint64_t)pa;
send_data_req_64bit.rsp_len = buf_size;
send_data_req_64bit.sglistinfo_ptr = (uint64_t)pa;
send_data_req_64bit.sglistinfo_len = buf_size;
cmd_buf = (void *)&send_data_req_64bit;
cmd_len = sizeof(struct qseecom_client_send_data_64bit_ireq);
}
ret = qseecom_scm_call(SCM_SVC_TZSCHEDULER, 1,
cmd_buf, cmd_len,
&resp, sizeof(resp));
/*
* If this cmd exists and whitelist is supported, scm_call return -2 (scm
* driver remap it to -EINVAL) and resp.result 0xFFFFFFED(-19); Otherwise,
* scm_call return -1 (remap to -EIO).
*/
if (ret == -EIO) {
qseecom.whitelist_support = false;
ret = 0;
} else if (ret == -EINVAL &&
resp.result == QSEOS_RESULT_FAIL_SEND_CMD_NO_THREAD) {
qseecom.whitelist_support = true;
ret = 0;
} else {
pr_info("Check whitelist with ret = %d, result = 0x%x\n",
ret, resp.result);
qseecom.whitelist_support = false;
ret = 0;
}
kfree(buf);
return ret;
return version >= MAKE_WHITELIST_VERSION(1, 0, 0);
}
static int qseecom_probe(struct platform_device *pdev)
@ -7498,11 +7557,7 @@ static int qseecom_probe(struct platform_device *pdev)
qseecom.qsee_perf_client = msm_bus_scale_register_client(
qseecom_platform_support);
rc = qseecom_check_whitelist_feature();
if (rc) {
rc = -EINVAL;
goto exit_destroy_ion_client;
}
qseecom.whitelist_support = qseecom_check_whitelist_feature();
pr_warn("qseecom.whitelist_support = %d\n",
qseecom.whitelist_support);

View File

@ -78,6 +78,7 @@ enum qseecom_qceos_cmd_id {
QSEOS_CLIENT_SEND_DATA_COMMAND_WHITELIST = 0x1C,
QSEOS_TEE_OPEN_SESSION_WHITELIST = 0x1D,
QSEOS_TEE_INVOKE_COMMAND_WHITELIST = 0x1E,
QSEOS_LISTENER_DATA_RSP_COMMAND_WHITELIST = 0x1F,
QSEOS_FSM_OEM_FUSE_WRITE_ROW = 0x301,
QSEOS_FSM_OEM_FUSE_READ_ROW = 0x302,
QSEOS_CMD_MAX = 0xEFFFFFFF
@ -211,6 +212,16 @@ __packed struct qseecom_client_listener_data_irsp {
uint32_t qsee_cmd_id;
uint32_t listener_id;
uint32_t status;
uint32_t sglistinfo_ptr;
uint32_t sglistinfo_len;
};
__packed struct qseecom_client_listener_data_64bit_irsp {
uint32_t qsee_cmd_id;
uint32_t listener_id;
uint32_t status;
uint64_t sglistinfo_ptr;
uint32_t sglistinfo_len;
};
/*
@ -679,4 +690,12 @@ __packed struct qseecom_client_send_fsm_key_req {
TZ_SYSCALL_PARAM_TYPE_VAL, TZ_SYSCALL_PARAM_TYPE_BUF_RW, \
TZ_SYSCALL_PARAM_TYPE_VAL)
#define TZ_OS_LISTENER_RESPONSE_HANDLER_WITH_WHITELIST_ID \
TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_QSEE_OS, TZ_SVC_LISTENER, 0x05)
#define TZ_OS_LISTENER_RESPONSE_HANDLER_WITH_WHITELIST_PARAM_ID \
TZ_SYSCALL_CREATE_PARAM_ID_4( \
TZ_SYSCALL_PARAM_TYPE_VAL, TZ_SYSCALL_PARAM_TYPE_VAL, \
TZ_SYSCALL_PARAM_TYPE_BUF_RW, TZ_SYSCALL_PARAM_TYPE_VAL)
#endif /* __QSEECOMI_H_ */