fix: 合并进程栈两个地址连续的region
背景:进程加载的时候,先预申请一个页用作参数拷贝,另外通过mmap方式申请 额外的虚拟栈空间,此时便有两个地址连续的区间。 方案:新增内部接口OsStackAlloc,用于申请一个连续的虚拟地址区间,并对其 中指定区间做物理内存的映射。 close #I43QYJ Signed-off-by: Haryslee <lihao189@huawei.com> Change-Id: I224cca3671c42a94c2f74b2da5a11403849e33d3
This commit is contained in:
@@ -456,7 +456,6 @@ extern UINT32 OsExecStart(const TSK_ENTRY_FUNC entry, UINTPTR sp, UINTPTR mapBas
|
||||
extern UINT32 OsSetProcessName(LosProcessCB *processCB, const CHAR *name);
|
||||
extern INT32 OsSetProcessScheduler(INT32 which, INT32 pid, UINT16 prio, UINT16 policy);
|
||||
extern INT32 OsGetProcessPriority(INT32 which, INT32 pid);
|
||||
extern VOID *OsUserStackAlloc(UINT32 processID, UINT32 *size);
|
||||
extern UINT32 OsGetUserInitProcessID(VOID);
|
||||
extern UINT32 OsGetIdleProcessID(VOID);
|
||||
extern INT32 OsSetProcessGroupID(UINT32 pid, UINT32 gid);
|
||||
|
||||
@@ -288,7 +288,6 @@ STATUS_T LOS_VaddrToPaddrMmap(LosVmSpace *space, VADDR_T vaddr, PADDR_T paddr, s
|
||||
BOOL OsUserVmSpaceInit(LosVmSpace *vmSpace, VADDR_T *virtTtb);
|
||||
LosVmSpace *OsCreateUserVmSpace(VOID);
|
||||
STATUS_T LOS_VmSpaceClone(LosVmSpace *oldVmSpace, LosVmSpace *newVmSpace);
|
||||
STATUS_T LOS_UserSpaceVmAlloc(LosVmSpace *space, size_t size, VOID **ptr, UINT8 align_log2, UINT32 regionFlags);
|
||||
LosMux *OsGVmSpaceMuxGet(VOID);
|
||||
STATUS_T OsUnMMap(LosVmSpace *space, VADDR_T addr, size_t size);
|
||||
/**
|
||||
|
||||
@@ -985,73 +985,6 @@ STATUS_T LOS_VaddrToPaddrMmap(LosVmSpace *space, VADDR_T vaddr, PADDR_T paddr, s
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
STATUS_T LOS_UserSpaceVmAlloc(LosVmSpace *space, size_t size, VOID **ptr, UINT8 align_log2, UINT32 regionFlags)
|
||||
{
|
||||
STATUS_T err = LOS_OK;
|
||||
VADDR_T vaddr = 0;
|
||||
size_t sizeCount;
|
||||
size_t count;
|
||||
LosVmPage *vmPage = NULL;
|
||||
VADDR_T vaddrTemp;
|
||||
PADDR_T paddrTemp;
|
||||
LosVmMapRegion *region = NULL;
|
||||
|
||||
size = ROUNDUP(size, PAGE_SIZE);
|
||||
if (size == 0) {
|
||||
return LOS_ERRNO_VM_INVALID_ARGS;
|
||||
}
|
||||
sizeCount = (size >> PAGE_SHIFT);
|
||||
|
||||
/* if they're asking for a specific spot, copy the address */
|
||||
if (ptr != NULL) {
|
||||
vaddr = (VADDR_T)(UINTPTR)*ptr;
|
||||
}
|
||||
/* allocate physical memory up front, in case it cant be satisfied */
|
||||
/* allocate a random pile of pages */
|
||||
LOS_DL_LIST_HEAD(pageList);
|
||||
|
||||
(VOID)LOS_MuxAcquire(&space->regionMux);
|
||||
count = LOS_PhysPagesAlloc(sizeCount, &pageList);
|
||||
if (count < sizeCount) {
|
||||
VM_ERR("failed to allocate enough pages (ask %zu, got %zu)", sizeCount, count);
|
||||
err = LOS_ERRNO_VM_NO_MEMORY;
|
||||
goto MEMORY_ALLOC_FAIL;
|
||||
}
|
||||
|
||||
/* allocate a region and put it in the aspace list */
|
||||
region = LOS_RegionAlloc(space, vaddr, size, regionFlags, 0);
|
||||
if (!region) {
|
||||
err = LOS_ERRNO_VM_NO_MEMORY;
|
||||
VM_ERR("failed to allocate region, vaddr: %#x, size: %#x, space: %#x", vaddr, size, space);
|
||||
goto MEMORY_ALLOC_FAIL;
|
||||
}
|
||||
|
||||
/* return the vaddr if requested */
|
||||
if (ptr != NULL) {
|
||||
*ptr = (VOID *)(UINTPTR)region->range.base;
|
||||
}
|
||||
|
||||
/* map all of the pages */
|
||||
vaddrTemp = region->range.base;
|
||||
while ((vmPage = LOS_ListRemoveHeadType(&pageList, LosVmPage, node))) {
|
||||
paddrTemp = vmPage->physAddr;
|
||||
LOS_AtomicInc(&vmPage->refCounts);
|
||||
err = LOS_ArchMmuMap(&space->archMmu, vaddrTemp, paddrTemp, 1, regionFlags);
|
||||
if (err != 1) {
|
||||
LOS_Panic("%s %d, LOS_ArchMmuMap failed!, err: %d\n", __FUNCTION__, __LINE__, err);
|
||||
}
|
||||
vaddrTemp += PAGE_SIZE;
|
||||
}
|
||||
err = LOS_OK;
|
||||
goto VMM_ALLOC_SUCCEED;
|
||||
|
||||
MEMORY_ALLOC_FAIL:
|
||||
(VOID)LOS_PhysPagesFree(&pageList);
|
||||
VMM_ALLOC_SUCCEED:
|
||||
(VOID)LOS_MuxRelease(&space->regionMux);
|
||||
return err;
|
||||
}
|
||||
|
||||
VOID *LOS_VMalloc(size_t size)
|
||||
{
|
||||
LosVmSpace *space = &g_vMallocSpace;
|
||||
|
||||
Reference in New Issue
Block a user