10d163575Sopenharmony_ci/* 20d163575Sopenharmony_ci * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. 30d163575Sopenharmony_ci * Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved. 40d163575Sopenharmony_ci * 50d163575Sopenharmony_ci * Redistribution and use in source and binary forms, with or without modification, 60d163575Sopenharmony_ci * are permitted provided that the following conditions are met: 70d163575Sopenharmony_ci * 80d163575Sopenharmony_ci * 1. Redistributions of source code must retain the above copyright notice, this list of 90d163575Sopenharmony_ci * conditions and the following disclaimer. 100d163575Sopenharmony_ci * 110d163575Sopenharmony_ci * 2. Redistributions in binary form must reproduce the above copyright notice, this list 120d163575Sopenharmony_ci * of conditions and the following disclaimer in the documentation and/or other materials 130d163575Sopenharmony_ci * provided with the distribution. 140d163575Sopenharmony_ci * 150d163575Sopenharmony_ci * 3. Neither the name of the copyright holder nor the names of its contributors may be used 160d163575Sopenharmony_ci * to endorse or promote products derived from this software without specific prior written 170d163575Sopenharmony_ci * permission. 180d163575Sopenharmony_ci * 190d163575Sopenharmony_ci * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 200d163575Sopenharmony_ci * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 210d163575Sopenharmony_ci * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 220d163575Sopenharmony_ci * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 230d163575Sopenharmony_ci * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 240d163575Sopenharmony_ci * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 250d163575Sopenharmony_ci * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 260d163575Sopenharmony_ci * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 270d163575Sopenharmony_ci * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 280d163575Sopenharmony_ci * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 290d163575Sopenharmony_ci * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 300d163575Sopenharmony_ci */ 310d163575Sopenharmony_ci 320d163575Sopenharmony_ci#include "hm_liteipc.h" 330d163575Sopenharmony_ci#include "linux/kernel.h" 340d163575Sopenharmony_ci#include "fs/file.h" 350d163575Sopenharmony_ci#include "fs/driver.h" 360d163575Sopenharmony_ci#include "los_init.h" 370d163575Sopenharmony_ci#include "los_mp.h" 380d163575Sopenharmony_ci#include "los_mux.h" 390d163575Sopenharmony_ci#include "los_process_pri.h" 400d163575Sopenharmony_ci#include "los_sched_pri.h" 410d163575Sopenharmony_ci#include "los_spinlock.h" 420d163575Sopenharmony_ci#include "los_task_pri.h" 430d163575Sopenharmony_ci#include "los_vm_lock.h" 440d163575Sopenharmony_ci#include "los_vm_map.h" 450d163575Sopenharmony_ci#include "los_vm_page.h" 460d163575Sopenharmony_ci#include "los_vm_phys.h" 470d163575Sopenharmony_ci#include "los_hook.h" 480d163575Sopenharmony_ci 490d163575Sopenharmony_ci#define USE_TASKID_AS_HANDLE 1 500d163575Sopenharmony_ci#define USE_MMAP 1 510d163575Sopenharmony_ci#define IPC_IO_DATA_MAX 8192UL 520d163575Sopenharmony_ci#define IPC_MSG_DATA_SZ_MAX (IPC_IO_DATA_MAX * sizeof(SpecialObj) / (sizeof(SpecialObj) + sizeof(size_t))) 530d163575Sopenharmony_ci#define IPC_MSG_OBJECT_NUM_MAX (IPC_MSG_DATA_SZ_MAX / sizeof(SpecialObj)) 540d163575Sopenharmony_ci 550d163575Sopenharmony_ci#define LITE_IPC_POOL_NAME "liteipc" 560d163575Sopenharmony_ci#define LITE_IPC_POOL_PAGE_MAX_NUM 64 /* 256KB */ 570d163575Sopenharmony_ci#define LITE_IPC_POOL_PAGE_DEFAULT_NUM 16 /* 64KB */ 580d163575Sopenharmony_ci#define LITE_IPC_POOL_MAX_SIZE (LITE_IPC_POOL_PAGE_MAX_NUM << PAGE_SHIFT) 590d163575Sopenharmony_ci#define LITE_IPC_POOL_DEFAULT_SIZE (LITE_IPC_POOL_PAGE_DEFAULT_NUM << PAGE_SHIFT) 600d163575Sopenharmony_ci#define LITE_IPC_POOL_UVADDR 0x10000000 610d163575Sopenharmony_ci#define INVAILD_ID (-1) 620d163575Sopenharmony_ci 630d163575Sopenharmony_ci#define LITEIPC_TIMEOUT_MS 5000UL 640d163575Sopenharmony_ci#define LITEIPC_TIMEOUT_NS 5000000000ULL 650d163575Sopenharmony_ci 660d163575Sopenharmony_ci#define MAJOR_VERSION (2) 670d163575Sopenharmony_ci#define MINOR_VERSION (0) 680d163575Sopenharmony_ci#define DRIVER_VERSION (MAJOR_VERSION | MINOR_VERSION << 16) 690d163575Sopenharmony_ci 700d163575Sopenharmony_citypedef struct { 710d163575Sopenharmony_ci LOS_DL_LIST list; 720d163575Sopenharmony_ci VOID *ptr; 730d163575Sopenharmony_ci} IpcUsedNode; 740d163575Sopenharmony_ci 750d163575Sopenharmony_ciSTATIC LosMux g_serviceHandleMapMux; 760d163575Sopenharmony_ci#if (USE_TASKID_AS_HANDLE == 1) 770d163575Sopenharmony_ciSTATIC HandleInfo g_cmsTask; 780d163575Sopenharmony_ci#else 790d163575Sopenharmony_ciSTATIC HandleInfo g_serviceHandleMap[MAX_SERVICE_NUM]; 800d163575Sopenharmony_ci#endif 810d163575Sopenharmony_ciSTATIC LOS_DL_LIST g_ipcPendlist; 820d163575Sopenharmony_ci 830d163575Sopenharmony_ci/* ipc lock */ 840d163575Sopenharmony_ciSPIN_LOCK_INIT(g_ipcSpin); 850d163575Sopenharmony_ci#define IPC_LOCK(state) LOS_SpinLockSave(&g_ipcSpin, &(state)) 860d163575Sopenharmony_ci#define IPC_UNLOCK(state) LOS_SpinUnlockRestore(&g_ipcSpin, state) 870d163575Sopenharmony_ci 880d163575Sopenharmony_ciSTATIC int LiteIpcOpen(struct file *filep); 890d163575Sopenharmony_ciSTATIC int LiteIpcClose(struct file *filep); 900d163575Sopenharmony_ciSTATIC int LiteIpcIoctl(struct file *filep, int cmd, unsigned long arg); 910d163575Sopenharmony_ciSTATIC int LiteIpcMmap(struct file* filep, LosVmMapRegion *region); 920d163575Sopenharmony_ciSTATIC UINT32 LiteIpcWrite(IpcContent *content); 930d163575Sopenharmony_ciSTATIC UINT32 GetTid(UINT32 serviceHandle, UINT32 *taskID); 940d163575Sopenharmony_ciSTATIC UINT32 HandleSpecialObjects(UINT32 dstTid, IpcListNode *node, BOOL isRollback); 950d163575Sopenharmony_ciSTATIC ProcIpcInfo *LiteIpcPoolCreate(VOID); 960d163575Sopenharmony_ci 970d163575Sopenharmony_ciSTATIC const struct file_operations_vfs g_liteIpcFops = { 980d163575Sopenharmony_ci .open = LiteIpcOpen, /* open */ 990d163575Sopenharmony_ci .close = LiteIpcClose, /* close */ 1000d163575Sopenharmony_ci .ioctl = LiteIpcIoctl, /* ioctl */ 1010d163575Sopenharmony_ci .mmap = LiteIpcMmap, /* mmap */ 1020d163575Sopenharmony_ci}; 1030d163575Sopenharmony_ci 1040d163575Sopenharmony_ciLITE_OS_SEC_TEXT_INIT UINT32 OsLiteIpcInit(VOID) 1050d163575Sopenharmony_ci{ 1060d163575Sopenharmony_ci UINT32 ret; 1070d163575Sopenharmony_ci#if (USE_TASKID_AS_HANDLE == 1) 1080d163575Sopenharmony_ci g_cmsTask.status = HANDLE_NOT_USED; 1090d163575Sopenharmony_ci#else 1100d163575Sopenharmony_ci (void)memset_s(g_serviceHandleMap, sizeof(g_serviceHandleMap), 0, sizeof(g_serviceHandleMap)); 1110d163575Sopenharmony_ci#endif 1120d163575Sopenharmony_ci ret = LOS_MuxInit(&g_serviceHandleMapMux, NULL); 1130d163575Sopenharmony_ci if (ret != LOS_OK) { 1140d163575Sopenharmony_ci return ret; 1150d163575Sopenharmony_ci } 1160d163575Sopenharmony_ci ret = (UINT32)register_driver(LITEIPC_DRIVER, &g_liteIpcFops, LITEIPC_DRIVER_MODE, NULL); 1170d163575Sopenharmony_ci if (ret != LOS_OK) { 1180d163575Sopenharmony_ci PRINT_ERR("register lite_ipc driver failed:%d\n", ret); 1190d163575Sopenharmony_ci } 1200d163575Sopenharmony_ci LOS_ListInit(&(g_ipcPendlist)); 1210d163575Sopenharmony_ci 1220d163575Sopenharmony_ci return ret; 1230d163575Sopenharmony_ci} 1240d163575Sopenharmony_ci 1250d163575Sopenharmony_ciLOS_MODULE_INIT(OsLiteIpcInit, LOS_INIT_LEVEL_KMOD_EXTENDED); 1260d163575Sopenharmony_ci 1270d163575Sopenharmony_ciLITE_OS_SEC_TEXT STATIC int LiteIpcOpen(struct file *filep) 1280d163575Sopenharmony_ci{ 1290d163575Sopenharmony_ci LosProcessCB *pcb = OsCurrProcessGet(); 1300d163575Sopenharmony_ci if (pcb->ipcInfo != NULL) { 1310d163575Sopenharmony_ci return 0; 1320d163575Sopenharmony_ci } 1330d163575Sopenharmony_ci 1340d163575Sopenharmony_ci pcb->ipcInfo = LiteIpcPoolCreate(); 1350d163575Sopenharmony_ci if (pcb->ipcInfo == NULL) { 1360d163575Sopenharmony_ci return -ENOMEM; 1370d163575Sopenharmony_ci } 1380d163575Sopenharmony_ci 1390d163575Sopenharmony_ci return 0; 1400d163575Sopenharmony_ci} 1410d163575Sopenharmony_ci 1420d163575Sopenharmony_ciLITE_OS_SEC_TEXT STATIC int LiteIpcClose(struct file *filep) 1430d163575Sopenharmony_ci{ 1440d163575Sopenharmony_ci return 0; 1450d163575Sopenharmony_ci} 1460d163575Sopenharmony_ci 1470d163575Sopenharmony_ciLITE_OS_SEC_TEXT STATIC BOOL IsPoolMapped(ProcIpcInfo *ipcInfo) 1480d163575Sopenharmony_ci{ 1490d163575Sopenharmony_ci return (ipcInfo->pool.uvaddr != NULL) && (ipcInfo->pool.kvaddr != NULL) && 1500d163575Sopenharmony_ci (ipcInfo->pool.poolSize != 0); 1510d163575Sopenharmony_ci} 1520d163575Sopenharmony_ci 1530d163575Sopenharmony_ciLITE_OS_SEC_TEXT STATIC INT32 DoIpcMmap(LosProcessCB *pcb, LosVmMapRegion *region) 1540d163575Sopenharmony_ci{ 1550d163575Sopenharmony_ci UINT32 i; 1560d163575Sopenharmony_ci INT32 ret = 0; 1570d163575Sopenharmony_ci PADDR_T pa; 1580d163575Sopenharmony_ci UINT32 uflags = VM_MAP_REGION_FLAG_PERM_READ | VM_MAP_REGION_FLAG_PERM_USER; 1590d163575Sopenharmony_ci LosVmPage *vmPage = NULL; 1600d163575Sopenharmony_ci VADDR_T uva = (VADDR_T)(UINTPTR)pcb->ipcInfo->pool.uvaddr; 1610d163575Sopenharmony_ci VADDR_T kva = (VADDR_T)(UINTPTR)pcb->ipcInfo->pool.kvaddr; 1620d163575Sopenharmony_ci 1630d163575Sopenharmony_ci (VOID)LOS_MuxAcquire(&pcb->vmSpace->regionMux); 1640d163575Sopenharmony_ci 1650d163575Sopenharmony_ci for (i = 0; i < (region->range.size >> PAGE_SHIFT); i++) { 1660d163575Sopenharmony_ci pa = LOS_PaddrQuery((VOID *)(UINTPTR)(kva + (i << PAGE_SHIFT))); 1670d163575Sopenharmony_ci if (pa == 0) { 1680d163575Sopenharmony_ci PRINT_ERR("%s, %d\n", __FUNCTION__, __LINE__); 1690d163575Sopenharmony_ci ret = -EINVAL; 1700d163575Sopenharmony_ci break; 1710d163575Sopenharmony_ci } 1720d163575Sopenharmony_ci vmPage = LOS_VmPageGet(pa); 1730d163575Sopenharmony_ci if (vmPage == NULL) { 1740d163575Sopenharmony_ci PRINT_ERR("%s, %d\n", __FUNCTION__, __LINE__); 1750d163575Sopenharmony_ci ret = -EINVAL; 1760d163575Sopenharmony_ci break; 1770d163575Sopenharmony_ci } 1780d163575Sopenharmony_ci STATUS_T err = LOS_ArchMmuMap(&pcb->vmSpace->archMmu, uva + (i << PAGE_SHIFT), pa, 1, uflags); 1790d163575Sopenharmony_ci if (err < 0) { 1800d163575Sopenharmony_ci ret = err; 1810d163575Sopenharmony_ci PRINT_ERR("%s, %d\n", __FUNCTION__, __LINE__); 1820d163575Sopenharmony_ci break; 1830d163575Sopenharmony_ci } 1840d163575Sopenharmony_ci } 1850d163575Sopenharmony_ci /* if any failure happened, rollback */ 1860d163575Sopenharmony_ci if (i != (region->range.size >> PAGE_SHIFT)) { 1870d163575Sopenharmony_ci while (i--) { 1880d163575Sopenharmony_ci pa = LOS_PaddrQuery((VOID *)(UINTPTR)(kva + (i << PAGE_SHIFT))); 1890d163575Sopenharmony_ci vmPage = LOS_VmPageGet(pa); 1900d163575Sopenharmony_ci (VOID)LOS_ArchMmuUnmap(&pcb->vmSpace->archMmu, uva + (i << PAGE_SHIFT), 1); 1910d163575Sopenharmony_ci LOS_PhysPageFree(vmPage); 1920d163575Sopenharmony_ci } 1930d163575Sopenharmony_ci } 1940d163575Sopenharmony_ci 1950d163575Sopenharmony_ci (VOID)LOS_MuxRelease(&pcb->vmSpace->regionMux); 1960d163575Sopenharmony_ci return ret; 1970d163575Sopenharmony_ci} 1980d163575Sopenharmony_ci 1990d163575Sopenharmony_ciLITE_OS_SEC_TEXT STATIC int LiteIpcMmap(struct file *filep, LosVmMapRegion *region) 2000d163575Sopenharmony_ci{ 2010d163575Sopenharmony_ci int ret = 0; 2020d163575Sopenharmony_ci LosVmMapRegion *regionTemp = NULL; 2030d163575Sopenharmony_ci LosProcessCB *pcb = OsCurrProcessGet(); 2040d163575Sopenharmony_ci ProcIpcInfo *ipcInfo = pcb->ipcInfo; 2050d163575Sopenharmony_ci 2060d163575Sopenharmony_ci if ((ipcInfo == NULL) || (region == NULL) || (region->range.size > LITE_IPC_POOL_MAX_SIZE) || 2070d163575Sopenharmony_ci (!LOS_IsRegionPermUserReadOnly(region)) || (!LOS_IsRegionFlagPrivateOnly(region))) { 2080d163575Sopenharmony_ci ret = -EINVAL; 2090d163575Sopenharmony_ci goto ERROR_REGION_OUT; 2100d163575Sopenharmony_ci } 2110d163575Sopenharmony_ci if (IsPoolMapped(ipcInfo)) { 2120d163575Sopenharmony_ci return -EEXIST; 2130d163575Sopenharmony_ci } 2140d163575Sopenharmony_ci if (ipcInfo->pool.uvaddr != NULL) { 2150d163575Sopenharmony_ci regionTemp = LOS_RegionFind(pcb->vmSpace, (VADDR_T)(UINTPTR)ipcInfo->pool.uvaddr); 2160d163575Sopenharmony_ci if (regionTemp != NULL) { 2170d163575Sopenharmony_ci (VOID)LOS_RegionFree(pcb->vmSpace, regionTemp); 2180d163575Sopenharmony_ci } 2190d163575Sopenharmony_ci } 2200d163575Sopenharmony_ci ipcInfo->pool.uvaddr = (VOID *)(UINTPTR)region->range.base; 2210d163575Sopenharmony_ci if (ipcInfo->pool.kvaddr != NULL) { 2220d163575Sopenharmony_ci LOS_VFree(ipcInfo->pool.kvaddr); 2230d163575Sopenharmony_ci ipcInfo->pool.kvaddr = NULL; 2240d163575Sopenharmony_ci } 2250d163575Sopenharmony_ci /* use vmalloc to alloc phy mem */ 2260d163575Sopenharmony_ci ipcInfo->pool.kvaddr = LOS_VMalloc(region->range.size); 2270d163575Sopenharmony_ci if (ipcInfo->pool.kvaddr == NULL) { 2280d163575Sopenharmony_ci ret = -ENOMEM; 2290d163575Sopenharmony_ci goto ERROR_REGION_OUT; 2300d163575Sopenharmony_ci } 2310d163575Sopenharmony_ci /* do mmap */ 2320d163575Sopenharmony_ci ret = DoIpcMmap(pcb, region); 2330d163575Sopenharmony_ci if (ret) { 2340d163575Sopenharmony_ci goto ERROR_MAP_OUT; 2350d163575Sopenharmony_ci } 2360d163575Sopenharmony_ci /* ipc pool init */ 2370d163575Sopenharmony_ci if (LOS_MemInit(ipcInfo->pool.kvaddr, region->range.size) != LOS_OK) { 2380d163575Sopenharmony_ci ret = -EINVAL; 2390d163575Sopenharmony_ci goto ERROR_MAP_OUT; 2400d163575Sopenharmony_ci } 2410d163575Sopenharmony_ci ipcInfo->pool.poolSize = region->range.size; 2420d163575Sopenharmony_ci region->regionFlags |= VM_MAP_REGION_FLAG_LITEIPC; 2430d163575Sopenharmony_ci return 0; 2440d163575Sopenharmony_ciERROR_MAP_OUT: 2450d163575Sopenharmony_ci LOS_VFree(ipcInfo->pool.kvaddr); 2460d163575Sopenharmony_ciERROR_REGION_OUT: 2470d163575Sopenharmony_ci if (ipcInfo != NULL) { 2480d163575Sopenharmony_ci ipcInfo->pool.uvaddr = NULL; 2490d163575Sopenharmony_ci ipcInfo->pool.kvaddr = NULL; 2500d163575Sopenharmony_ci } 2510d163575Sopenharmony_ci return ret; 2520d163575Sopenharmony_ci} 2530d163575Sopenharmony_ci 2540d163575Sopenharmony_ciLITE_OS_SEC_TEXT_INIT STATIC UINT32 LiteIpcPoolInit(ProcIpcInfo *ipcInfo) 2550d163575Sopenharmony_ci{ 2560d163575Sopenharmony_ci ipcInfo->pool.uvaddr = NULL; 2570d163575Sopenharmony_ci ipcInfo->pool.kvaddr = NULL; 2580d163575Sopenharmony_ci ipcInfo->pool.poolSize = 0; 2590d163575Sopenharmony_ci ipcInfo->ipcTaskID = INVAILD_ID; 2600d163575Sopenharmony_ci LOS_ListInit(&ipcInfo->ipcUsedNodelist); 2610d163575Sopenharmony_ci return LOS_OK; 2620d163575Sopenharmony_ci} 2630d163575Sopenharmony_ci 2640d163575Sopenharmony_ciLITE_OS_SEC_TEXT_INIT STATIC ProcIpcInfo *LiteIpcPoolCreate(VOID) 2650d163575Sopenharmony_ci{ 2660d163575Sopenharmony_ci ProcIpcInfo *ipcInfo = LOS_MemAlloc(m_aucSysMem1, sizeof(ProcIpcInfo)); 2670d163575Sopenharmony_ci if (ipcInfo == NULL) { 2680d163575Sopenharmony_ci return NULL; 2690d163575Sopenharmony_ci } 2700d163575Sopenharmony_ci 2710d163575Sopenharmony_ci (VOID)memset_s(ipcInfo, sizeof(ProcIpcInfo), 0, sizeof(ProcIpcInfo)); 2720d163575Sopenharmony_ci 2730d163575Sopenharmony_ci (VOID)LiteIpcPoolInit(ipcInfo); 2740d163575Sopenharmony_ci return ipcInfo; 2750d163575Sopenharmony_ci} 2760d163575Sopenharmony_ci 2770d163575Sopenharmony_ciLITE_OS_SEC_TEXT ProcIpcInfo *LiteIpcPoolReInit(const ProcIpcInfo *parent) 2780d163575Sopenharmony_ci{ 2790d163575Sopenharmony_ci ProcIpcInfo *ipcInfo = LiteIpcPoolCreate(); 2800d163575Sopenharmony_ci if (ipcInfo == NULL) { 2810d163575Sopenharmony_ci return NULL; 2820d163575Sopenharmony_ci } 2830d163575Sopenharmony_ci 2840d163575Sopenharmony_ci ipcInfo->pool.uvaddr = parent->pool.uvaddr; 2850d163575Sopenharmony_ci ipcInfo->pool.kvaddr = NULL; 2860d163575Sopenharmony_ci ipcInfo->pool.poolSize = 0; 2870d163575Sopenharmony_ci ipcInfo->ipcTaskID = INVAILD_ID; 2880d163575Sopenharmony_ci return ipcInfo; 2890d163575Sopenharmony_ci} 2900d163575Sopenharmony_ci 2910d163575Sopenharmony_ciSTATIC VOID LiteIpcPoolDelete(ProcIpcInfo *ipcInfo, UINT32 processID) 2920d163575Sopenharmony_ci{ 2930d163575Sopenharmony_ci UINT32 intSave; 2940d163575Sopenharmony_ci IpcUsedNode *node = NULL; 2950d163575Sopenharmony_ci if (ipcInfo->pool.kvaddr != NULL) { 2960d163575Sopenharmony_ci LOS_VFree(ipcInfo->pool.kvaddr); 2970d163575Sopenharmony_ci ipcInfo->pool.kvaddr = NULL; 2980d163575Sopenharmony_ci IPC_LOCK(intSave); 2990d163575Sopenharmony_ci while (!LOS_ListEmpty(&ipcInfo->ipcUsedNodelist)) { 3000d163575Sopenharmony_ci node = LOS_DL_LIST_ENTRY(ipcInfo->ipcUsedNodelist.pstNext, IpcUsedNode, list); 3010d163575Sopenharmony_ci LOS_ListDelete(&node->list); 3020d163575Sopenharmony_ci free(node); 3030d163575Sopenharmony_ci } 3040d163575Sopenharmony_ci IPC_UNLOCK(intSave); 3050d163575Sopenharmony_ci } 3060d163575Sopenharmony_ci /* remove process access to service */ 3070d163575Sopenharmony_ci for (UINT32 i = 0; i < MAX_SERVICE_NUM; i++) { 3080d163575Sopenharmony_ci if (ipcInfo->access[i] == TRUE) { 3090d163575Sopenharmony_ci ipcInfo->access[i] = FALSE; 3100d163575Sopenharmony_ci if (OS_TCB_FROM_TID(i)->ipcTaskInfo != NULL) { 3110d163575Sopenharmony_ci OS_TCB_FROM_TID(i)->ipcTaskInfo->accessMap[processID] = FALSE; 3120d163575Sopenharmony_ci } 3130d163575Sopenharmony_ci } 3140d163575Sopenharmony_ci } 3150d163575Sopenharmony_ci} 3160d163575Sopenharmony_ci 3170d163575Sopenharmony_ciLITE_OS_SEC_TEXT UINT32 LiteIpcPoolDestroy(UINT32 processID) 3180d163575Sopenharmony_ci{ 3190d163575Sopenharmony_ci LosProcessCB *pcb = OS_PCB_FROM_PID(processID); 3200d163575Sopenharmony_ci if (pcb->ipcInfo == NULL) { 3210d163575Sopenharmony_ci return LOS_NOK; 3220d163575Sopenharmony_ci } 3230d163575Sopenharmony_ci 3240d163575Sopenharmony_ci LiteIpcPoolDelete(pcb->ipcInfo, pcb->processID); 3250d163575Sopenharmony_ci LOS_MemFree(m_aucSysMem1, pcb->ipcInfo); 3260d163575Sopenharmony_ci pcb->ipcInfo = NULL; 3270d163575Sopenharmony_ci return LOS_OK; 3280d163575Sopenharmony_ci} 3290d163575Sopenharmony_ci 3300d163575Sopenharmony_ciLITE_OS_SEC_TEXT_INIT STATIC IpcTaskInfo *LiteIpcTaskInit(VOID) 3310d163575Sopenharmony_ci{ 3320d163575Sopenharmony_ci IpcTaskInfo *taskInfo = LOS_MemAlloc((VOID *)m_aucSysMem1, sizeof(IpcTaskInfo)); 3330d163575Sopenharmony_ci if (taskInfo == NULL) { 3340d163575Sopenharmony_ci return NULL; 3350d163575Sopenharmony_ci } 3360d163575Sopenharmony_ci 3370d163575Sopenharmony_ci (VOID)memset_s(taskInfo, sizeof(IpcTaskInfo), 0, sizeof(IpcTaskInfo)); 3380d163575Sopenharmony_ci LOS_ListInit(&taskInfo->msgListHead); 3390d163575Sopenharmony_ci return taskInfo; 3400d163575Sopenharmony_ci} 3410d163575Sopenharmony_ci 3420d163575Sopenharmony_ci/* Only when kernenl no longer access ipc node content, can user free the ipc node */ 3430d163575Sopenharmony_ciLITE_OS_SEC_TEXT STATIC VOID EnableIpcNodeFreeByUser(LosProcessCB *pcb, VOID *buf) 3440d163575Sopenharmony_ci{ 3450d163575Sopenharmony_ci UINT32 intSave; 3460d163575Sopenharmony_ci ProcIpcInfo *ipcInfo = pcb->ipcInfo; 3470d163575Sopenharmony_ci IpcUsedNode *node = (IpcUsedNode *)malloc(sizeof(IpcUsedNode)); 3480d163575Sopenharmony_ci if (node != NULL) { 3490d163575Sopenharmony_ci node->ptr = buf; 3500d163575Sopenharmony_ci IPC_LOCK(intSave); 3510d163575Sopenharmony_ci LOS_ListAdd(&ipcInfo->ipcUsedNodelist, &node->list); 3520d163575Sopenharmony_ci IPC_UNLOCK(intSave); 3530d163575Sopenharmony_ci } 3540d163575Sopenharmony_ci} 3550d163575Sopenharmony_ci 3560d163575Sopenharmony_ciLITE_OS_SEC_TEXT STATIC VOID *LiteIpcNodeAlloc(LosProcessCB *pcb, UINT32 size) 3570d163575Sopenharmony_ci{ 3580d163575Sopenharmony_ci VOID *ptr = LOS_MemAlloc(pcb->ipcInfo->pool.kvaddr, size); 3590d163575Sopenharmony_ci PRINT_INFO("LiteIpcNodeAlloc pid:%d, pool:%x buf:%x size:%d\n", 3600d163575Sopenharmony_ci pcb->processID, pcb->ipcInfo->pool.kvaddr, ptr, size); 3610d163575Sopenharmony_ci return ptr; 3620d163575Sopenharmony_ci} 3630d163575Sopenharmony_ci 3640d163575Sopenharmony_ciLITE_OS_SEC_TEXT STATIC UINT32 LiteIpcNodeFree(LosProcessCB *pcb, VOID *buf) 3650d163575Sopenharmony_ci{ 3660d163575Sopenharmony_ci PRINT_INFO("LiteIpcNodeFree pid:%d, pool:%x buf:%x\n", 3670d163575Sopenharmony_ci pcb->processID, pcb->ipcInfo->pool.kvaddr, buf); 3680d163575Sopenharmony_ci return LOS_MemFree(pcb->ipcInfo->pool.kvaddr, buf); 3690d163575Sopenharmony_ci} 3700d163575Sopenharmony_ci 3710d163575Sopenharmony_ciLITE_OS_SEC_TEXT STATIC BOOL IsIpcNode(LosProcessCB *pcb, const VOID *buf) 3720d163575Sopenharmony_ci{ 3730d163575Sopenharmony_ci IpcUsedNode *node = NULL; 3740d163575Sopenharmony_ci UINT32 intSave; 3750d163575Sopenharmony_ci ProcIpcInfo *ipcInfo = pcb->ipcInfo; 3760d163575Sopenharmony_ci IPC_LOCK(intSave); 3770d163575Sopenharmony_ci LOS_DL_LIST_FOR_EACH_ENTRY(node, &ipcInfo->ipcUsedNodelist, IpcUsedNode, list) { 3780d163575Sopenharmony_ci if (node->ptr == buf) { 3790d163575Sopenharmony_ci LOS_ListDelete(&node->list); 3800d163575Sopenharmony_ci IPC_UNLOCK(intSave); 3810d163575Sopenharmony_ci free(node); 3820d163575Sopenharmony_ci return TRUE; 3830d163575Sopenharmony_ci } 3840d163575Sopenharmony_ci } 3850d163575Sopenharmony_ci IPC_UNLOCK(intSave); 3860d163575Sopenharmony_ci return FALSE; 3870d163575Sopenharmony_ci} 3880d163575Sopenharmony_ci 3890d163575Sopenharmony_ciLITE_OS_SEC_TEXT STATIC INTPTR GetIpcUserAddr(const LosProcessCB *pcb, INTPTR kernelAddr) 3900d163575Sopenharmony_ci{ 3910d163575Sopenharmony_ci IpcPool pool = pcb->ipcInfo->pool; 3920d163575Sopenharmony_ci INTPTR offset = (INTPTR)(pool.uvaddr) - (INTPTR)(pool.kvaddr); 3930d163575Sopenharmony_ci return kernelAddr + offset; 3940d163575Sopenharmony_ci} 3950d163575Sopenharmony_ci 3960d163575Sopenharmony_ciLITE_OS_SEC_TEXT STATIC INTPTR GetIpcKernelAddr(const LosProcessCB *pcb, INTPTR userAddr) 3970d163575Sopenharmony_ci{ 3980d163575Sopenharmony_ci IpcPool pool = pcb->ipcInfo->pool; 3990d163575Sopenharmony_ci INTPTR offset = (INTPTR)(pool.uvaddr) - (INTPTR)(pool.kvaddr); 4000d163575Sopenharmony_ci return userAddr - offset; 4010d163575Sopenharmony_ci} 4020d163575Sopenharmony_ci 4030d163575Sopenharmony_ciLITE_OS_SEC_TEXT STATIC UINT32 CheckUsedBuffer(const VOID *node, IpcListNode **outPtr) 4040d163575Sopenharmony_ci{ 4050d163575Sopenharmony_ci VOID *ptr = NULL; 4060d163575Sopenharmony_ci LosProcessCB *pcb = OsCurrProcessGet(); 4070d163575Sopenharmony_ci IpcPool pool = pcb->ipcInfo->pool; 4080d163575Sopenharmony_ci if ((node == NULL) || ((INTPTR)node < (INTPTR)(pool.uvaddr)) || 4090d163575Sopenharmony_ci ((INTPTR)node > (INTPTR)(pool.uvaddr) + pool.poolSize)) { 4100d163575Sopenharmony_ci return -EINVAL; 4110d163575Sopenharmony_ci } 4120d163575Sopenharmony_ci ptr = (VOID *)GetIpcKernelAddr(pcb, (INTPTR)(node)); 4130d163575Sopenharmony_ci if (IsIpcNode(pcb, ptr) != TRUE) { 4140d163575Sopenharmony_ci return -EFAULT; 4150d163575Sopenharmony_ci } 4160d163575Sopenharmony_ci *outPtr = (IpcListNode *)ptr; 4170d163575Sopenharmony_ci return LOS_OK; 4180d163575Sopenharmony_ci} 4190d163575Sopenharmony_ci 4200d163575Sopenharmony_ciLITE_OS_SEC_TEXT STATIC UINT32 GetTid(UINT32 serviceHandle, UINT32 *taskID) 4210d163575Sopenharmony_ci{ 4220d163575Sopenharmony_ci if (serviceHandle >= MAX_SERVICE_NUM) { 4230d163575Sopenharmony_ci return -EINVAL; 4240d163575Sopenharmony_ci } 4250d163575Sopenharmony_ci (VOID)LOS_MuxLock(&g_serviceHandleMapMux, LOS_WAIT_FOREVER); 4260d163575Sopenharmony_ci#if (USE_TASKID_AS_HANDLE == 1) 4270d163575Sopenharmony_ci *taskID = serviceHandle ? serviceHandle : g_cmsTask.taskID; 4280d163575Sopenharmony_ci (VOID)LOS_MuxUnlock(&g_serviceHandleMapMux); 4290d163575Sopenharmony_ci return LOS_OK; 4300d163575Sopenharmony_ci#else 4310d163575Sopenharmony_ci if (g_serviceHandleMap[serviceHandle].status == HANDLE_REGISTED) { 4320d163575Sopenharmony_ci *taskID = g_serviceHandleMap[serviceHandle].taskID; 4330d163575Sopenharmony_ci (VOID)LOS_MuxUnlock(&g_serviceHandleMapMux); 4340d163575Sopenharmony_ci return LOS_OK; 4350d163575Sopenharmony_ci } 4360d163575Sopenharmony_ci (VOID)LOS_MuxUnlock(&g_serviceHandleMapMux); 4370d163575Sopenharmony_ci return -EINVAL; 4380d163575Sopenharmony_ci#endif 4390d163575Sopenharmony_ci} 4400d163575Sopenharmony_ci 4410d163575Sopenharmony_ciLITE_OS_SEC_TEXT STATIC UINT32 GenerateServiceHandle(UINT32 taskID, HandleStatus status, UINT32 *serviceHandle) 4420d163575Sopenharmony_ci{ 4430d163575Sopenharmony_ci (VOID)LOS_MuxLock(&g_serviceHandleMapMux, LOS_WAIT_FOREVER); 4440d163575Sopenharmony_ci#if (USE_TASKID_AS_HANDLE == 1) 4450d163575Sopenharmony_ci *serviceHandle = taskID ? taskID : LOS_CurTaskIDGet(); /* if taskID is 0, return curTaskID */ 4460d163575Sopenharmony_ci if (*serviceHandle != g_cmsTask.taskID) { 4470d163575Sopenharmony_ci (VOID)LOS_MuxUnlock(&g_serviceHandleMapMux); 4480d163575Sopenharmony_ci return LOS_OK; 4490d163575Sopenharmony_ci } 4500d163575Sopenharmony_ci#else 4510d163575Sopenharmony_ci for (UINT32 i = 1; i < MAX_SERVICE_NUM; i++) { 4520d163575Sopenharmony_ci if (g_serviceHandleMap[i].status == HANDLE_NOT_USED) { 4530d163575Sopenharmony_ci g_serviceHandleMap[i].taskID = taskID; 4540d163575Sopenharmony_ci g_serviceHandleMap[i].status = status; 4550d163575Sopenharmony_ci *serviceHandle = i; 4560d163575Sopenharmony_ci (VOID)LOS_MuxUnlock(&g_serviceHandleMapMux); 4570d163575Sopenharmony_ci return LOS_OK; 4580d163575Sopenharmony_ci } 4590d163575Sopenharmony_ci } 4600d163575Sopenharmony_ci#endif 4610d163575Sopenharmony_ci (VOID)LOS_MuxUnlock(&g_serviceHandleMapMux); 4620d163575Sopenharmony_ci return -EINVAL; 4630d163575Sopenharmony_ci} 4640d163575Sopenharmony_ci 4650d163575Sopenharmony_ciLITE_OS_SEC_TEXT STATIC VOID RefreshServiceHandle(UINT32 serviceHandle, UINT32 result) 4660d163575Sopenharmony_ci{ 4670d163575Sopenharmony_ci#if (USE_TASKID_AS_HANDLE == 0) 4680d163575Sopenharmony_ci (VOID)LOS_MuxLock(&g_serviceHandleMapMux, LOS_WAIT_FOREVER); 4690d163575Sopenharmony_ci if ((result == LOS_OK) && (g_serviceHandleMap[serviceHandle].status == HANDLE_REGISTING)) { 4700d163575Sopenharmony_ci g_serviceHandleMap[serviceHandle].status = HANDLE_REGISTED; 4710d163575Sopenharmony_ci } else { 4720d163575Sopenharmony_ci g_serviceHandleMap[serviceHandle].status = HANDLE_NOT_USED; 4730d163575Sopenharmony_ci } 4740d163575Sopenharmony_ci (VOID)LOS_MuxUnlock(&g_serviceHandleMapMux); 4750d163575Sopenharmony_ci#endif 4760d163575Sopenharmony_ci} 4770d163575Sopenharmony_ci 4780d163575Sopenharmony_ciLITE_OS_SEC_TEXT STATIC UINT32 AddServiceAccess(UINT32 taskID, UINT32 serviceHandle) 4790d163575Sopenharmony_ci{ 4800d163575Sopenharmony_ci UINT32 serviceTid = 0; 4810d163575Sopenharmony_ci UINT32 ret = GetTid(serviceHandle, &serviceTid); 4820d163575Sopenharmony_ci if (ret != LOS_OK) { 4830d163575Sopenharmony_ci PRINT_ERR("Liteipc AddServiceAccess GetTid failed\n"); 4840d163575Sopenharmony_ci return ret; 4850d163575Sopenharmony_ci } 4860d163575Sopenharmony_ci 4870d163575Sopenharmony_ci LosTaskCB *tcb = OS_TCB_FROM_TID(serviceTid); 4880d163575Sopenharmony_ci LosProcessCB *pcb = OS_PCB_FROM_TID(taskID); 4890d163575Sopenharmony_ci if ((tcb->ipcTaskInfo == NULL) || (pcb->ipcInfo == NULL)) { 4900d163575Sopenharmony_ci PRINT_ERR("Liteipc AddServiceAccess ipc not create! pid %u tid %u\n", pcb->processID, tcb->taskID); 4910d163575Sopenharmony_ci return -EINVAL; 4920d163575Sopenharmony_ci } 4930d163575Sopenharmony_ci tcb->ipcTaskInfo->accessMap[pcb->processID] = TRUE; 4940d163575Sopenharmony_ci pcb->ipcInfo->access[serviceTid] = TRUE; 4950d163575Sopenharmony_ci return LOS_OK; 4960d163575Sopenharmony_ci} 4970d163575Sopenharmony_ci 4980d163575Sopenharmony_ciLITE_OS_SEC_TEXT STATIC BOOL HasServiceAccess(UINT32 serviceHandle) 4990d163575Sopenharmony_ci{ 5000d163575Sopenharmony_ci UINT32 serviceTid = 0; 5010d163575Sopenharmony_ci LosProcessCB *curr = OsCurrProcessGet(); 5020d163575Sopenharmony_ci UINT32 ret; 5030d163575Sopenharmony_ci if (serviceHandle >= MAX_SERVICE_NUM) { 5040d163575Sopenharmony_ci return FALSE; 5050d163575Sopenharmony_ci } 5060d163575Sopenharmony_ci if (serviceHandle == 0) { 5070d163575Sopenharmony_ci return TRUE; 5080d163575Sopenharmony_ci } 5090d163575Sopenharmony_ci ret = GetTid(serviceHandle, &serviceTid); 5100d163575Sopenharmony_ci if (ret != LOS_OK) { 5110d163575Sopenharmony_ci PRINT_ERR("Liteipc HasServiceAccess GetTid failed\n"); 5120d163575Sopenharmony_ci return FALSE; 5130d163575Sopenharmony_ci } 5140d163575Sopenharmony_ci LosTaskCB *taskCB = OS_TCB_FROM_TID(serviceTid); 5150d163575Sopenharmony_ci if (taskCB->processCB == (UINTPTR)curr) { 5160d163575Sopenharmony_ci return TRUE; 5170d163575Sopenharmony_ci } 5180d163575Sopenharmony_ci 5190d163575Sopenharmony_ci if (taskCB->ipcTaskInfo == NULL) { 5200d163575Sopenharmony_ci return FALSE; 5210d163575Sopenharmony_ci } 5220d163575Sopenharmony_ci 5230d163575Sopenharmony_ci return taskCB->ipcTaskInfo->accessMap[curr->processID]; 5240d163575Sopenharmony_ci} 5250d163575Sopenharmony_ci 5260d163575Sopenharmony_ciLITE_OS_SEC_TEXT STATIC UINT32 SetIpcTask(VOID) 5270d163575Sopenharmony_ci{ 5280d163575Sopenharmony_ci if (OsCurrProcessGet()->ipcInfo->ipcTaskID == INVAILD_ID) { 5290d163575Sopenharmony_ci OsCurrProcessGet()->ipcInfo->ipcTaskID = LOS_CurTaskIDGet(); 5300d163575Sopenharmony_ci return OsCurrProcessGet()->ipcInfo->ipcTaskID; 5310d163575Sopenharmony_ci } 5320d163575Sopenharmony_ci PRINT_ERR("Liteipc curprocess %d IpcTask already set!\n", OsCurrProcessGet()->processID); 5330d163575Sopenharmony_ci return -EINVAL; 5340d163575Sopenharmony_ci} 5350d163575Sopenharmony_ci 5360d163575Sopenharmony_ciLITE_OS_SEC_TEXT BOOL IsIpcTaskSet(VOID) 5370d163575Sopenharmony_ci{ 5380d163575Sopenharmony_ci if (OsCurrProcessGet()->ipcInfo->ipcTaskID == INVAILD_ID) { 5390d163575Sopenharmony_ci return FALSE; 5400d163575Sopenharmony_ci } 5410d163575Sopenharmony_ci return TRUE; 5420d163575Sopenharmony_ci} 5430d163575Sopenharmony_ci 5440d163575Sopenharmony_ciLITE_OS_SEC_TEXT STATIC UINT32 GetIpcTaskID(LosProcessCB *pcb, UINT32 *ipcTaskID) 5450d163575Sopenharmony_ci{ 5460d163575Sopenharmony_ci if (pcb->ipcInfo->ipcTaskID == INVAILD_ID) { 5470d163575Sopenharmony_ci return LOS_NOK; 5480d163575Sopenharmony_ci } 5490d163575Sopenharmony_ci *ipcTaskID = pcb->ipcInfo->ipcTaskID; 5500d163575Sopenharmony_ci return LOS_OK; 5510d163575Sopenharmony_ci} 5520d163575Sopenharmony_ci 5530d163575Sopenharmony_ciLITE_OS_SEC_TEXT STATIC UINT32 SendDeathMsg(UINT32 processID, UINT32 serviceHandle) 5540d163575Sopenharmony_ci{ 5550d163575Sopenharmony_ci UINT32 ipcTaskID; 5560d163575Sopenharmony_ci UINT32 ret; 5570d163575Sopenharmony_ci IpcContent content; 5580d163575Sopenharmony_ci IpcMsg msg; 5590d163575Sopenharmony_ci LosProcessCB *pcb = OS_PCB_FROM_PID(processID); 5600d163575Sopenharmony_ci 5610d163575Sopenharmony_ci if (pcb->ipcInfo == NULL) { 5620d163575Sopenharmony_ci return -EINVAL; 5630d163575Sopenharmony_ci } 5640d163575Sopenharmony_ci 5650d163575Sopenharmony_ci pcb->ipcInfo->access[serviceHandle] = FALSE; 5660d163575Sopenharmony_ci 5670d163575Sopenharmony_ci ret = GetIpcTaskID(pcb, &ipcTaskID); 5680d163575Sopenharmony_ci if (ret != LOS_OK) { 5690d163575Sopenharmony_ci return -EINVAL; 5700d163575Sopenharmony_ci } 5710d163575Sopenharmony_ci content.flag = SEND; 5720d163575Sopenharmony_ci content.outMsg = &msg; 5730d163575Sopenharmony_ci (void)memset_s(content.outMsg, sizeof(IpcMsg), 0, sizeof(IpcMsg)); 5740d163575Sopenharmony_ci content.outMsg->type = MT_DEATH_NOTIFY; 5750d163575Sopenharmony_ci content.outMsg->target.handle = ipcTaskID; 5760d163575Sopenharmony_ci content.outMsg->target.token = serviceHandle; 5770d163575Sopenharmony_ci content.outMsg->code = 0; 5780d163575Sopenharmony_ci return LiteIpcWrite(&content); 5790d163575Sopenharmony_ci} 5800d163575Sopenharmony_ci 5810d163575Sopenharmony_ciLITE_OS_SEC_TEXT VOID LiteIpcRemoveServiceHandle(UINT32 taskID) 5820d163575Sopenharmony_ci{ 5830d163575Sopenharmony_ci UINT32 j; 5840d163575Sopenharmony_ci LosTaskCB *taskCB = OS_TCB_FROM_TID(taskID); 5850d163575Sopenharmony_ci IpcTaskInfo *ipcTaskInfo = taskCB->ipcTaskInfo; 5860d163575Sopenharmony_ci if (ipcTaskInfo == NULL) { 5870d163575Sopenharmony_ci return; 5880d163575Sopenharmony_ci } 5890d163575Sopenharmony_ci 5900d163575Sopenharmony_ci#if (USE_TASKID_AS_HANDLE == 1) 5910d163575Sopenharmony_ci 5920d163575Sopenharmony_ci UINT32 intSave; 5930d163575Sopenharmony_ci LOS_DL_LIST *listHead = NULL; 5940d163575Sopenharmony_ci LOS_DL_LIST *listNode = NULL; 5950d163575Sopenharmony_ci IpcListNode *node = NULL; 5960d163575Sopenharmony_ci LosProcessCB *pcb = OS_PCB_FROM_TCB(taskCB); 5970d163575Sopenharmony_ci 5980d163575Sopenharmony_ci listHead = &(ipcTaskInfo->msgListHead); 5990d163575Sopenharmony_ci do { 6000d163575Sopenharmony_ci SCHEDULER_LOCK(intSave); 6010d163575Sopenharmony_ci if (LOS_ListEmpty(listHead)) { 6020d163575Sopenharmony_ci SCHEDULER_UNLOCK(intSave); 6030d163575Sopenharmony_ci break; 6040d163575Sopenharmony_ci } else { 6050d163575Sopenharmony_ci listNode = LOS_DL_LIST_FIRST(listHead); 6060d163575Sopenharmony_ci LOS_ListDelete(listNode); 6070d163575Sopenharmony_ci node = LOS_DL_LIST_ENTRY(listNode, IpcListNode, listNode); 6080d163575Sopenharmony_ci SCHEDULER_UNLOCK(intSave); 6090d163575Sopenharmony_ci (VOID)HandleSpecialObjects(taskCB->taskID, node, TRUE); 6100d163575Sopenharmony_ci (VOID)LiteIpcNodeFree(pcb, (VOID *)node); 6110d163575Sopenharmony_ci } 6120d163575Sopenharmony_ci } while (1); 6130d163575Sopenharmony_ci 6140d163575Sopenharmony_ci ipcTaskInfo->accessMap[pcb->processID] = FALSE; 6150d163575Sopenharmony_ci for (j = 0; j < LOSCFG_BASE_CORE_PROCESS_LIMIT; j++) { 6160d163575Sopenharmony_ci if (ipcTaskInfo->accessMap[j] == TRUE) { 6170d163575Sopenharmony_ci ipcTaskInfo->accessMap[j] = FALSE; 6180d163575Sopenharmony_ci (VOID)SendDeathMsg(j, taskCB->taskID); 6190d163575Sopenharmony_ci } 6200d163575Sopenharmony_ci } 6210d163575Sopenharmony_ci#else 6220d163575Sopenharmony_ci (VOID)LOS_MuxLock(&g_serviceHandleMapMux, LOS_WAIT_FOREVER); 6230d163575Sopenharmony_ci for (UINT32 i = 1; i < MAX_SERVICE_NUM; i++) { 6240d163575Sopenharmony_ci if ((g_serviceHandleMap[i].status != HANDLE_NOT_USED) && (g_serviceHandleMap[i].taskID == taskCB->taskID)) { 6250d163575Sopenharmony_ci g_serviceHandleMap[i].status = HANDLE_NOT_USED; 6260d163575Sopenharmony_ci g_serviceHandleMap[i].taskID = INVAILD_ID; 6270d163575Sopenharmony_ci break; 6280d163575Sopenharmony_ci } 6290d163575Sopenharmony_ci } 6300d163575Sopenharmony_ci (VOID)LOS_MuxUnlock(&g_serviceHandleMapMux); 6310d163575Sopenharmony_ci /* run deathHandler */ 6320d163575Sopenharmony_ci if (i < MAX_SERVICE_NUM) { 6330d163575Sopenharmony_ci for (j = 0; j < LOSCFG_BASE_CORE_PROCESS_LIMIT; j++) { 6340d163575Sopenharmony_ci if (ipcTaskInfo->accessMap[j] == TRUE) { 6350d163575Sopenharmony_ci (VOID)SendDeathMsg(j, i); 6360d163575Sopenharmony_ci } 6370d163575Sopenharmony_ci } 6380d163575Sopenharmony_ci } 6390d163575Sopenharmony_ci#endif 6400d163575Sopenharmony_ci 6410d163575Sopenharmony_ci (VOID)LOS_MemFree(m_aucSysMem1, ipcTaskInfo); 6420d163575Sopenharmony_ci taskCB->ipcTaskInfo = NULL; 6430d163575Sopenharmony_ci} 6440d163575Sopenharmony_ci 6450d163575Sopenharmony_ciLITE_OS_SEC_TEXT STATIC UINT32 SetCms(UINTPTR maxMsgSize) 6460d163575Sopenharmony_ci{ 6470d163575Sopenharmony_ci if (maxMsgSize < sizeof(IpcMsg)) { 6480d163575Sopenharmony_ci return -EINVAL; 6490d163575Sopenharmony_ci } 6500d163575Sopenharmony_ci (VOID)LOS_MuxLock(&g_serviceHandleMapMux, LOS_WAIT_FOREVER); 6510d163575Sopenharmony_ci#if (USE_TASKID_AS_HANDLE == 1) 6520d163575Sopenharmony_ci if (g_cmsTask.status == HANDLE_NOT_USED) { 6530d163575Sopenharmony_ci g_cmsTask.status = HANDLE_REGISTED; 6540d163575Sopenharmony_ci g_cmsTask.taskID = LOS_CurTaskIDGet(); 6550d163575Sopenharmony_ci g_cmsTask.maxMsgSize = maxMsgSize; 6560d163575Sopenharmony_ci (VOID)LOS_MuxUnlock(&g_serviceHandleMapMux); 6570d163575Sopenharmony_ci return LOS_OK; 6580d163575Sopenharmony_ci } 6590d163575Sopenharmony_ci#else 6600d163575Sopenharmony_ci if (g_serviceHandleMap[0].status == HANDLE_NOT_USED) { 6610d163575Sopenharmony_ci g_serviceHandleMap[0].status = HANDLE_REGISTED; 6620d163575Sopenharmony_ci g_serviceHandleMap[0].taskID = LOS_CurTaskIDGet(); 6630d163575Sopenharmony_ci (VOID)LOS_MuxUnlock(&g_serviceHandleMapMux); 6640d163575Sopenharmony_ci return LOS_OK; 6650d163575Sopenharmony_ci } 6660d163575Sopenharmony_ci#endif 6670d163575Sopenharmony_ci (VOID)LOS_MuxUnlock(&g_serviceHandleMapMux); 6680d163575Sopenharmony_ci return -EEXIST; 6690d163575Sopenharmony_ci} 6700d163575Sopenharmony_ci 6710d163575Sopenharmony_ciLITE_OS_SEC_TEXT STATIC BOOL IsCmsSet(VOID) 6720d163575Sopenharmony_ci{ 6730d163575Sopenharmony_ci BOOL ret; 6740d163575Sopenharmony_ci (VOID)LOS_MuxLock(&g_serviceHandleMapMux, LOS_WAIT_FOREVER); 6750d163575Sopenharmony_ci#if (USE_TASKID_AS_HANDLE == 1) 6760d163575Sopenharmony_ci ret = g_cmsTask.status == HANDLE_REGISTED; 6770d163575Sopenharmony_ci#else 6780d163575Sopenharmony_ci ret = g_serviceHandleMap[0].status == HANDLE_REGISTED; 6790d163575Sopenharmony_ci#endif 6800d163575Sopenharmony_ci (VOID)LOS_MuxUnlock(&g_serviceHandleMapMux); 6810d163575Sopenharmony_ci return ret; 6820d163575Sopenharmony_ci} 6830d163575Sopenharmony_ci 6840d163575Sopenharmony_ciLITE_OS_SEC_TEXT STATIC BOOL IsCmsTask(UINT32 taskID) 6850d163575Sopenharmony_ci{ 6860d163575Sopenharmony_ci BOOL ret; 6870d163575Sopenharmony_ci (VOID)LOS_MuxLock(&g_serviceHandleMapMux, LOS_WAIT_FOREVER); 6880d163575Sopenharmony_ci#if (USE_TASKID_AS_HANDLE == 1) 6890d163575Sopenharmony_ci ret = IsCmsSet() ? (OS_TCB_FROM_TID(taskID)->processCB == OS_TCB_FROM_TID(g_cmsTask.taskID)->processCB) : FALSE; 6900d163575Sopenharmony_ci#else 6910d163575Sopenharmony_ci ret = IsCmsSet() ? (OS_TCB_FROM_TID(taskID)->processCB == 6920d163575Sopenharmony_ci OS_TCB_FROM_TID(g_serviceHandleMap[0].taskID)->processCB) : FALSE; 6930d163575Sopenharmony_ci#endif 6940d163575Sopenharmony_ci (VOID)LOS_MuxUnlock(&g_serviceHandleMapMux); 6950d163575Sopenharmony_ci return ret; 6960d163575Sopenharmony_ci} 6970d163575Sopenharmony_ci 6980d163575Sopenharmony_ciLITE_OS_SEC_TEXT STATIC BOOL IsTaskAlive(UINT32 taskID) 6990d163575Sopenharmony_ci{ 7000d163575Sopenharmony_ci LosTaskCB *tcb = NULL; 7010d163575Sopenharmony_ci if (OS_TID_CHECK_INVALID(taskID)) { 7020d163575Sopenharmony_ci return FALSE; 7030d163575Sopenharmony_ci } 7040d163575Sopenharmony_ci tcb = OS_TCB_FROM_TID(taskID); 7050d163575Sopenharmony_ci if (OsTaskIsUnused(tcb)) { 7060d163575Sopenharmony_ci return FALSE; 7070d163575Sopenharmony_ci } 7080d163575Sopenharmony_ci if (OsTaskIsInactive(tcb)) { 7090d163575Sopenharmony_ci return FALSE; 7100d163575Sopenharmony_ci } 7110d163575Sopenharmony_ci if (!OsTaskIsUserMode(tcb)) { 7120d163575Sopenharmony_ci return FALSE; 7130d163575Sopenharmony_ci } 7140d163575Sopenharmony_ci return TRUE; 7150d163575Sopenharmony_ci} 7160d163575Sopenharmony_ci 7170d163575Sopenharmony_ciLITE_OS_SEC_TEXT STATIC UINT32 HandleFd(const LosProcessCB *pcb, SpecialObj *obj, BOOL isRollback) 7180d163575Sopenharmony_ci{ 7190d163575Sopenharmony_ci int ret; 7200d163575Sopenharmony_ci if (isRollback == FALSE) { 7210d163575Sopenharmony_ci ret = CopyFdToProc(obj->content.fd, pcb->processID); 7220d163575Sopenharmony_ci if (ret < 0) { 7230d163575Sopenharmony_ci return ret; 7240d163575Sopenharmony_ci } 7250d163575Sopenharmony_ci obj->content.fd = ret; 7260d163575Sopenharmony_ci } else { 7270d163575Sopenharmony_ci ret = CloseProcFd(obj->content.fd, pcb->processID); 7280d163575Sopenharmony_ci if (ret < 0) { 7290d163575Sopenharmony_ci return ret; 7300d163575Sopenharmony_ci } 7310d163575Sopenharmony_ci } 7320d163575Sopenharmony_ci 7330d163575Sopenharmony_ci return LOS_OK; 7340d163575Sopenharmony_ci} 7350d163575Sopenharmony_ci 7360d163575Sopenharmony_ciLITE_OS_SEC_TEXT STATIC UINT32 HandlePtr(LosProcessCB *pcb, SpecialObj *obj, BOOL isRollback) 7370d163575Sopenharmony_ci{ 7380d163575Sopenharmony_ci VOID *buf = NULL; 7390d163575Sopenharmony_ci UINT32 ret; 7400d163575Sopenharmony_ci if ((obj->content.ptr.buff == NULL) || (obj->content.ptr.buffSz == 0)) { 7410d163575Sopenharmony_ci return -EINVAL; 7420d163575Sopenharmony_ci } 7430d163575Sopenharmony_ci if (isRollback == FALSE) { 7440d163575Sopenharmony_ci if (LOS_IsUserAddress((vaddr_t)(UINTPTR)(obj->content.ptr.buff)) == FALSE) { 7450d163575Sopenharmony_ci PRINT_ERR("Liteipc Bad ptr address\n"); 7460d163575Sopenharmony_ci return -EINVAL; 7470d163575Sopenharmony_ci } 7480d163575Sopenharmony_ci buf = LiteIpcNodeAlloc(pcb, obj->content.ptr.buffSz); 7490d163575Sopenharmony_ci if (buf == NULL) { 7500d163575Sopenharmony_ci PRINT_ERR("Liteipc DealPtr alloc mem failed\n"); 7510d163575Sopenharmony_ci return -EINVAL; 7520d163575Sopenharmony_ci } 7530d163575Sopenharmony_ci ret = copy_from_user(buf, obj->content.ptr.buff, obj->content.ptr.buffSz); 7540d163575Sopenharmony_ci if (ret != LOS_OK) { 7550d163575Sopenharmony_ci LiteIpcNodeFree(pcb, buf); 7560d163575Sopenharmony_ci return ret; 7570d163575Sopenharmony_ci } 7580d163575Sopenharmony_ci obj->content.ptr.buff = (VOID *)GetIpcUserAddr(pcb, (INTPTR)buf); 7590d163575Sopenharmony_ci EnableIpcNodeFreeByUser(pcb, (VOID *)buf); 7600d163575Sopenharmony_ci } else { 7610d163575Sopenharmony_ci buf = (VOID *)GetIpcKernelAddr(pcb, (INTPTR)obj->content.ptr.buff); 7620d163575Sopenharmony_ci if (IsIpcNode(pcb, buf) == TRUE) { 7630d163575Sopenharmony_ci (VOID)LiteIpcNodeFree(pcb, buf); 7640d163575Sopenharmony_ci } 7650d163575Sopenharmony_ci } 7660d163575Sopenharmony_ci return LOS_OK; 7670d163575Sopenharmony_ci} 7680d163575Sopenharmony_ci 7690d163575Sopenharmony_ciLITE_OS_SEC_TEXT STATIC UINT32 HandleSvc(UINT32 dstTid, SpecialObj *obj, BOOL isRollback) 7700d163575Sopenharmony_ci{ 7710d163575Sopenharmony_ci UINT32 taskID = 0; 7720d163575Sopenharmony_ci if (isRollback == FALSE) { 7730d163575Sopenharmony_ci if (obj->content.svc.handle == -1) { 7740d163575Sopenharmony_ci if (obj->content.svc.token != 1) { 7750d163575Sopenharmony_ci PRINT_ERR("Liteipc HandleSvc wrong svc token\n"); 7760d163575Sopenharmony_ci return -EINVAL; 7770d163575Sopenharmony_ci } 7780d163575Sopenharmony_ci UINT32 selfTid = LOS_CurTaskIDGet(); 7790d163575Sopenharmony_ci LosTaskCB *tcb = OS_TCB_FROM_TID(selfTid); 7800d163575Sopenharmony_ci if (tcb->ipcTaskInfo == NULL) { 7810d163575Sopenharmony_ci tcb->ipcTaskInfo = LiteIpcTaskInit(); 7820d163575Sopenharmony_ci } 7830d163575Sopenharmony_ci uint32_t serviceHandle = 0; 7840d163575Sopenharmony_ci UINT32 ret = GenerateServiceHandle(selfTid, HANDLE_REGISTED, &serviceHandle); 7850d163575Sopenharmony_ci if (ret != LOS_OK) { 7860d163575Sopenharmony_ci PRINT_ERR("Liteipc GenerateServiceHandle failed.\n"); 7870d163575Sopenharmony_ci return ret; 7880d163575Sopenharmony_ci } 7890d163575Sopenharmony_ci obj->content.svc.handle = serviceHandle; 7900d163575Sopenharmony_ci (VOID)LOS_MuxLock(&g_serviceHandleMapMux, LOS_WAIT_FOREVER); 7910d163575Sopenharmony_ci AddServiceAccess(dstTid, serviceHandle); 7920d163575Sopenharmony_ci (VOID)LOS_MuxUnlock(&g_serviceHandleMapMux); 7930d163575Sopenharmony_ci } 7940d163575Sopenharmony_ci if (IsTaskAlive(obj->content.svc.handle) == FALSE) { 7950d163575Sopenharmony_ci PRINT_ERR("Liteipc HandleSvc wrong svctid\n"); 7960d163575Sopenharmony_ci return -EINVAL; 7970d163575Sopenharmony_ci } 7980d163575Sopenharmony_ci if (HasServiceAccess(obj->content.svc.handle) == FALSE) { 7990d163575Sopenharmony_ci PRINT_ERR("Liteipc %s, %d, svchandle:%d, tid:%d\n", __FUNCTION__, __LINE__, obj->content.svc.handle, LOS_CurTaskIDGet()); 8000d163575Sopenharmony_ci return -EACCES; 8010d163575Sopenharmony_ci } 8020d163575Sopenharmony_ci LosTaskCB *taskCb = OS_TCB_FROM_TID(obj->content.svc.handle); 8030d163575Sopenharmony_ci if (taskCb->ipcTaskInfo == NULL) { 8040d163575Sopenharmony_ci taskCb->ipcTaskInfo = LiteIpcTaskInit(); 8050d163575Sopenharmony_ci } 8060d163575Sopenharmony_ci if (GetTid(obj->content.svc.handle, &taskID) == 0) { 8070d163575Sopenharmony_ci AddServiceAccess(dstTid, obj->content.svc.handle); 8080d163575Sopenharmony_ci } 8090d163575Sopenharmony_ci } 8100d163575Sopenharmony_ci return LOS_OK; 8110d163575Sopenharmony_ci} 8120d163575Sopenharmony_ci 8130d163575Sopenharmony_ciLITE_OS_SEC_TEXT STATIC UINT32 HandleObj(UINT32 dstTid, SpecialObj *obj, BOOL isRollback) 8140d163575Sopenharmony_ci{ 8150d163575Sopenharmony_ci UINT32 ret; 8160d163575Sopenharmony_ci LosProcessCB *pcb = OS_PCB_FROM_TID(dstTid); 8170d163575Sopenharmony_ci switch (obj->type) { 8180d163575Sopenharmony_ci case OBJ_FD: 8190d163575Sopenharmony_ci ret = HandleFd(pcb, obj, isRollback); 8200d163575Sopenharmony_ci break; 8210d163575Sopenharmony_ci case OBJ_PTR: 8220d163575Sopenharmony_ci ret = HandlePtr(pcb, obj, isRollback); 8230d163575Sopenharmony_ci break; 8240d163575Sopenharmony_ci case OBJ_SVC: 8250d163575Sopenharmony_ci ret = HandleSvc(dstTid, (SpecialObj *)obj, isRollback); 8260d163575Sopenharmony_ci break; 8270d163575Sopenharmony_ci default: 8280d163575Sopenharmony_ci ret = -EINVAL; 8290d163575Sopenharmony_ci break; 8300d163575Sopenharmony_ci } 8310d163575Sopenharmony_ci return ret; 8320d163575Sopenharmony_ci} 8330d163575Sopenharmony_ci 8340d163575Sopenharmony_ciLITE_OS_SEC_TEXT STATIC UINT32 HandleSpecialObjects(UINT32 dstTid, IpcListNode *node, BOOL isRollback) 8350d163575Sopenharmony_ci{ 8360d163575Sopenharmony_ci UINT32 ret = LOS_OK; 8370d163575Sopenharmony_ci IpcMsg *msg = &(node->msg); 8380d163575Sopenharmony_ci INT32 i; 8390d163575Sopenharmony_ci SpecialObj *obj = NULL; 8400d163575Sopenharmony_ci UINT32 *offset = (UINT32 *)(UINTPTR)(msg->offsets); 8410d163575Sopenharmony_ci if (isRollback) { 8420d163575Sopenharmony_ci i = msg->spObjNum; 8430d163575Sopenharmony_ci goto EXIT; 8440d163575Sopenharmony_ci } 8450d163575Sopenharmony_ci for (i = 0; i < msg->spObjNum; i++) { 8460d163575Sopenharmony_ci if (offset[i] > msg->dataSz - sizeof(SpecialObj)) { 8470d163575Sopenharmony_ci ret = -EINVAL; 8480d163575Sopenharmony_ci goto EXIT; 8490d163575Sopenharmony_ci } 8500d163575Sopenharmony_ci if ((i > 0) && (offset[i] < offset[i - 1] + sizeof(SpecialObj))) { 8510d163575Sopenharmony_ci ret = -EINVAL; 8520d163575Sopenharmony_ci goto EXIT; 8530d163575Sopenharmony_ci } 8540d163575Sopenharmony_ci obj = (SpecialObj *)((UINTPTR)msg->data + offset[i]); 8550d163575Sopenharmony_ci if (obj == NULL) { 8560d163575Sopenharmony_ci ret = -EINVAL; 8570d163575Sopenharmony_ci goto EXIT; 8580d163575Sopenharmony_ci } 8590d163575Sopenharmony_ci ret = HandleObj(dstTid, obj, FALSE); 8600d163575Sopenharmony_ci if (ret != LOS_OK) { 8610d163575Sopenharmony_ci goto EXIT; 8620d163575Sopenharmony_ci } 8630d163575Sopenharmony_ci } 8640d163575Sopenharmony_ci return LOS_OK; 8650d163575Sopenharmony_ciEXIT: 8660d163575Sopenharmony_ci for (i--; i >= 0; i--) { 8670d163575Sopenharmony_ci obj = (SpecialObj *)((UINTPTR)msg->data + offset[i]); 8680d163575Sopenharmony_ci (VOID)HandleObj(dstTid, obj, TRUE); 8690d163575Sopenharmony_ci } 8700d163575Sopenharmony_ci return ret; 8710d163575Sopenharmony_ci} 8720d163575Sopenharmony_ci 8730d163575Sopenharmony_ciLITE_OS_SEC_TEXT STATIC UINT32 CheckMsgSize(IpcMsg *msg) 8740d163575Sopenharmony_ci{ 8750d163575Sopenharmony_ci UINT64 totalSize; 8760d163575Sopenharmony_ci UINT32 i; 8770d163575Sopenharmony_ci UINT32 *offset = (UINT32 *)(UINTPTR)(msg->offsets); 8780d163575Sopenharmony_ci SpecialObj *obj = NULL; 8790d163575Sopenharmony_ci if (msg->target.handle != 0) { 8800d163575Sopenharmony_ci return LOS_OK; 8810d163575Sopenharmony_ci } 8820d163575Sopenharmony_ci /* msg send to cms, check the msg size */ 8830d163575Sopenharmony_ci totalSize = (UINT64)sizeof(IpcMsg) + msg->dataSz + msg->spObjNum * sizeof(UINT32); 8840d163575Sopenharmony_ci for (i = 0; i < msg->spObjNum; i++) { 8850d163575Sopenharmony_ci if (offset[i] > msg->dataSz - sizeof(SpecialObj)) { 8860d163575Sopenharmony_ci return -EINVAL; 8870d163575Sopenharmony_ci } 8880d163575Sopenharmony_ci if ((i > 0) && (offset[i] < offset[i - 1] + sizeof(SpecialObj))) { 8890d163575Sopenharmony_ci return -EINVAL; 8900d163575Sopenharmony_ci } 8910d163575Sopenharmony_ci obj = (SpecialObj *)((UINTPTR)msg->data + offset[i]); 8920d163575Sopenharmony_ci if (obj == NULL) { 8930d163575Sopenharmony_ci return -EINVAL; 8940d163575Sopenharmony_ci } 8950d163575Sopenharmony_ci if (obj->type == OBJ_PTR) { 8960d163575Sopenharmony_ci totalSize += obj->content.ptr.buffSz; 8970d163575Sopenharmony_ci } 8980d163575Sopenharmony_ci } 8990d163575Sopenharmony_ci (VOID)LOS_MuxLock(&g_serviceHandleMapMux, LOS_WAIT_FOREVER); 9000d163575Sopenharmony_ci if (totalSize > g_cmsTask.maxMsgSize) { 9010d163575Sopenharmony_ci (VOID)LOS_MuxUnlock(&g_serviceHandleMapMux); 9020d163575Sopenharmony_ci return -EINVAL; 9030d163575Sopenharmony_ci } 9040d163575Sopenharmony_ci (VOID)LOS_MuxUnlock(&g_serviceHandleMapMux); 9050d163575Sopenharmony_ci return LOS_OK; 9060d163575Sopenharmony_ci} 9070d163575Sopenharmony_ci 9080d163575Sopenharmony_ciLITE_OS_SEC_TEXT STATIC UINT32 CopyDataFromUser(IpcListNode *node, UINT32 bufSz, const IpcMsg *msg) 9090d163575Sopenharmony_ci{ 9100d163575Sopenharmony_ci UINT32 ret; 9110d163575Sopenharmony_ci ret = (UINT32)memcpy_s((VOID *)(&node->msg), bufSz - sizeof(LOS_DL_LIST), (const VOID *)msg, sizeof(IpcMsg)); 9120d163575Sopenharmony_ci if (ret != LOS_OK) { 9130d163575Sopenharmony_ci PRINT_DEBUG("%s, %d, %u\n", __FUNCTION__, __LINE__, ret); 9140d163575Sopenharmony_ci return ret; 9150d163575Sopenharmony_ci } 9160d163575Sopenharmony_ci 9170d163575Sopenharmony_ci if (msg->dataSz) { 9180d163575Sopenharmony_ci node->msg.data = (VOID *)((UINTPTR)node + sizeof(IpcListNode)); 9190d163575Sopenharmony_ci ret = copy_from_user((VOID *)(node->msg.data), msg->data, msg->dataSz); 9200d163575Sopenharmony_ci if (ret != LOS_OK) { 9210d163575Sopenharmony_ci PRINT_DEBUG("%s, %d\n", __FUNCTION__, __LINE__); 9220d163575Sopenharmony_ci return ret; 9230d163575Sopenharmony_ci } 9240d163575Sopenharmony_ci } else { 9250d163575Sopenharmony_ci node->msg.data = NULL; 9260d163575Sopenharmony_ci } 9270d163575Sopenharmony_ci 9280d163575Sopenharmony_ci if (msg->spObjNum) { 9290d163575Sopenharmony_ci node->msg.offsets = (VOID *)((UINTPTR)node + sizeof(IpcListNode) + msg->dataSz); 9300d163575Sopenharmony_ci ret = copy_from_user((VOID *)(node->msg.offsets), msg->offsets, msg->spObjNum * sizeof(UINT32)); 9310d163575Sopenharmony_ci if (ret != LOS_OK) { 9320d163575Sopenharmony_ci PRINT_DEBUG("%s, %d, %x, %x, %d\n", __FUNCTION__, __LINE__, node->msg.offsets, msg->offsets, msg->spObjNum); 9330d163575Sopenharmony_ci return ret; 9340d163575Sopenharmony_ci } 9350d163575Sopenharmony_ci } else { 9360d163575Sopenharmony_ci node->msg.offsets = NULL; 9370d163575Sopenharmony_ci } 9380d163575Sopenharmony_ci ret = CheckMsgSize(&node->msg); 9390d163575Sopenharmony_ci if (ret != LOS_OK) { 9400d163575Sopenharmony_ci PRINT_DEBUG("%s, %d\n", __FUNCTION__, __LINE__); 9410d163575Sopenharmony_ci return ret; 9420d163575Sopenharmony_ci } 9430d163575Sopenharmony_ci node->msg.taskID = LOS_CurTaskIDGet(); 9440d163575Sopenharmony_ci node->msg.processID = OsCurrProcessGet()->processID; 9450d163575Sopenharmony_ci#ifdef LOSCFG_SECURITY_CAPABILITY 9460d163575Sopenharmony_ci node->msg.userID = OsCurrProcessGet()->user->userID; 9470d163575Sopenharmony_ci node->msg.gid = OsCurrProcessGet()->user->gid; 9480d163575Sopenharmony_ci#endif 9490d163575Sopenharmony_ci return LOS_OK; 9500d163575Sopenharmony_ci} 9510d163575Sopenharmony_ci 9520d163575Sopenharmony_ciLITE_OS_SEC_TEXT STATIC BOOL IsValidReply(const IpcContent *content) 9530d163575Sopenharmony_ci{ 9540d163575Sopenharmony_ci LosProcessCB *curr = OsCurrProcessGet(); 9550d163575Sopenharmony_ci IpcListNode *node = (IpcListNode *)GetIpcKernelAddr(curr, (INTPTR)(content->buffToFree)); 9560d163575Sopenharmony_ci IpcMsg *requestMsg = &node->msg; 9570d163575Sopenharmony_ci IpcMsg *replyMsg = content->outMsg; 9580d163575Sopenharmony_ci UINT32 reqDstTid = 0; 9590d163575Sopenharmony_ci /* Check whether the reply matches the request */ 9600d163575Sopenharmony_ci if ((requestMsg->type != MT_REQUEST) || 9610d163575Sopenharmony_ci (requestMsg->flag == LITEIPC_FLAG_ONEWAY) || 9620d163575Sopenharmony_ci (replyMsg->timestamp != requestMsg->timestamp) || 9630d163575Sopenharmony_ci (replyMsg->target.handle != requestMsg->taskID) || 9640d163575Sopenharmony_ci (GetTid(requestMsg->target.handle, &reqDstTid) != 0) || 9650d163575Sopenharmony_ci (OS_TCB_FROM_TID(reqDstTid)->processCB != (UINTPTR)curr)) { 9660d163575Sopenharmony_ci return FALSE; 9670d163575Sopenharmony_ci } 9680d163575Sopenharmony_ci return TRUE; 9690d163575Sopenharmony_ci} 9700d163575Sopenharmony_ci 9710d163575Sopenharmony_ciLITE_OS_SEC_TEXT STATIC UINT32 CheckPara(IpcContent *content, UINT32 *dstTid) 9720d163575Sopenharmony_ci{ 9730d163575Sopenharmony_ci UINT32 ret; 9740d163575Sopenharmony_ci IpcMsg *msg = content->outMsg; 9750d163575Sopenharmony_ci UINT32 flag = content->flag; 9760d163575Sopenharmony_ci#if (USE_TIMESTAMP == 1) 9770d163575Sopenharmony_ci UINT64 now = LOS_CurrNanosec(); 9780d163575Sopenharmony_ci#endif 9790d163575Sopenharmony_ci if (((msg->dataSz > 0) && (msg->data == NULL)) || 9800d163575Sopenharmony_ci ((msg->spObjNum > 0) && (msg->offsets == NULL)) || 9810d163575Sopenharmony_ci (msg->dataSz > IPC_MSG_DATA_SZ_MAX) || 9820d163575Sopenharmony_ci (msg->spObjNum > IPC_MSG_OBJECT_NUM_MAX) || 9830d163575Sopenharmony_ci (msg->dataSz < msg->spObjNum * sizeof(SpecialObj))) { 9840d163575Sopenharmony_ci return -EINVAL; 9850d163575Sopenharmony_ci } 9860d163575Sopenharmony_ci switch (msg->type) { 9870d163575Sopenharmony_ci case MT_REQUEST: 9880d163575Sopenharmony_ci if (HasServiceAccess(msg->target.handle)) { 9890d163575Sopenharmony_ci ret = GetTid(msg->target.handle, dstTid); 9900d163575Sopenharmony_ci if (ret != LOS_OK) { 9910d163575Sopenharmony_ci return -EINVAL; 9920d163575Sopenharmony_ci } 9930d163575Sopenharmony_ci } else { 9940d163575Sopenharmony_ci PRINT_ERR("Liteipc %s, %d\n", __FUNCTION__, __LINE__); 9950d163575Sopenharmony_ci return -EACCES; 9960d163575Sopenharmony_ci } 9970d163575Sopenharmony_ci#if (USE_TIMESTAMP == 1) 9980d163575Sopenharmony_ci msg->timestamp = now; 9990d163575Sopenharmony_ci#endif 10000d163575Sopenharmony_ci break; 10010d163575Sopenharmony_ci case MT_REPLY: 10020d163575Sopenharmony_ci case MT_FAILED_REPLY: 10030d163575Sopenharmony_ci if ((flag & BUFF_FREE) != BUFF_FREE) { 10040d163575Sopenharmony_ci return -EINVAL; 10050d163575Sopenharmony_ci } 10060d163575Sopenharmony_ci if (!IsValidReply(content)) { 10070d163575Sopenharmony_ci return -EINVAL; 10080d163575Sopenharmony_ci } 10090d163575Sopenharmony_ci#if (USE_TIMESTAMP == 1) 10100d163575Sopenharmony_ci if (now > msg->timestamp + LITEIPC_TIMEOUT_NS) { 10110d163575Sopenharmony_ci#ifdef LOSCFG_KERNEL_HOOK 10120d163575Sopenharmony_ci ret = GetTid(msg->target.handle, dstTid); 10130d163575Sopenharmony_ci if (ret != LOS_OK) { 10140d163575Sopenharmony_ci *dstTid = INVAILD_ID; 10150d163575Sopenharmony_ci } 10160d163575Sopenharmony_ci#endif 10170d163575Sopenharmony_ci OsHookCall(LOS_HOOK_TYPE_IPC_WRITE_DROP, msg, *dstTid, 10180d163575Sopenharmony_ci (*dstTid == INVAILD_ID) ? INVAILD_ID : OS_PCB_FROM_TID(*dstTid)->processID, 0); 10190d163575Sopenharmony_ci PRINT_ERR("Liteipc A timeout reply, request timestamp:%lld, now:%lld\n", msg->timestamp, now); 10200d163575Sopenharmony_ci return -ETIME; 10210d163575Sopenharmony_ci } 10220d163575Sopenharmony_ci#endif 10230d163575Sopenharmony_ci *dstTid = msg->target.handle; 10240d163575Sopenharmony_ci break; 10250d163575Sopenharmony_ci case MT_DEATH_NOTIFY: 10260d163575Sopenharmony_ci *dstTid = msg->target.handle; 10270d163575Sopenharmony_ci#if (USE_TIMESTAMP == 1) 10280d163575Sopenharmony_ci msg->timestamp = now; 10290d163575Sopenharmony_ci#endif 10300d163575Sopenharmony_ci break; 10310d163575Sopenharmony_ci default: 10320d163575Sopenharmony_ci PRINT_DEBUG("Unknown msg type:%d\n", msg->type); 10330d163575Sopenharmony_ci return -EINVAL; 10340d163575Sopenharmony_ci } 10350d163575Sopenharmony_ci 10360d163575Sopenharmony_ci if (IsTaskAlive(*dstTid) == FALSE) { 10370d163575Sopenharmony_ci return -EINVAL; 10380d163575Sopenharmony_ci } 10390d163575Sopenharmony_ci return LOS_OK; 10400d163575Sopenharmony_ci} 10410d163575Sopenharmony_ci 10420d163575Sopenharmony_ciLITE_OS_SEC_TEXT STATIC UINT32 LiteIpcWrite(IpcContent *content) 10430d163575Sopenharmony_ci{ 10440d163575Sopenharmony_ci UINT32 ret, intSave; 10450d163575Sopenharmony_ci UINT32 dstTid; 10460d163575Sopenharmony_ci 10470d163575Sopenharmony_ci IpcMsg *msg = content->outMsg; 10480d163575Sopenharmony_ci 10490d163575Sopenharmony_ci ret = CheckPara(content, &dstTid); 10500d163575Sopenharmony_ci if (ret != LOS_OK) { 10510d163575Sopenharmony_ci return ret; 10520d163575Sopenharmony_ci } 10530d163575Sopenharmony_ci 10540d163575Sopenharmony_ci LosTaskCB *tcb = OS_TCB_FROM_TID(dstTid); 10550d163575Sopenharmony_ci LosProcessCB *pcb = OS_PCB_FROM_TCB(tcb); 10560d163575Sopenharmony_ci if (pcb->ipcInfo == NULL) { 10570d163575Sopenharmony_ci PRINT_ERR("pid %u Liteipc not create\n", pcb->processID); 10580d163575Sopenharmony_ci return -EINVAL; 10590d163575Sopenharmony_ci } 10600d163575Sopenharmony_ci 10610d163575Sopenharmony_ci UINT32 bufSz = sizeof(IpcListNode) + msg->dataSz + msg->spObjNum * sizeof(UINT32); 10620d163575Sopenharmony_ci IpcListNode *buf = (IpcListNode *)LiteIpcNodeAlloc(pcb, bufSz); 10630d163575Sopenharmony_ci if (buf == NULL) { 10640d163575Sopenharmony_ci PRINT_ERR("%s, %d\n", __FUNCTION__, __LINE__); 10650d163575Sopenharmony_ci return -ENOMEM; 10660d163575Sopenharmony_ci } 10670d163575Sopenharmony_ci ret = CopyDataFromUser(buf, bufSz, (const IpcMsg *)msg); 10680d163575Sopenharmony_ci if (ret != LOS_OK) { 10690d163575Sopenharmony_ci PRINT_ERR("%s, %d\n", __FUNCTION__, __LINE__); 10700d163575Sopenharmony_ci goto ERROR_COPY; 10710d163575Sopenharmony_ci } 10720d163575Sopenharmony_ci 10730d163575Sopenharmony_ci if (tcb->ipcTaskInfo == NULL) { 10740d163575Sopenharmony_ci tcb->ipcTaskInfo = LiteIpcTaskInit(); 10750d163575Sopenharmony_ci } 10760d163575Sopenharmony_ci 10770d163575Sopenharmony_ci ret = HandleSpecialObjects(dstTid, buf, FALSE); 10780d163575Sopenharmony_ci if (ret != LOS_OK) { 10790d163575Sopenharmony_ci PRINT_ERR("%s, %d\n", __FUNCTION__, __LINE__); 10800d163575Sopenharmony_ci goto ERROR_COPY; 10810d163575Sopenharmony_ci } 10820d163575Sopenharmony_ci /* add data to list and wake up dest task */ 10830d163575Sopenharmony_ci SCHEDULER_LOCK(intSave); 10840d163575Sopenharmony_ci LOS_ListTailInsert(&(tcb->ipcTaskInfo->msgListHead), &(buf->listNode)); 10850d163575Sopenharmony_ci OsHookCall(LOS_HOOK_TYPE_IPC_WRITE, &buf->msg, dstTid, pcb->processID, tcb->waitFlag); 10860d163575Sopenharmony_ci if (tcb->waitFlag == OS_TASK_WAIT_LITEIPC) { 10870d163575Sopenharmony_ci OsTaskWakeClearPendMask(tcb); 10880d163575Sopenharmony_ci tcb->ops->wake(tcb); 10890d163575Sopenharmony_ci SCHEDULER_UNLOCK(intSave); 10900d163575Sopenharmony_ci LOS_MpSchedule(OS_MP_CPU_ALL); 10910d163575Sopenharmony_ci LOS_Schedule(); 10920d163575Sopenharmony_ci } else { 10930d163575Sopenharmony_ci SCHEDULER_UNLOCK(intSave); 10940d163575Sopenharmony_ci } 10950d163575Sopenharmony_ci return LOS_OK; 10960d163575Sopenharmony_ciERROR_COPY: 10970d163575Sopenharmony_ci LiteIpcNodeFree(pcb, buf); 10980d163575Sopenharmony_ci return ret; 10990d163575Sopenharmony_ci} 11000d163575Sopenharmony_ci 11010d163575Sopenharmony_ciLITE_OS_SEC_TEXT STATIC UINT32 CheckReceivedMsg(IpcListNode *node, IpcContent *content, LosTaskCB *tcb) 11020d163575Sopenharmony_ci{ 11030d163575Sopenharmony_ci UINT32 ret = LOS_OK; 11040d163575Sopenharmony_ci if (node == NULL) { 11050d163575Sopenharmony_ci return -EINVAL; 11060d163575Sopenharmony_ci } 11070d163575Sopenharmony_ci switch (node->msg.type) { 11080d163575Sopenharmony_ci case MT_REQUEST: 11090d163575Sopenharmony_ci if ((content->flag & SEND) == SEND) { 11100d163575Sopenharmony_ci PRINT_ERR("%s, %d\n", __FUNCTION__, __LINE__); 11110d163575Sopenharmony_ci ret = -EINVAL; 11120d163575Sopenharmony_ci } 11130d163575Sopenharmony_ci break; 11140d163575Sopenharmony_ci case MT_FAILED_REPLY: 11150d163575Sopenharmony_ci ret = -ENOENT; 11160d163575Sopenharmony_ci /* fall-through */ 11170d163575Sopenharmony_ci case MT_REPLY: 11180d163575Sopenharmony_ci if ((content->flag & SEND) != SEND) { 11190d163575Sopenharmony_ci PRINT_ERR("%s, %d\n", __FUNCTION__, __LINE__); 11200d163575Sopenharmony_ci ret = -EINVAL; 11210d163575Sopenharmony_ci } 11220d163575Sopenharmony_ci#if (USE_TIMESTAMP == 1) 11230d163575Sopenharmony_ci if (node->msg.timestamp != content->outMsg->timestamp) { 11240d163575Sopenharmony_ci PRINT_ERR("Receive a unmatch reply, drop it\n"); 11250d163575Sopenharmony_ci ret = -EINVAL; 11260d163575Sopenharmony_ci } 11270d163575Sopenharmony_ci#else 11280d163575Sopenharmony_ci if ((node->msg.code != content->outMsg->code) || 11290d163575Sopenharmony_ci (node->msg.target.token != content->outMsg->target.token)) { 11300d163575Sopenharmony_ci PRINT_ERR("Receive a unmatch reply, drop it\n"); 11310d163575Sopenharmony_ci ret = -EINVAL; 11320d163575Sopenharmony_ci } 11330d163575Sopenharmony_ci#endif 11340d163575Sopenharmony_ci break; 11350d163575Sopenharmony_ci case MT_DEATH_NOTIFY: 11360d163575Sopenharmony_ci break; 11370d163575Sopenharmony_ci default: 11380d163575Sopenharmony_ci PRINT_ERR("Unknown msg type:%d\n", node->msg.type); 11390d163575Sopenharmony_ci ret = -EINVAL; 11400d163575Sopenharmony_ci } 11410d163575Sopenharmony_ci if (ret != LOS_OK) { 11420d163575Sopenharmony_ci OsHookCall(LOS_HOOK_TYPE_IPC_READ_DROP, &node->msg, tcb->waitFlag); 11430d163575Sopenharmony_ci (VOID)HandleSpecialObjects(LOS_CurTaskIDGet(), node, TRUE); 11440d163575Sopenharmony_ci (VOID)LiteIpcNodeFree(OsCurrProcessGet(), (VOID *)node); 11450d163575Sopenharmony_ci } else { 11460d163575Sopenharmony_ci OsHookCall(LOS_HOOK_TYPE_IPC_READ, &node->msg, tcb->waitFlag); 11470d163575Sopenharmony_ci } 11480d163575Sopenharmony_ci return ret; 11490d163575Sopenharmony_ci} 11500d163575Sopenharmony_ci 11510d163575Sopenharmony_ciLITE_OS_SEC_TEXT STATIC UINT32 LiteIpcRead(IpcContent *content) 11520d163575Sopenharmony_ci{ 11530d163575Sopenharmony_ci UINT32 intSave, ret; 11540d163575Sopenharmony_ci UINT32 selfTid = LOS_CurTaskIDGet(); 11550d163575Sopenharmony_ci LOS_DL_LIST *listHead = NULL; 11560d163575Sopenharmony_ci LOS_DL_LIST *listNode = NULL; 11570d163575Sopenharmony_ci IpcListNode *node = NULL; 11580d163575Sopenharmony_ci UINT32 syncFlag = (content->flag & SEND) && (content->flag & RECV); 11590d163575Sopenharmony_ci UINT32 timeout = syncFlag ? LOS_MS2Tick(LITEIPC_TIMEOUT_MS) : LOS_WAIT_FOREVER; 11600d163575Sopenharmony_ci 11610d163575Sopenharmony_ci LosTaskCB *tcb = OS_TCB_FROM_TID(selfTid); 11620d163575Sopenharmony_ci if (tcb->ipcTaskInfo == NULL) { 11630d163575Sopenharmony_ci tcb->ipcTaskInfo = LiteIpcTaskInit(); 11640d163575Sopenharmony_ci } 11650d163575Sopenharmony_ci 11660d163575Sopenharmony_ci listHead = &(tcb->ipcTaskInfo->msgListHead); 11670d163575Sopenharmony_ci do { 11680d163575Sopenharmony_ci SCHEDULER_LOCK(intSave); 11690d163575Sopenharmony_ci if (LOS_ListEmpty(listHead)) { 11700d163575Sopenharmony_ci OsTaskWaitSetPendMask(OS_TASK_WAIT_LITEIPC, OS_INVALID_VALUE, timeout); 11710d163575Sopenharmony_ci OsHookCall(LOS_HOOK_TYPE_IPC_TRY_READ, syncFlag ? MT_REPLY : MT_REQUEST, tcb->waitFlag); 11720d163575Sopenharmony_ci ret = tcb->ops->wait(tcb, &g_ipcPendlist, timeout); 11730d163575Sopenharmony_ci if (ret == LOS_ERRNO_TSK_TIMEOUT) { 11740d163575Sopenharmony_ci OsHookCall(LOS_HOOK_TYPE_IPC_READ_TIMEOUT, syncFlag ? MT_REPLY : MT_REQUEST, tcb->waitFlag); 11750d163575Sopenharmony_ci SCHEDULER_UNLOCK(intSave); 11760d163575Sopenharmony_ci return -ETIME; 11770d163575Sopenharmony_ci } 11780d163575Sopenharmony_ci 11790d163575Sopenharmony_ci if (OsTaskIsKilled(tcb)) { 11800d163575Sopenharmony_ci OsHookCall(LOS_HOOK_TYPE_IPC_KILL, syncFlag ? MT_REPLY : MT_REQUEST, tcb->waitFlag); 11810d163575Sopenharmony_ci SCHEDULER_UNLOCK(intSave); 11820d163575Sopenharmony_ci return -ERFKILL; 11830d163575Sopenharmony_ci } 11840d163575Sopenharmony_ci 11850d163575Sopenharmony_ci SCHEDULER_UNLOCK(intSave); 11860d163575Sopenharmony_ci } else { 11870d163575Sopenharmony_ci listNode = LOS_DL_LIST_FIRST(listHead); 11880d163575Sopenharmony_ci LOS_ListDelete(listNode); 11890d163575Sopenharmony_ci node = LOS_DL_LIST_ENTRY(listNode, IpcListNode, listNode); 11900d163575Sopenharmony_ci SCHEDULER_UNLOCK(intSave); 11910d163575Sopenharmony_ci ret = CheckReceivedMsg(node, content, tcb); 11920d163575Sopenharmony_ci if (ret == LOS_OK) { 11930d163575Sopenharmony_ci break; 11940d163575Sopenharmony_ci } 11950d163575Sopenharmony_ci if (ret == -ENOENT) { /* It means that we've received a failed reply */ 11960d163575Sopenharmony_ci return ret; 11970d163575Sopenharmony_ci } 11980d163575Sopenharmony_ci } 11990d163575Sopenharmony_ci } while (1); 12000d163575Sopenharmony_ci node->msg.data = (VOID *)GetIpcUserAddr(OsCurrProcessGet(), (INTPTR)(node->msg.data)); 12010d163575Sopenharmony_ci node->msg.offsets = (VOID *)GetIpcUserAddr(OsCurrProcessGet(), (INTPTR)(node->msg.offsets)); 12020d163575Sopenharmony_ci content->inMsg = (VOID *)GetIpcUserAddr(OsCurrProcessGet(), (INTPTR)(&(node->msg))); 12030d163575Sopenharmony_ci EnableIpcNodeFreeByUser(OsCurrProcessGet(), (VOID *)node); 12040d163575Sopenharmony_ci return LOS_OK; 12050d163575Sopenharmony_ci} 12060d163575Sopenharmony_ci 12070d163575Sopenharmony_ciLITE_OS_SEC_TEXT STATIC UINT32 LiteIpcMsgHandle(IpcContent *con) 12080d163575Sopenharmony_ci{ 12090d163575Sopenharmony_ci UINT32 ret = LOS_OK; 12100d163575Sopenharmony_ci IpcContent localContent; 12110d163575Sopenharmony_ci IpcContent *content = &localContent; 12120d163575Sopenharmony_ci IpcMsg localMsg; 12130d163575Sopenharmony_ci IpcMsg *msg = &localMsg; 12140d163575Sopenharmony_ci IpcListNode *nodeNeedFree = NULL; 12150d163575Sopenharmony_ci 12160d163575Sopenharmony_ci if (copy_from_user((void *)content, (const void *)con, sizeof(IpcContent)) != LOS_OK) { 12170d163575Sopenharmony_ci PRINT_ERR("%s, %d\n", __FUNCTION__, __LINE__); 12180d163575Sopenharmony_ci return -EINVAL; 12190d163575Sopenharmony_ci } 12200d163575Sopenharmony_ci 12210d163575Sopenharmony_ci if ((content->flag & BUFF_FREE) == BUFF_FREE) { 12220d163575Sopenharmony_ci ret = CheckUsedBuffer(content->buffToFree, &nodeNeedFree); 12230d163575Sopenharmony_ci if (ret != LOS_OK) { 12240d163575Sopenharmony_ci PRINT_ERR("CheckUsedBuffer failed:%d\n", ret); 12250d163575Sopenharmony_ci return ret; 12260d163575Sopenharmony_ci } 12270d163575Sopenharmony_ci } 12280d163575Sopenharmony_ci 12290d163575Sopenharmony_ci if ((content->flag & SEND) == SEND) { 12300d163575Sopenharmony_ci if (content->outMsg == NULL) { 12310d163575Sopenharmony_ci PRINT_ERR("content->outmsg is null\n"); 12320d163575Sopenharmony_ci ret = -EINVAL; 12330d163575Sopenharmony_ci goto BUFFER_FREE; 12340d163575Sopenharmony_ci } 12350d163575Sopenharmony_ci if (copy_from_user((void *)msg, (const void *)content->outMsg, sizeof(IpcMsg)) != LOS_OK) { 12360d163575Sopenharmony_ci PRINT_ERR("%s, %d\n", __FUNCTION__, __LINE__); 12370d163575Sopenharmony_ci ret = -EINVAL; 12380d163575Sopenharmony_ci goto BUFFER_FREE; 12390d163575Sopenharmony_ci } 12400d163575Sopenharmony_ci content->outMsg = msg; 12410d163575Sopenharmony_ci if ((content->outMsg->type < 0) || (content->outMsg->type >= MT_DEATH_NOTIFY)) { 12420d163575Sopenharmony_ci PRINT_ERR("LiteIpc unknown msg type:%d\n", content->outMsg->type); 12430d163575Sopenharmony_ci ret = -EINVAL; 12440d163575Sopenharmony_ci goto BUFFER_FREE; 12450d163575Sopenharmony_ci } 12460d163575Sopenharmony_ci ret = LiteIpcWrite(content); 12470d163575Sopenharmony_ci if (ret != LOS_OK) { 12480d163575Sopenharmony_ci PRINT_ERR("LiteIpcWrite failed\n"); 12490d163575Sopenharmony_ci goto BUFFER_FREE; 12500d163575Sopenharmony_ci } 12510d163575Sopenharmony_ci } 12520d163575Sopenharmony_ciBUFFER_FREE: 12530d163575Sopenharmony_ci if (nodeNeedFree != NULL) { 12540d163575Sopenharmony_ci UINT32 freeRet = LiteIpcNodeFree(OsCurrProcessGet(), nodeNeedFree); 12550d163575Sopenharmony_ci ret = (freeRet == LOS_OK) ? ret : freeRet; 12560d163575Sopenharmony_ci } 12570d163575Sopenharmony_ci if (ret != LOS_OK) { 12580d163575Sopenharmony_ci return ret; 12590d163575Sopenharmony_ci } 12600d163575Sopenharmony_ci 12610d163575Sopenharmony_ci if ((content->flag & RECV) == RECV) { 12620d163575Sopenharmony_ci ret = LiteIpcRead(content); 12630d163575Sopenharmony_ci if (ret != LOS_OK) { 12640d163575Sopenharmony_ci PRINT_ERR("LiteIpcRead failed ERROR: %d\n", (INT32)ret); 12650d163575Sopenharmony_ci return ret; 12660d163575Sopenharmony_ci } 12670d163575Sopenharmony_ci UINT32 offset = LOS_OFF_SET_OF(IpcContent, inMsg); 12680d163575Sopenharmony_ci ret = copy_to_user((char*)con + offset, (char*)content + offset, sizeof(IpcMsg *)); 12690d163575Sopenharmony_ci if (ret != LOS_OK) { 12700d163575Sopenharmony_ci PRINT_ERR("%s, %d, %d\n", __FUNCTION__, __LINE__, ret); 12710d163575Sopenharmony_ci return -EINVAL; 12720d163575Sopenharmony_ci } 12730d163575Sopenharmony_ci } 12740d163575Sopenharmony_ci return ret; 12750d163575Sopenharmony_ci} 12760d163575Sopenharmony_ci 12770d163575Sopenharmony_ciLITE_OS_SEC_TEXT STATIC UINT32 HandleCmsCmd(CmsCmdContent *content) 12780d163575Sopenharmony_ci{ 12790d163575Sopenharmony_ci UINT32 ret = LOS_OK; 12800d163575Sopenharmony_ci CmsCmdContent localContent; 12810d163575Sopenharmony_ci if (content == NULL) { 12820d163575Sopenharmony_ci return -EINVAL; 12830d163575Sopenharmony_ci } 12840d163575Sopenharmony_ci if (IsCmsTask(LOS_CurTaskIDGet()) == FALSE) { 12850d163575Sopenharmony_ci return -EACCES; 12860d163575Sopenharmony_ci } 12870d163575Sopenharmony_ci if (copy_from_user((void *)(&localContent), (const void *)content, sizeof(CmsCmdContent)) != LOS_OK) { 12880d163575Sopenharmony_ci PRINT_ERR("%s, %d\n", __FUNCTION__, __LINE__); 12890d163575Sopenharmony_ci return -EINVAL; 12900d163575Sopenharmony_ci } 12910d163575Sopenharmony_ci switch (localContent.cmd) { 12920d163575Sopenharmony_ci case CMS_GEN_HANDLE: 12930d163575Sopenharmony_ci if ((localContent.taskID != 0) && (IsTaskAlive(localContent.taskID) == FALSE)) { 12940d163575Sopenharmony_ci return -EINVAL; 12950d163575Sopenharmony_ci } 12960d163575Sopenharmony_ci ret = GenerateServiceHandle(localContent.taskID, HANDLE_REGISTED, &(localContent.serviceHandle)); 12970d163575Sopenharmony_ci if (ret == LOS_OK) { 12980d163575Sopenharmony_ci ret = copy_to_user((void *)content, (const void *)(&localContent), sizeof(CmsCmdContent)); 12990d163575Sopenharmony_ci } 13000d163575Sopenharmony_ci (VOID)LOS_MuxLock(&g_serviceHandleMapMux, LOS_WAIT_FOREVER); 13010d163575Sopenharmony_ci AddServiceAccess(g_cmsTask.taskID, localContent.serviceHandle); 13020d163575Sopenharmony_ci (VOID)LOS_MuxUnlock(&g_serviceHandleMapMux); 13030d163575Sopenharmony_ci break; 13040d163575Sopenharmony_ci case CMS_REMOVE_HANDLE: 13050d163575Sopenharmony_ci if (localContent.serviceHandle >= MAX_SERVICE_NUM) { 13060d163575Sopenharmony_ci return -EINVAL; 13070d163575Sopenharmony_ci } 13080d163575Sopenharmony_ci RefreshServiceHandle(localContent.serviceHandle, -1); 13090d163575Sopenharmony_ci break; 13100d163575Sopenharmony_ci case CMS_ADD_ACCESS: 13110d163575Sopenharmony_ci if (IsTaskAlive(localContent.taskID) == FALSE) { 13120d163575Sopenharmony_ci return -EINVAL; 13130d163575Sopenharmony_ci } 13140d163575Sopenharmony_ci return AddServiceAccess(localContent.taskID, localContent.serviceHandle); 13150d163575Sopenharmony_ci default: 13160d163575Sopenharmony_ci PRINT_DEBUG("Unknown cmd cmd:%d\n", localContent.cmd); 13170d163575Sopenharmony_ci return -EINVAL; 13180d163575Sopenharmony_ci } 13190d163575Sopenharmony_ci return ret; 13200d163575Sopenharmony_ci} 13210d163575Sopenharmony_ci 13220d163575Sopenharmony_ciLITE_OS_SEC_TEXT STATIC UINT32 HandleGetVersion(IpcVersion *version) 13230d163575Sopenharmony_ci{ 13240d163575Sopenharmony_ci UINT32 ret = LOS_OK; 13250d163575Sopenharmony_ci IpcVersion localIpcVersion; 13260d163575Sopenharmony_ci if (version == NULL) { 13270d163575Sopenharmony_ci return -EINVAL; 13280d163575Sopenharmony_ci } 13290d163575Sopenharmony_ci 13300d163575Sopenharmony_ci localIpcVersion.driverVersion = DRIVER_VERSION; 13310d163575Sopenharmony_ci ret = copy_to_user((void *)version, (const void *)(&localIpcVersion), sizeof(IpcVersion)); 13320d163575Sopenharmony_ci if (ret != LOS_OK) { 13330d163575Sopenharmony_ci PRINT_ERR("%s, %d\n", __FUNCTION__, __LINE__); 13340d163575Sopenharmony_ci } 13350d163575Sopenharmony_ci return ret; 13360d163575Sopenharmony_ci} 13370d163575Sopenharmony_ci 13380d163575Sopenharmony_ciLITE_OS_SEC_TEXT int LiteIpcIoctl(struct file *filep, int cmd, unsigned long arg) 13390d163575Sopenharmony_ci{ 13400d163575Sopenharmony_ci UINT32 ret = LOS_OK; 13410d163575Sopenharmony_ci LosProcessCB *pcb = OsCurrProcessGet(); 13420d163575Sopenharmony_ci ProcIpcInfo *ipcInfo = pcb->ipcInfo; 13430d163575Sopenharmony_ci 13440d163575Sopenharmony_ci if (ipcInfo == NULL) { 13450d163575Sopenharmony_ci PRINT_ERR("Liteipc pool not create!\n"); 13460d163575Sopenharmony_ci return -EINVAL; 13470d163575Sopenharmony_ci } 13480d163575Sopenharmony_ci 13490d163575Sopenharmony_ci if (IsPoolMapped(ipcInfo) == FALSE) { 13500d163575Sopenharmony_ci PRINT_ERR("Liteipc Ipc pool not init, need to mmap first!\n"); 13510d163575Sopenharmony_ci return -ENOMEM; 13520d163575Sopenharmony_ci } 13530d163575Sopenharmony_ci 13540d163575Sopenharmony_ci switch (cmd) { 13550d163575Sopenharmony_ci case IPC_SET_CMS: 13560d163575Sopenharmony_ci return (INT32)SetCms(arg); 13570d163575Sopenharmony_ci case IPC_CMS_CMD: 13580d163575Sopenharmony_ci return (INT32)HandleCmsCmd((CmsCmdContent *)(UINTPTR)arg); 13590d163575Sopenharmony_ci case IPC_GET_VERSION: 13600d163575Sopenharmony_ci return (INT32)HandleGetVersion((IpcVersion *)(UINTPTR)arg); 13610d163575Sopenharmony_ci case IPC_SET_IPC_THREAD: 13620d163575Sopenharmony_ci if (IsCmsSet() == FALSE) { 13630d163575Sopenharmony_ci PRINT_ERR("Liteipc ServiceManager not set!\n"); 13640d163575Sopenharmony_ci return -EINVAL; 13650d163575Sopenharmony_ci } 13660d163575Sopenharmony_ci return (INT32)SetIpcTask(); 13670d163575Sopenharmony_ci case IPC_SEND_RECV_MSG: 13680d163575Sopenharmony_ci if (arg == 0) { 13690d163575Sopenharmony_ci return -EINVAL; 13700d163575Sopenharmony_ci } 13710d163575Sopenharmony_ci if (IsCmsSet() == FALSE) { 13720d163575Sopenharmony_ci PRINT_ERR("Liteipc ServiceManager not set!\n"); 13730d163575Sopenharmony_ci return -EINVAL; 13740d163575Sopenharmony_ci } 13750d163575Sopenharmony_ci ret = LiteIpcMsgHandle((IpcContent *)(UINTPTR)arg); 13760d163575Sopenharmony_ci if (ret != LOS_OK) { 13770d163575Sopenharmony_ci return (INT32)ret; 13780d163575Sopenharmony_ci } 13790d163575Sopenharmony_ci break; 13800d163575Sopenharmony_ci default: 13810d163575Sopenharmony_ci PRINT_ERR("Unknown liteipc ioctl cmd:%d\n", cmd); 13820d163575Sopenharmony_ci return -EINVAL; 13830d163575Sopenharmony_ci } 13840d163575Sopenharmony_ci return (INT32)ret; 13850d163575Sopenharmony_ci} 1386