kernel: add a temporary 'munmap' sysfunc

This commit is contained in:
K. Lange 2022-03-06 15:58:38 +09:00
parent 49fd67bf2d
commit 4c2ec1f0a0
3 changed files with 47 additions and 0 deletions

View File

@ -643,6 +643,24 @@ void mmu_set_directory(union PML * new_pml) {
void mmu_invalidate(uintptr_t addr) {
}
void mmu_unmap_user(uintptr_t addr, size_t size) {
for (uintptr_t a = addr; a < addr + size; a += PAGE_SIZE) {
if (a >= USER_DEVICE_MAP && a <= USER_SHM_HIGH) continue;
union PML * page = mmu_get_page(a, 0);
spin_lock(frame_alloc_lock);
if (page && page->bits.present) {
if (page->bits.ap & 1) {
mmu_frame_clear((uintptr_t)page->bits.page << PAGE_SHIFT);
page->bits.present = 0;
page->bits.ap = 0;
}
}
mmu_invalidate(a);
spin_unlock(frame_alloc_lock);
}
}
static char * heapStart = NULL;
extern char end[];

View File

@ -836,6 +836,27 @@ void mmu_invalidate(uintptr_t addr) {
arch_tlb_shootdown(addr);
}
void mmu_unmap_user(uintptr_t addr, size_t size) {
for (uintptr_t a = addr; a < addr + size; a += PAGE_SIZE) {
if (a >= USER_DEVICE_MAP && a <= USER_SHM_HIGH) continue;
spin_lock(frame_alloc_lock);
union PML * page = mmu_get_page(a, 0);
if (page && page->bits.present && page->bits.user) {
if (page->bits.writable) {
assert(mem_refcounts[page->bits.page] == 0);
mmu_frame_clear((uintptr_t)page->bits.page << PAGE_SHIFT);
} else if (refcount_dec(page->bits.page) == 0) {
mmu_frame_clear((uintptr_t)page->bits.page << PAGE_SHIFT);
}
page->bits.present = 0;
page->bits.writable = 0;
}
mmu_invalidate(a);
spin_unlock(frame_alloc_lock);
}
}
static char * heapStart = NULL;
extern char end[];

View File

@ -104,6 +104,14 @@ long sys_sysfunc(long fn, char ** args) {
#endif
return 0;
case 43: {
extern void mmu_unmap_user(uintptr_t addr, size_t size);
PTR_VALIDATE(&args[0]);
PTR_VALIDATE(&args[1]);
mmu_unmap_user((uintptr_t)args[0], (size_t)args[1]);
return 0;
}
case TOARU_SYS_FUNC_INSMOD:
/* Linux has init_module as a system call? */
if (this_core->current_process->user != 0) return -EACCES;