static long cmdq_driver_create_secure_medadata(cmdqCommandStruct *pCommand) { void *pAddrMetadatas = NULL; const uint32_t length = (pCommand->secData.addrMetadataCount) * sizeof(cmdqSecAddrMetadataStruct); /* verify parameter */ if ((false == pCommand->secData.isSecure) && (0 != pCommand->secData.addrMetadataCount)) { /* normal path with non-zero secure metadata */ CMDQ_ERR ("[secData]mismatch secData.isSecure(%d) and secData.addrMetadataCount(%d)\n", pCommand->secData.isSecure, pCommand->secData.addrMetadataCount); return -EFAULT; } /* revise max count field */ pCommand->secData.addrMetadataMaxCount = pCommand->secData.addrMetadataCount; /* bypass 0 metadata case */ if (0 == pCommand->secData.addrMetadataCount) { pCommand->secData.addrMetadatas = (cmdqU32Ptr_t) (unsigned long)NULL; return 0; } /* create kernel-space buffer for working */ pAddrMetadatas = kzalloc(length, GFP_KERNEL); if (NULL == pAddrMetadatas) { CMDQ_ERR("[secData]kzalloc for addrMetadatas failed, count:%d, alloacted_size:%d\n", pCommand->secData.addrMetadataCount, length); return -ENOMEM; } /* copy from user */ if (copy_from_user(pAddrMetadatas, CMDQ_U32_PTR(pCommand->secData.addrMetadatas), length)) { CMDQ_ERR("[secData]fail to copy user addrMetadatas\n"); /* replace buffer first to ensure that */ /* addrMetadatas is valid kernel space buffer address when free it */ pCommand->secData.addrMetadatas = (cmdqU32Ptr_t) (unsigned long)pAddrMetadatas; /* free secure path metadata */ cmdq_driver_destroy_secure_medadata(pCommand); return -EFAULT; } /* replace buffer */ pCommand->secData.addrMetadatas = (cmdqU32Ptr_t) (unsigned long)pAddrMetadatas; #if 0 cmdq_core_dump_secure_metadata(&(pCommand->secData)); #endif return 0; }
int32_t cmdq_sec_submit_to_secure_world_async_unlocked(uint32_t iwcCommand, TaskStruct *pTask, int32_t thread, CmdqSecFillIwcCB iwcFillCB, void *data) { const int32_t tgid = current->tgid; const int32_t pid = current->pid; cmdqSecContextHandle handle = NULL; int32_t status = 0; int32_t duration = 0; CMDQ_TIME tEntrySec; CMDQ_TIME tExitSec; CMDQ_MSG("[SEC]-->SEC_SUBMIT: tgid[%d:%d]\n", tgid, pid); do { /* find handle first */ /* Unlike tBase user space API, * tBase kernel API maintains a GLOBAL table to control mobicore device reference count. * For kernel spece user, mc_open_device and session_handle don't depend on the process context. * Therefore we use global secssion handle to inter-world commumication. */ if(NULL == gCmdqSecContextHandle) { gCmdqSecContextHandle = cmdq_sec_context_handle_create(current->tgid); } handle = gCmdqSecContextHandle; if (NULL == handle) { CMDQ_ERR("SEC_SUBMIT: tgid %d err[NULL secCtxHandle]\n", tgid); status = -(CMDQ_ERR_NULL_SEC_CTX_HANDLE); break; } if (0 > cmdq_sec_setup_context_session(handle)) { status = -(CMDQ_ERR_SEC_CTX_SETUP); break; } tEntrySec = sched_clock(); status = cmdq_sec_send_context_session_message( handle, iwcCommand, pTask, thread, iwcFillCB, data); tExitSec = sched_clock(); CMDQ_GET_TIME_IN_US_PART(tEntrySec, tExitSec, duration); cmdq_sec_track_task_record(iwcCommand, pTask, &tEntrySec, &tExitSec); /* release resource */ #if !(CMDQ_OPEN_SESSION_ONCE) cmdq_sec_teardown_context_session(handle) #endif /* Note we entry secure for config only and wait result in normal world. */ /* No need reset module HW for config failed case*/ } while (0); if (-ETIMEDOUT == status) { /* t-base strange issue, mc_wait_notification false timeout when secure world has done */ /* becuase retry may failed, give up retry method */ CMDQ_AEE("CMDQ", "[SEC]<--SEC_SUBMIT: err[%d][mc_wait_notification timeout], pTask[0x%p], THR[%d], tgid[%d:%d], config_duration_ms[%d], cmdId[%d]\n", status, pTask, thread, tgid, pid, duration, iwcCommand); } else if (0 > status) { /* dump metadata first */ if (pTask) { cmdq_core_dump_secure_metadata(&(pTask->secData)); } /* throw AEE */ CMDQ_AEE("CMDQ", "[SEC]<--SEC_SUBMIT: err[%d], pTask[0x%p], THR[%d], tgid[%d:%d], config_duration_ms[%d], cmdId[%d]\n", status, pTask, thread, tgid, pid, duration, iwcCommand); } else { CMDQ_LOG ("[SEC]<--SEC_SUBMIT: err[%d], pTask[0x%p], THR[%d], tgid[%d:%d], config_duration_ms[%d], cmdId[%d]\n", status, pTask, thread, tgid, pid, duration, iwcCommand); } return status; }