fix: 合并进程栈两个地址连续的region

背景:进程加载的时候,先预申请一个页用作参数拷贝,另外通过mmap方式申请
额外的虚拟栈空间,此时便有两个地址连续的区间。
方案:新增内部接口OsStackAlloc,用于申请一个连续的虚拟地址区间,并对其
中指定区间做物理内存的映射。

close #I43QYJ

Signed-off-by: Haryslee <lihao189@huawei.com>
Change-Id: I224cca3671c42a94c2f74b2da5a11403849e33d3
This commit is contained in:
Haryslee
2021-08-09 16:54:22 +08:00
parent 024a8f2771
commit 42f374dd7a
4 changed files with 48 additions and 87 deletions

View File

@@ -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);

View File

@@ -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);
/**

View File

@@ -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;