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