mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-10-29 05:38:21 +00:00
vmm: address space forking
This commit is contained in:
@@ -65,4 +65,6 @@ bool vmm_allocnowat(void* addr, size_t mmuflags, size_t size);
|
||||
void* vmm_allocfrom(void* addr, size_t mmuflags, size_t size);
|
||||
vmm_context* vmm_newcontext();
|
||||
void vmm_switchcontext(vmm_context*);
|
||||
int vmm_fork(vmm_context* oldctx, vmm_context* newctx);
|
||||
|
||||
#endif
|
||||
|
||||
+71
-2
@@ -366,6 +366,77 @@ static void getcontextinfo(void* addr, int** lock, vmm_mapping*** start){
|
||||
|
||||
}
|
||||
|
||||
int vmm_fork(vmm_context* oldctx, vmm_context* newctx){
|
||||
|
||||
// TODO make this copy on write
|
||||
|
||||
spinlock_acquire(&oldctx->lock);
|
||||
spinlock_acquire(&newctx->lock);
|
||||
|
||||
vmm_mapping* mapping = oldctx->userstart;
|
||||
|
||||
while(mapping){
|
||||
|
||||
if(mapping->type == VMM_TYPE_FILE)
|
||||
_panic("File mappings not supported yet!", NULL);
|
||||
|
||||
size_t pagesize =((uintptr_t)mapping->end - (uintptr_t)mapping->start + 1) / PAGE_SIZE;
|
||||
|
||||
if(!setmap(&newctx->userstart, mapping->start, pagesize, mapping->mmuflags, mapping->type, mapping->data, mapping->offset))
|
||||
|
||||
goto _fail;
|
||||
|
||||
|
||||
|
||||
if(mapping->type == VMM_TYPE_ANON){
|
||||
|
||||
|
||||
for(uintmax_t page = 0; page < pagesize; ++page){
|
||||
void* pageaddr = mapping->start + page*PAGE_SIZE;
|
||||
|
||||
if(arch_mmu_ismapped(oldctx->context, pageaddr) == false)
|
||||
continue;
|
||||
|
||||
void* newp = pmm_alloc(1);
|
||||
|
||||
if(!newp)
|
||||
goto _fail;
|
||||
|
||||
if(!arch_mmu_map(newctx->context, newp, pageaddr, mapping->mmuflags))
|
||||
goto _fail;
|
||||
|
||||
|
||||
void* oldp = arch_mmu_getphysicaladdr(oldctx->context, pageaddr);
|
||||
|
||||
oldp += (uintptr_t)limine_hhdm_offset;
|
||||
newp += (uintptr_t)limine_hhdm_offset;
|
||||
|
||||
memcpy(newp, oldp, PAGE_SIZE);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
mapping = mapping->next;
|
||||
|
||||
}
|
||||
|
||||
|
||||
spinlock_release(&oldctx->lock);
|
||||
spinlock_release(&newctx->lock);
|
||||
return 0;
|
||||
|
||||
_fail:
|
||||
spinlock_release(&oldctx->lock);
|
||||
spinlock_release(&newctx->lock);
|
||||
return ENOMEM;
|
||||
|
||||
|
||||
}
|
||||
|
||||
void* vmm_alloc(size_t pagec, size_t mmuflags){
|
||||
spinlock_acquire(&klock);
|
||||
|
||||
@@ -505,8 +576,6 @@ bool vmm_allocnowat(void* addr, size_t mmuflags, size_t size){
|
||||
for(size_t page = 0; page < size && result; ++page)
|
||||
result = arch_mmu_map(arch_getcls()->context->context, paddr + page*PAGE_SIZE, addr + page*PAGE_SIZE, mmuflags);
|
||||
|
||||
if(!result)
|
||||
pmm_free(paddr, size);
|
||||
|
||||
spinlock_release(lock);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user