Merge "qseecom: Change in buffer sharing mechanism in qseecom"

This commit is contained in:
qctecmdr 2020-07-20 08:45:50 -07:00 • committed by Gerrit - the friendly Code Review server
commit a539b642f4

View file

@ -460,6 +460,10 @@ static int __maybe_unused get_qseecom_keymaster_status(char *str)
}
__setup("androidboot.keymaster=", get_qseecom_keymaster_status);
static int __qseecom_alloc_coherent_buf(
uint32_t size, u8 **vaddr, phys_addr_t *paddr);
static void __qseecom_free_coherent_buf(uint32_t size,
u8 *vaddr, phys_addr_t paddr);
#define QSEECOM_SCM_EBUSY_WAIT_MS 30
#define QSEECOM_SCM_EBUSY_MAX_RETRY 67
@ -3662,7 +3666,8 @@ static int __qseecom_process_reentrancy(struct qseecom_command_scm_resp *resp,
}
static int __qseecom_send_cmd(struct qseecom_dev_handle *data,
struct qseecom_send_cmd_req *req)
struct qseecom_send_cmd_req *req,
bool is_phys_adr)
{
int ret = 0;
u32 reqd_len_sb_in = 0;
@ -3703,11 +3708,20 @@ static int __qseecom_send_cmd(struct qseecom_dev_handle *data,
if (qseecom.qsee_version < QSEE_VERSION_40) {
send_data_req.app_id = data->client.app_id;
send_data_req.req_ptr = (uint32_t)(__qseecom_uvirt_to_kphys(
data, (uintptr_t)req->cmd_req_buf));
if (!is_phys_adr) {
send_data_req.req_ptr =
(uint32_t)(__qseecom_uvirt_to_kphys
(data, (uintptr_t)req->cmd_req_buf));
send_data_req.rsp_ptr =
(uint32_t)(__qseecom_uvirt_to_kphys(
data, (uintptr_t)req->resp_buf));
} else {
send_data_req.req_ptr = (uint32_t)req->cmd_req_buf;
send_data_req.rsp_ptr = (uint32_t)req->resp_buf;
}
send_data_req.req_len = req->cmd_req_len;
send_data_req.rsp_ptr = (uint32_t)(__qseecom_uvirt_to_kphys(
data, (uintptr_t)req->resp_buf));
send_data_req.rsp_len = req->resp_len;
send_data_req.sglistinfo_ptr =
(uint32_t)data->sglistinfo_shm.paddr;
@ -3717,11 +3731,21 @@ static int __qseecom_send_cmd(struct qseecom_dev_handle *data,
cmd_len = sizeof(struct qseecom_client_send_data_ireq);
} else {
send_data_req_64bit.app_id = data->client.app_id;
send_data_req_64bit.req_ptr = __qseecom_uvirt_to_kphys(data,
(uintptr_t)req->cmd_req_buf);
if (!is_phys_adr) {
send_data_req_64bit.req_ptr =
__qseecom_uvirt_to_kphys(data,
(uintptr_t)req->cmd_req_buf);
send_data_req_64bit.rsp_ptr =
__qseecom_uvirt_to_kphys(data,
(uintptr_t)req->resp_buf);
} else {
send_data_req_64bit.req_ptr =
(uintptr_t)req->cmd_req_buf;
send_data_req_64bit.rsp_ptr =
(uintptr_t)req->resp_buf;
}
send_data_req_64bit.req_len = req->cmd_req_len;
send_data_req_64bit.rsp_ptr = __qseecom_uvirt_to_kphys(data,
(uintptr_t)req->resp_buf);
send_data_req_64bit.rsp_len = req->resp_len;
/* check if 32bit app's phys_addr region is under 4GB.*/
if ((data->client.app_arch == ELFCLASS32) &&
@ -3818,7 +3842,7 @@ static int qseecom_send_cmd(struct qseecom_dev_handle *data, void __user *argp)
if (__validate_send_cmd_inputs(data, &req))
return -EINVAL;
ret = __qseecom_send_cmd(data, &req);
ret = __qseecom_send_cmd(data, &req, false);
return ret;
}
@ -4336,6 +4360,9 @@ static int __qseecom_send_modfd_cmd(struct qseecom_dev_handle *data,
int i;
struct qseecom_send_modfd_cmd_req req;
struct qseecom_send_cmd_req send_cmd_req;
void *origin_req_buf_kvirt, *origin_rsp_buf_kvirt;
phys_addr_t pa;
u8 *va = NULL;
ret = copy_from_user(&req, argp, sizeof(req));
if (ret) {
@ -4359,33 +4386,57 @@ static int __qseecom_send_modfd_cmd(struct qseecom_dev_handle *data,
return -EINVAL;
}
}
req.cmd_req_buf = (void *)__qseecom_uvirt_to_kvirt(data,
(uintptr_t)req.cmd_req_buf);
req.resp_buf = (void *)__qseecom_uvirt_to_kvirt(data,
(uintptr_t)req.resp_buf);
/*Back up original address */
origin_req_buf_kvirt = (void *)__qseecom_uvirt_to_kvirt(data,
(uintptr_t)req.cmd_req_buf);
origin_rsp_buf_kvirt = (void *)__qseecom_uvirt_to_kvirt(data,
(uintptr_t)req.resp_buf);
/* Allocate kernel buffer for request and response*/
ret = __qseecom_alloc_coherent_buf(req.cmd_req_len + req.resp_len,
&va, &pa);
req.cmd_req_buf = va;
send_cmd_req.cmd_req_buf = (void *)pa;
req.resp_buf = va + req.cmd_req_len;
send_cmd_req.resp_buf = (void *)pa + req.cmd_req_len;
/* Copy the data to kernel request and response buffers*/
memcpy(req.cmd_req_buf, origin_req_buf_kvirt, req.cmd_req_len);
memcpy(req.resp_buf, origin_rsp_buf_kvirt, req.resp_len);
if (!is_64bit_addr) {
ret = __qseecom_update_cmd_buf(&req, false, data);
if (ret)
return ret;
ret = __qseecom_send_cmd(data, &send_cmd_req);
goto out;
ret = __qseecom_send_cmd(data, &send_cmd_req, true);
if (ret)
return ret;
goto out;
ret = __qseecom_update_cmd_buf(&req, true, data);
if (ret)
return ret;
goto out;
} else {
ret = __qseecom_update_cmd_buf_64(&req, false, data);
if (ret)
return ret;
ret = __qseecom_send_cmd(data, &send_cmd_req);
goto out;
ret = __qseecom_send_cmd(data, &send_cmd_req, true);
if (ret)
return ret;
goto out;
ret = __qseecom_update_cmd_buf_64(&req, true, data);
if (ret)
return ret;
goto out;
}
/*Copy the response back to the userspace buffer*/
memcpy(origin_rsp_buf_kvirt, req.resp_buf, req.resp_len);
memcpy(origin_req_buf_kvirt, req.cmd_req_buf, req.cmd_req_len);
out:
if (req.cmd_req_buf)
__qseecom_free_coherent_buf(req.cmd_req_len + req.resp_len,
req.cmd_req_buf, (phys_addr_t)send_cmd_req.cmd_req_buf);
return ret;
}
@ -5251,7 +5302,7 @@ int qseecom_send_command(struct qseecom_handle *handle, void *send_buf,
if (!strcmp(data->client.app_name, "securemm"))
data->use_legacy_cmd = true;
ret = __qseecom_send_cmd(data, &req);
ret = __qseecom_send_cmd(data, &req, false);
data->use_legacy_cmd = false;
if (qseecom.support_bus_scaling)