Add new smc invoke interface for Trustonic TEE driver.

In kernel 5.4, the old qcom interface scm_call2() has been abandoned, so
add new function trustonic_smc_fastcall() for Trustonic TEE driver module,
and it will send syscall to the secure world through new qcom scm interface.

Change-Id: Ib76c00e9910be6796fc71bdcfaf4352fd8f2806c
Signed-off-by: linyx10 <linyx10@lenovo.com>
Reviewed-on: https://gerrit.mot.com/1836283
SLTApproved: Slta Waiver
SME-Granted: SME Approvals Granted
Tested-by: Jira Key
Reviewed-by: Zhenxin Xi <xizx@motorola.com>
Submit-Approved: Jira Key
This commit is contained in:
linyx10 2020-12-24 10:30:15 +08:00 • committed by Xiaojun Ji
commit adc9d546d5
4 changed files with 75 additions and 0 deletions

View file

@ -28,6 +28,10 @@
#define MAX_QCOM_SCM_ARGS 10
#define MAX_QCOM_SCM_RETS 3
#define SCM_SVC_MOBICORE 250
#define SCM_CMD_MOBICORE 1
#define ARM_SMCCC_OWNER_MOBI_OS 51
#define QCOM_SCM_ATOMIC BIT(0)
#define QCOM_SCM_NORETRY BIT(1)
@ -2388,6 +2392,69 @@ int __qcom_scm_invoke_smc(struct device *dev, phys_addr_t in_buf,
return ret;
}
int __trustonic_smc_fastcall(void *fc_generic, size_t size)
{
int ret;
struct qcom_scm_desc desc = {
.svc = SCM_SVC_MOBICORE,
.cmd = SCM_CMD_MOBICORE,
.owner = ARM_SMCCC_OWNER_MOBI_OS
};
void *scm_buf_va = NULL;
phys_addr_t scm_buf_pa;
struct qtee_shm scm_shm = {0};
if (qtee_shmbridge_is_enabled()) {
ret = qtee_shmbridge_allocate_shm(PAGE_ALIGN(size), &scm_shm);
if (ret)
return ret;
}
else {
scm_shm.vaddr = kzalloc(PAGE_ALIGN(size), GFP_KERNEL);
if (!scm_shm.vaddr)
return -ENOMEM;
scm_shm.paddr = dma_map_single(NULL, scm_shm.vaddr, size, DMA_TO_DEVICE);
if (dma_mapping_error(NULL, scm_shm.paddr)) {
kfree(scm_shm.vaddr);
return -ENOMEM;
}
}
scm_buf_va = scm_shm.vaddr;
scm_buf_pa = scm_shm.paddr;
if (!scm_buf_va)
return -ENOMEM;
memset(scm_buf_va, 0, size);
memcpy(scm_buf_va, fc_generic, size);
qtee_shmbridge_flush_shm_buf(&scm_shm);
desc.args[0] = scm_buf_pa;
desc.args[1] = (u32)size;
desc.args[2] = scm_buf_pa;
desc.args[3] = (u32)size;
desc.arginfo = QCOM_SCM_ARGS(4, QCOM_SCM_RW, QCOM_SCM_VAL, QCOM_SCM_RW, QCOM_SCM_VAL);
ret = qcom_scm_call(NULL, &desc);
qtee_shmbridge_flush_shm_buf(&scm_shm);
memcpy(fc_generic, scm_buf_va, size);
if (qtee_shmbridge_is_enabled()) {
qtee_shmbridge_free_shm(&scm_shm);
}
else {
dma_unmap_single(NULL, scm_shm.paddr, size, DMA_TO_DEVICE);
kfree(scm_shm.vaddr);
}
return ret;
}
int __qcom_scm_invoke_callback_response(struct device *dev, phys_addr_t out_buf,
size_t out_buf_size, int32_t *result, u64 *response_type,
unsigned int *data)

View file

@ -1065,6 +1065,12 @@ int qcom_scm_invoke_smc(phys_addr_t in_buf, size_t in_buf_size,
}
EXPORT_SYMBOL(qcom_scm_invoke_smc);
int trustonic_smc_fastcall(void *fc_generic, size_t size)
{
return __trustonic_smc_fastcall(fc_generic, size);
}
EXPORT_SYMBOL(trustonic_smc_fastcall);
int qcom_scm_invoke_callback_response(phys_addr_t out_buf,
size_t out_buf_size, int32_t *result, u64 *response_type,
unsigned int *data)

View file

@ -297,6 +297,7 @@ extern int __qcom_scm_invoke_smc_legacy(struct device *dev, phys_addr_t in_buf,
extern int __qcom_scm_invoke_smc(struct device *dev, phys_addr_t in_buf,
size_t in_buf_size, phys_addr_t out_buf, size_t out_buf_size,
int32_t *result, u64 *response_type, unsigned int *data);
extern int __trustonic_smc_fastcall(void *fc_generic, size_t size);
extern int __qcom_scm_invoke_callback_response(struct device *dev,
phys_addr_t out_buf, size_t out_buf_size, int32_t *result,
u64 *response_type, unsigned int *data);

View file

@ -208,6 +208,7 @@ extern int qcom_scm_invoke_smc_legacy(phys_addr_t in_buf, size_t in_buf_size,
extern int qcom_scm_invoke_smc(phys_addr_t in_buf, size_t in_buf_size,
phys_addr_t out_buf, size_t out_buf_size, int32_t *result,
u64 *response_type, unsigned int *data);
extern int trustonic_smc_fastcall(void *fc_generic, size_t size);
extern int qcom_scm_invoke_callback_response(phys_addr_t out_buf,
size_t out_buf_size, int32_t *result, u64 *response_type,
unsigned int *data);