mm: rename vmm api to mm

This commit is contained in:
Matheus
2026-07-01 14:57:05 -03:00
parent c650036cfe
commit 239c267ed3
47 changed files with 402 additions and 413 deletions
+1 -2
View File
@@ -1,5 +1,4 @@
#include <kernel/mm.h>
#include <kernel/vmm.h>
#include <util.h>
#include <logging.h>
#include <kernel/timekeeper.h>
@@ -487,7 +486,7 @@ static void writer() {
void mm_cache_init(void) {
MUTEX_INIT(&mutex);
table = vmm_map(NULL, TABLE_SIZE * sizeof(page_t *), VMM_FLAGS_ALLOCATE, ARCH_MMU_FLAGS_READ | ARCH_MMU_FLAGS_WRITE | ARCH_MMU_FLAGS_NOEXEC, NULL);
table = mm_map(NULL, TABLE_SIZE * sizeof(page_t *), MM_RANGE_FLAGS_ALLOCATE, ARCH_MMU_FLAGS_READ | ARCH_MMU_FLAGS_WRITE | ARCH_MMU_FLAGS_NOEXEC, NULL);
__assert(table);
memset(table, 0, TABLE_SIZE * sizeof(page_t *));
+114 -116
View File
@@ -1,4 +1,4 @@
#include <kernel/vmm.h>
#include <kernel/mm.h>
#include <logging.h>
#include <kernel/page.h>
#include <util.h>
@@ -6,29 +6,28 @@
#include <limine.h>
#include <string.h>
#include <kernel/slab.h>
#include <kernel/mm.h>
#include <kernel/init.h>
// ranges are separated into kernel and user. the kernel has a temporary user context
vmmcontext_t vmm_kernelctx;
static vmmspace_t kernelspace = {
mm_context_t mm_kernel_ctx;
static mm_space_t kernelspace = {
.start = KERNELSPACE_START,
.end = KERNELSPACE_END
};
// returns a pointer to the space of vaddr
static vmmspace_t *getspace(void *vaddr) {
static mm_space_t *getspace(void *vaddr) {
if (USERSPACE_START <= vaddr && vaddr < USERSPACE_END)
return &current_vmm_context()->space;
return &current_mm_context()->space;
else if (KERNELSPACE_START <= vaddr && vaddr < KERNELSPACE_END)
return &kernelspace;
else
return NULL;
}
static int vmm_range_compare(rbtree_t *a, rbtree_t *b) {
vmmrange_t *range_a = container_of(a, vmmrange_t, rbtree_node);
vmmrange_t *range_b = container_of(b, vmmrange_t, rbtree_node);
static int mm_range_compare(rbtree_t *a, rbtree_t *b) {
mm_range_t *range_a = container_of(a, mm_range_t, rbtree_node);
mm_range_t *range_b = container_of(b, mm_range_t, rbtree_node);
if (range_a->start == range_b->start)
return 0;
@@ -36,10 +35,10 @@ static int vmm_range_compare(rbtree_t *a, rbtree_t *b) {
return range_a->start > range_b->start ? 1 : -1;
}
int vmm_changemmuflags(void *base, size_t size, mmuflags_t mmuflags, int flags) {
int mm_change_mmu_flags(void *base, size_t size, mmuflags_t mmuflags, int flags) {
base = (void *)ROUND_DOWN((uintptr_t)base, PAGE_SIZE);
if (flags & VMM_FLAGS_PAGESIZE)
if (flags & MM_RANGE_FLAGS_PAGESIZE)
size *= PAGE_SIZE;
else
size = ROUND_UP(size, PAGE_SIZE);
@@ -47,7 +46,7 @@ int vmm_changemmuflags(void *base, size_t size, mmuflags_t mmuflags, int flags)
if (size == 0)
return 0;
vmmspace_t *space = getspace(base);
mm_space_t *space = getspace(base);
if (space == NULL)
return ENOMEM;
@@ -63,40 +62,40 @@ int vmm_changemmuflags(void *base, size_t size, mmuflags_t mmuflags, int flags)
return error;
}
static void printspace(vmmspace_t *space) {
printf("vmm: ranges:\n");
static void printspace(mm_space_t *space) {
printf("mm: ranges:\n");
rbtree_t *rbtree = rbtree_first(space->ranges);
while (rbtree) {
vmmrange_t *range = container_of(rbtree, vmmrange_t, rbtree_node);
printf("vmm: address %p size %lx flags %x\n", range->start, range->size, range->flags);
mm_range_t *range = container_of(rbtree, mm_range_t, rbtree_node);
printf("mm: address %p size %lx flags %x\n", range->start, range->size, range->flags);
rbtree = rbtree_successor(rbtree);
}
}
static void *zeropage;
bool vmm_pagefault(void *addr, bool user, int actions) {
bool mm_handle_page_fault(void *addr, bool user, int actions) {
if (user == false && addr > USERSPACE_END) {
printf("vmm: kernel access\n");
printf("mm: kernel access\n");
return false;
}
addr = (void *)ROUND_DOWN((uintptr_t)addr, PAGE_SIZE);
vmmspace_t *space = getspace(addr);
mm_space_t *space = getspace(addr);
if (space == NULL || (space == &kernelspace && user)) {
printf("vmm: no such space or space accessed is kerneç\n");
printf("mm: no such space or space accessed is kernel\n");
return false;
}
MUTEX_ACQUIRE(&space->lock);
vmmrange_t *range = mm_get_range(space, addr);
mm_range_t *range = mm_get_range(space, addr);
bool status = false;
if (range == NULL) {
printf("vmm: no range\n");
printf("mm: no range\n");
goto cleanup;
}
@@ -105,16 +104,16 @@ bool vmm_pagefault(void *addr, bool user, int actions) {
int invalidactions = 0;
if ((range->mmuflags & ARCH_MMU_FLAGS_READ) == 0)
invalidactions |= VMM_ACTION_READ;
invalidactions |= MM_FAULT_ACTION_READ;
if ((range->mmuflags & ARCH_MMU_FLAGS_WRITE) == 0)
invalidactions |= VMM_ACTION_WRITE;
invalidactions |= MM_FAULT_ACTION_WRITE;
if ((range->mmuflags & ARCH_MMU_FLAGS_NOEXEC))
invalidactions |= VMM_ACTION_EXEC;
invalidactions |= MM_FAULT_ACTION_EXEC;
if (invalidactions & actions) {
printf("vmm: bad action\n");
printf("mm: bad action\n");
goto cleanup;
}
@@ -122,14 +121,14 @@ bool vmm_pagefault(void *addr, bool user, int actions) {
proc_t *proc = thread ? thread->proc : NULL;
cred_t *cred = proc ? &proc->cred : NULL;
if (arch_mmu_ispresent(current_vmm_context()->pagetable, addr) == false) {
if (arch_mmu_ispresent(current_mm_context()->pagetable, addr) == false) {
// page not present in the page tables
if (range->flags & VMM_FLAGS_FILE) {
if (range->flags & MM_RANGE_FLAGS_FILE) {
uintmax_t mapoffset = (uintptr_t)addr - (uintptr_t)range->start;
if (vfs_iscacheable(range->vnode) == false) {
// map non cacheable vnodes
VOP_LOCK(range->vnode);
__assert(VOP_MMAP(range->vnode, addr, range->offset + mapoffset, mmuflagstovnodeflags(range->mmuflags) | (range->flags & VMM_FLAGS_SHARED ? V_FFLAGS_SHARED : 0), cred) == 0);
__assert(VOP_MMAP(range->vnode, addr, range->offset + mapoffset, mm_mmu_flags_to_vnode_flags(range->mmuflags) | (range->flags & MM_RANGE_FLAGS_SHARED ? V_FFLAGS_SHARED : 0), cred) == 0);
VOP_UNLOCK(range->vnode);
status = true;
} else {
@@ -139,17 +138,17 @@ bool vmm_pagefault(void *addr, bool user, int actions) {
if (error == ENXIO || error == ENOMEM) {
if (error == ENOMEM)
printf("vmm: out of memory to handle getpage (sending SIGBUS)\n");
printf("mm: out of memory to handle getpage (sending SIGBUS)\n");
// address is past the last page of the file
signal_signalthread(current_thread(), SIGBUS, true);
status = true;
} else if (error) {
printf("vmm: error on mm_cache_get_page(): %d\n", error);
printf("mm: error on mm_cache_get_page(): %d\n", error);
status = false;
} else {
status = arch_mmu_map(current_vmm_context()->pagetable, mm_get_page_address(res), addr, range->mmuflags & ~ARCH_MMU_FLAGS_WRITE);
status = arch_mmu_map(current_mm_context()->pagetable, mm_get_page_address(res), addr, range->mmuflags & ~ARCH_MMU_FLAGS_WRITE);
if (!status) {
printf("vmm: out of memory to map file into address space (sending SIGBUS)\n");
printf("mm: out of memory to map file into address space (sending SIGBUS)\n");
mm_release_page(mm_get_page_address(res));
signal_signalthread(current_thread(), SIGBUS, true);
status = true;
@@ -163,39 +162,39 @@ bool vmm_pagefault(void *addr, bool user, int actions) {
// writeable range: allocate a new page, zero it and map it
void *new_page = mm_alloc_page(MEMORY_SECTION_DEFAULT);
if (new_page == NULL) {
printf("vmm: out of memory to allocate page to satisfy anonymous page-in (sending SIGBUS)\n");
printf("mm: out of memory to allocate page to satisfy anonymous page-in (sending SIGBUS)\n");
signal_signalthread(current_thread(), SIGBUS, true);
goto cleanup;
}
memset(MAKE_HHDM(new_page), 0, PAGE_SIZE);
if (!arch_mmu_map(current_vmm_context()->pagetable, new_page, addr, range->mmuflags)) {
printf("vmm: out of memory to map page (sending SIGBUS)\n");
if (!arch_mmu_map(current_mm_context()->pagetable, new_page, addr, range->mmuflags)) {
printf("mm: out of memory to map page (sending SIGBUS)\n");
signal_signalthread(current_thread(), SIGBUS, true);
mm_release_page(new_page);
}
} else {
// read-only range: map a shared zero page
if (!arch_mmu_map(current_vmm_context()->pagetable, zeropage, addr, range->mmuflags)) {
printf("vmm: out of memory to map zero page into address space (sending SIGBUS)\n");
if (!arch_mmu_map(current_mm_context()->pagetable, zeropage, addr, range->mmuflags)) {
printf("mm: out of memory to map zero page into address space (sending SIGBUS)\n");
signal_signalthread(current_thread(), SIGBUS, true);
} else {
mm_hold_page(zeropage);
}
}
}
} else if (arch_mmu_iswritable(current_vmm_context()->pagetable, addr) == false) {
} else if (arch_mmu_iswritable(current_mm_context()->pagetable, addr) == false) {
// page present but not writeable in the page tables
void *oldphys = arch_mmu_getphysical(current_vmm_context()->pagetable, addr);
void *oldphys = arch_mmu_getphysical(current_mm_context()->pagetable, addr);
page_t *oldpage = mm_get_page(oldphys);
if ( ((range->flags & VMM_FLAGS_FILE) && (range->flags & VMM_FLAGS_SHARED)) ||
((range->flags & VMM_FLAGS_FILE) == 0 && oldpage->refcount == 1)) {
if ( ((range->flags & MM_RANGE_FLAGS_FILE) && (range->flags & MM_RANGE_FLAGS_SHARED)) ||
((range->flags & MM_RANGE_FLAGS_FILE) == 0 && oldpage->refcount == 1)) {
// shared file or anon with refcount == 1, remap it as writable
arch_mmu_remap(current_vmm_context()->pagetable, oldphys, addr, range->mmuflags);
if ((range->flags & VMM_FLAGS_FILE) && vfs_iscacheable(range->vnode)) {
arch_mmu_remap(current_mm_context()->pagetable, oldphys, addr, range->mmuflags);
if ((range->flags & MM_RANGE_FLAGS_FILE) && vfs_iscacheable(range->vnode)) {
// and if its a cache page, mark it as dirty
VOP_LOCK(range->vnode);
mm_cache_make_dirty(mm_get_page(oldphys));
@@ -207,14 +206,14 @@ bool vmm_pagefault(void *addr, bool user, int actions) {
// do copy on write
void *newphys = mm_alloc_page(MEMORY_SECTION_DEFAULT);
if (newphys == NULL) {
printf("vmm: out of memory to do copy on write on address space (sending SIGBUS)\n");
printf("mm: out of memory to do copy on write on address space (sending SIGBUS)\n");
signal_signalthread(current_thread(), SIGBUS, true);
status = true;
} else {
memcpy(MAKE_HHDM(newphys), MAKE_HHDM(oldphys), PAGE_SIZE);
arch_mmu_remap(current_vmm_context()->pagetable, newphys, addr, range->mmuflags);
arch_mmu_remap(current_mm_context()->pagetable, newphys, addr, range->mmuflags);
arch_mmu_invalidate_range(addr, PAGE_SIZE);
if ((range->flags & VMM_FLAGS_FILE) == 0 || vfs_iscacheable(range->vnode))
if ((range->flags & MM_RANGE_FLAGS_FILE) == 0 || vfs_iscacheable(range->vnode))
mm_release_page(oldphys);
status = true;
@@ -231,16 +230,16 @@ bool vmm_pagefault(void *addr, bool user, int actions) {
}
/*
static int lock_page(vmmspace_t *space, void *vaddr) {
vmmrange_t *range = mm_get_range(space, vaddr);
static int lock_page(mm_space_t *space, void *vaddr) {
mm_range_t *range = mm_get_range(space, vaddr);
if (!range)
return ENOENT;
void *mapped_address = arch_mmu_getphysical(current_vmm_context()->pagetable, vaddr);
bool present = arch_mmu_ispresent(current_vmm_context()->pagetable, vaddr);
bool writable = arch_mmu_iswritable(current_vmm_context()->pagetable, vaddr);
bool file_mapping = range->flags & VMM_FLAGS_FILE;
bool private = (range->flags & VMM_FLAGS_SHARED) == 0 || file_mapping == false;
void *mapped_address = arch_mmu_getphysical(current_mm_context()->pagetable, vaddr);
bool present = arch_mmu_ispresent(current_mm_context()->pagetable, vaddr);
bool writable = arch_mmu_iswritable(current_mm_context()->pagetable, vaddr);
bool file_mapping = range->flags & MM_RANGE_FLAGS_FILE;
bool private = (range->flags & MM_RANGE_FLAGS_SHARED) == 0 || file_mapping == false;
void *real_phys;
// TODO anon with refcount == 1 can go into another cas
@@ -254,7 +253,7 @@ static int lock_page(vmmspace_t *space, void *vaddr) {
memcpy(MAKE_HHDM(real_phys), MAKE_HHDM(mapped_address), PAGE_SIZE);
arch_mmu_remap(current_vmm_context()->pagetable, real_phys, vaddr, range->mmuflags);
arch_mmu_remap(current_mm_context()->pagetable, real_phys, vaddr, range->mmuflags);
arch_mmu_invalidate_range(vaddr, PAGE_SIZE);
if (file_mapping == false || vfs_iscacheable(range->vnode))
mm_release_page(mapped_address);
@@ -266,10 +265,10 @@ static int lock_page(vmmspace_t *space, void *vaddr) {
}
*/
void *vmm_getphysical(void *addr, int flags) {
void *mm_get_physical_address(void *addr, int flags) {
void *aligned_addr = (void *)ROUND_DOWN((uintptr_t)addr, PAGE_SIZE);
vmmspace_t *space = getspace(aligned_addr);
mm_space_t *space = getspace(aligned_addr);
if (space == NULL)
return NULL;
@@ -277,29 +276,28 @@ void *vmm_getphysical(void *addr, int flags) {
void *physical;
/*
if ((flags & VMM_GET_PHYSICAL_FLAGS_LOCK) && lock_page(space, aligned_addrr)) {
if ((flags & MM_GET_PHYSICAL_ADDRESS_FLAGS_LOCK) && lock_page(space, aligned_addrr)) {
physical = NULL;
goto leave;
}*/
physical = arch_mmu_getphysical(current_vmm_context()->pagetable, aligned_addr);
physical = arch_mmu_getphysical(current_mm_context()->pagetable, aligned_addr);
if (flags & VMM_GET_PHYSICAL_FLAGS_HOLD)
if (flags & MM_GET_PHYSICAL_ADDRESS_FLAGS_HOLD)
mm_hold_page(physical);
leave:
MUTEX_RELEASE(&space->lock);
return physical + ((uintptr_t)addr - (uintptr_t)aligned_addr);
}
void *vmm_map(void *addr, volatile size_t size, int flags, mmuflags_t mmuflags, void *private) {
void *mm_map(void *addr, volatile size_t size, int flags, mmuflags_t mmuflags, void *private) {
if (addr == NULL)
addr = KERNELSPACE_START;
// XXX maps where addr is not page aligned can break
addr = (void *)ROUND_DOWN((uintptr_t)addr, PAGE_SIZE);
if (flags & VMM_FLAGS_PAGESIZE)
if (flags & MM_RANGE_FLAGS_PAGESIZE)
size *= PAGE_SIZE;
else
size = ROUND_UP(size, PAGE_SIZE);
@@ -307,7 +305,7 @@ void *vmm_map(void *addr, volatile size_t size, int flags, mmuflags_t mmuflags,
if (size == 0)
return NULL;
vmmspace_t *space = getspace(addr);
mm_space_t *space = getspace(addr);
if (space == NULL)
return NULL;
@@ -315,25 +313,25 @@ void *vmm_map(void *addr, volatile size_t size, int flags, mmuflags_t mmuflags,
mmuflags |= ARCH_MMU_FLAGS_GLOBAL;
MUTEX_ACQUIRE(&space->lock);
vmmrange_t *range = NULL;
mm_range_t *range = NULL;
void *start = mm_get_free_range(space, addr, size);
void *retaddr = NULL;
if (((flags & VMM_FLAGS_EXACT) && start != addr) || start == NULL)
if (((flags & MM_RANGE_FLAGS_EXACT) && start != addr) || start == NULL)
goto cleanup;
range = mm_alloc_range();
if (range == NULL)
goto cleanup;
if (flags & VMM_FLAGS_REPLACE) {
if (flags & MM_RANGE_FLAGS_REPLACE) {
__assert(addr);
retaddr = addr;
range->start = addr;
range->size = size;
range->flags = VMM_PERMANENT_FLAGS_MASK & flags;
range->flags = MM_PERMANENT_RANGE_FLAGS_MASK & flags;
range->mmuflags = mmuflags;
__assert((flags & (VMM_FLAGS_ALLOCATE | VMM_FLAGS_PHYSICAL)) == 0);
__assert((flags & (MM_RANGE_FLAGS_ALLOCATE | MM_RANGE_FLAGS_PHYSICAL)) == 0);
// make the memory inacessible
mm_change_range(space, addr, size, false, flags, 0);
arch_mmu_invalidate_range(addr, size);
@@ -343,25 +341,25 @@ void *vmm_map(void *addr, volatile size_t size, int flags, mmuflags_t mmuflags,
retaddr = start;
range->start = start;
range->size = size;
range->flags = VMM_PERMANENT_FLAGS_MASK & flags;
range->flags = MM_PERMANENT_RANGE_FLAGS_MASK & flags;
range->mmuflags = mmuflags;
}
if (flags & VMM_FLAGS_FILE) {
if (flags & MM_RANGE_FLAGS_FILE) {
// XXX make sure that writes can't happen to executable memory mapped files and check file permissions
vmmfiledesc_t *desc = private;
mm_map_file_desc_t *desc = private;
__assert((desc->offset % PAGE_SIZE) == 0);
range->vnode = desc->node;
range->offset = desc->offset;
VOP_HOLD(desc->node);
}
if (flags & VMM_FLAGS_PHYSICAL) {
if (flags & MM_RANGE_FLAGS_PHYSICAL) {
// map to allocated virtual memory
for (uintmax_t i = 0; i < size; i += PAGE_SIZE) {
if (arch_mmu_map(current_vmm_context()->pagetable, (void *)((uintptr_t)private + i), (void *)((uintptr_t)start + i), mmuflags) == false) {
if (arch_mmu_map(current_mm_context()->pagetable, (void *)((uintptr_t)private + i), (void *)((uintptr_t)start + i), mmuflags) == false) {
for (uintmax_t j = 0; j < size; j += PAGE_SIZE)
arch_mmu_unmap(current_vmm_context()->pagetable, (void *)((uintptr_t)start + j));
arch_mmu_unmap(current_mm_context()->pagetable, (void *)((uintptr_t)start + j));
// invalidate here just to be sure
arch_mmu_invalidate_range(start, size);
@@ -369,7 +367,7 @@ void *vmm_map(void *addr, volatile size_t size, int flags, mmuflags_t mmuflags,
goto cleanup;
}
}
} else if (flags & VMM_FLAGS_ALLOCATE) {
} else if (flags & MM_RANGE_FLAGS_ALLOCATE) {
// allocate to virtual memory
for (uintmax_t i = 0; i < size; i += PAGE_SIZE) {
void *allocated = mm_alloc_page(MEMORY_SECTION_DEFAULT);
@@ -378,14 +376,14 @@ void *vmm_map(void *addr, volatile size_t size, int flags, mmuflags_t mmuflags,
goto cleanup;
}
if (arch_mmu_map(current_vmm_context()->pagetable, allocated, (void *)((uintptr_t)start + i), mmuflags) == false) {
if (arch_mmu_map(current_mm_context()->pagetable, allocated, (void *)((uintptr_t)start + i), mmuflags) == false) {
for (uintmax_t j = 0; j < size; j += PAGE_SIZE) {
void *virt = (void *)((uintptr_t)start + i);
void *physical = arch_mmu_getphysical(current_vmm_context()->pagetable, virt);
void *physical = arch_mmu_getphysical(current_mm_context()->pagetable, virt);
if (physical) {
mm_release_page(physical);
arch_mmu_unmap(current_vmm_context()->pagetable, virt);
arch_mmu_unmap(current_mm_context()->pagetable, virt);
}
}
@@ -407,10 +405,10 @@ void *vmm_map(void *addr, volatile size_t size, int flags, mmuflags_t mmuflags,
return retaddr;
}
void vmm_unmap(void *addr, size_t size, int flags) {
void mm_unmap(void *addr, size_t size, int flags) {
addr = (void *)ROUND_DOWN((uintptr_t)addr, PAGE_SIZE);
if (flags & VMM_FLAGS_PAGESIZE)
if (flags & MM_RANGE_FLAGS_PAGESIZE)
size *= PAGE_SIZE;
else
size = ROUND_UP(size, PAGE_SIZE);
@@ -418,7 +416,7 @@ void vmm_unmap(void *addr, size_t size, int flags) {
if (size == 0)
return;
vmmspace_t *space = getspace(addr);
mm_space_t *space = getspace(addr);
if (space == NULL)
return;
@@ -437,7 +435,7 @@ void vmm_unmap(void *addr, size_t size, int flags) {
static scache_t *ctxcache;
static bool ctxctor(scache_t *cache, void *obj) {
vmmcontext_t *ctx = obj;
mm_context_t *ctx = obj;
ctx->space.start = USERSPACE_START;
ctx->space.end = USERSPACE_END;
MUTEX_INIT(&ctx->space.lock);
@@ -445,13 +443,13 @@ static bool ctxctor(scache_t *cache, void *obj) {
return true;
}
vmmcontext_t *vmm_newcontext() {
mm_context_t *mm_create_context() {
if (ctxcache == NULL) {
ctxcache = slab_newcache(sizeof(vmmcontext_t), 0, ctxctor, NULL);
ctxcache = slab_newcache(sizeof(mm_context_t), 0, ctxctor, NULL);
__assert(ctxcache);
}
vmmcontext_t *ctx = slab_allocate(ctxcache);
mm_context_t *ctx = slab_allocate(ctxcache);
if (ctx == NULL)
return NULL;
@@ -464,19 +462,19 @@ vmmcontext_t *vmm_newcontext() {
return ctx;
}
void vmm_destroycontext(vmmcontext_t *context) {
vmmcontext_t *oldctx = current_thread()->vmmctx;
vmm_switchcontext(context);
vmm_unmap(context->space.start, context->space.end - context->space.start, 0);
vmm_switchcontext(oldctx);
void mm_destroy_context(mm_context_t *context) {
mm_context_t *oldctx = current_thread()->mmctx;
mm_switch_context(context);
mm_unmap(context->space.start, context->space.end - context->space.start, 0);
mm_switch_context(oldctx);
arch_mmu_destroytable(context->pagetable);
context->space.ranges = NULL;
slab_free(ctxcache, context);
}
vmmcontext_t *vmm_fork(vmmcontext_t *oldcontext) {
vmmcontext_t *newcontext = vmm_newcontext();
mm_context_t *mm_fork_context(mm_context_t *oldcontext) {
mm_context_t *newcontext = mm_create_context();
if (newcontext == NULL)
return NULL;
@@ -484,15 +482,15 @@ vmmcontext_t *vmm_fork(vmmcontext_t *oldcontext) {
rbtree_t *rbtree = oldcontext->space.ranges ? rbtree_first(oldcontext->space.ranges) : NULL;
while (rbtree) {
vmmrange_t *range = container_of(rbtree, vmmrange_t, rbtree_node);
vmmrange_t *newrange = mm_alloc_range();
mm_range_t *range = container_of(rbtree, mm_range_t, rbtree_node);
mm_range_t *newrange = mm_alloc_range();
if (newrange == NULL)
goto error;
memcpy(newrange, range, sizeof(vmmrange_t));
memcpy(newrange, range, sizeof(mm_range_t));
rbtree_insert(&newcontext->space.ranges, &newrange->rbtree_node, vmm_range_compare);
if (range->flags & VMM_FLAGS_FILE)
rbtree_insert(&newcontext->space.ranges, &newrange->rbtree_node, mm_range_compare);
if (range->flags & MM_RANGE_FLAGS_FILE)
VOP_HOLD(range->vnode);
// copy any pages that are mapped
@@ -522,14 +520,14 @@ vmmcontext_t *vmm_fork(vmmcontext_t *oldcontext) {
return newcontext;
error:
MUTEX_RELEASE(&oldcontext->space.lock);
vmm_destroycontext(newcontext);
mm_destroy_context(newcontext);
return NULL;
}
void vmm_switchcontext(vmmcontext_t *ctx) {
void mm_switch_context(mm_context_t *ctx) {
if (current_thread())
current_thread()->vmmctx = ctx;
set_current_vmm_context(ctx);
current_thread()->mmctx = ctx;
set_current_mm_context(ctx);
arch_mmu_switch(ctx->pagetable);
}
@@ -542,18 +540,18 @@ extern void *_rodata_end;
extern volatile struct limine_memmap_request mm_page_limine_map;
void vmm_init() {
void mm_init() {
// set up initial state
mm_range_init();
MUTEX_INIT(&kernelspace.lock);
vmm_kernelctx.pagetable = arch_mmu_newtable();
__assert(vmm_kernelctx.pagetable);
mm_kernel_ctx.pagetable = arch_mmu_newtable();
__assert(mm_kernel_ctx.pagetable);
vmm_kernelctx.space.start = USERSPACE_START;
vmm_kernelctx.space.end = USERSPACE_END;
mm_kernel_ctx.space.start = USERSPACE_START;
mm_kernel_ctx.space.end = USERSPACE_END;
vmm_switchcontext(&vmm_kernelctx);
mm_switch_context(&mm_kernel_ctx);
// map HHDM
for (uint64_t i = 0; i < mm_page_limine_map.response->entry_count; ++i) {
@@ -566,16 +564,16 @@ void vmm_init() {
if (e->type == LIMINE_MEMMAP_FRAMEBUFFER)
mmuflags |= ARCH_MMU_FLAGS_WC;
__assert(vmm_map(MAKE_HHDM(e->base), e->length, VMM_FLAGS_EXACT, mmuflags, NULL));
__assert(mm_map(MAKE_HHDM(e->base), e->length, MM_RANGE_FLAGS_EXACT, mmuflags, NULL));
}
// map kernel
__assert(vmm_map(&_text_start, (uintptr_t)&_text_end - (uintptr_t)&_text_start, VMM_FLAGS_EXACT, ARCH_MMU_FLAGS_READ | ARCH_MMU_FLAGS_GLOBAL, NULL));
__assert(vmm_map(&_rodata_start, (uintptr_t)&_rodata_end - (uintptr_t)&_rodata_start, VMM_FLAGS_EXACT, ARCH_MMU_FLAGS_READ | ARCH_MMU_FLAGS_NOEXEC | ARCH_MMU_FLAGS_GLOBAL, NULL));
__assert(vmm_map(&_data_start, (uintptr_t)&_data_end - (uintptr_t)&_data_start, VMM_FLAGS_EXACT, ARCH_MMU_FLAGS_READ | ARCH_MMU_FLAGS_WRITE | ARCH_MMU_FLAGS_NOEXEC | ARCH_MMU_FLAGS_GLOBAL, NULL));
__assert(mm_map(&_text_start, (uintptr_t)&_text_end - (uintptr_t)&_text_start, MM_RANGE_FLAGS_EXACT, ARCH_MMU_FLAGS_READ | ARCH_MMU_FLAGS_GLOBAL, NULL));
__assert(mm_map(&_rodata_start, (uintptr_t)&_rodata_end - (uintptr_t)&_rodata_start, MM_RANGE_FLAGS_EXACT, ARCH_MMU_FLAGS_READ | ARCH_MMU_FLAGS_NOEXEC | ARCH_MMU_FLAGS_GLOBAL, NULL));
__assert(mm_map(&_data_start, (uintptr_t)&_data_end - (uintptr_t)&_data_start, MM_RANGE_FLAGS_EXACT, ARCH_MMU_FLAGS_READ | ARCH_MMU_FLAGS_WRITE | ARCH_MMU_FLAGS_NOEXEC | ARCH_MMU_FLAGS_GLOBAL, NULL));
// null page
vmm_map(MAKE_HHDM(NULL), PAGE_SIZE, VMM_FLAGS_EXACT, ARCH_MMU_FLAGS_NOEXEC, NULL);
mm_map(MAKE_HHDM(NULL), PAGE_SIZE, MM_RANGE_FLAGS_EXACT, ARCH_MMU_FLAGS_NOEXEC, NULL);
// zero page
zeropage = mm_alloc_page(MEMORY_SECTION_DEFAULT);
@@ -584,8 +582,8 @@ void vmm_init() {
printspace(&kernelspace);
}
INIT_ROUTINE_DEFINE(vmm, INIT_ROUTINE_FLAGS_NONE, vmm_init, mmu, slab_early);
INIT_ROUTINE_DEFINE(mm, INIT_ROUTINE_FLAGS_NONE, mm_init, mmu, slab_early);
void vmm_apinit() {
vmm_switchcontext(&vmm_kernelctx);
void mm_apinit() {
mm_switch_context(&mm_kernel_ctx);
}
+57 -58
View File
@@ -1,30 +1,29 @@
#include <kernel/vmm.h>
#include <kernel/mm.h>
#include <logging.h>
#include <kernel/page.h>
#include <util.h>
#include <arch/cpu.h>
#include <kernel/slab.h>
#include <kernel/mm.h>
#define RANGE_TOP(x) (void *)((uintptr_t)x->start + x->size)
static scache_t *range_cache;
void mm_range_init(void) {
range_cache = slab_create_new_cache_from_pmm(sizeof(vmmrange_t), 0, NULL, NULL);
range_cache = slab_create_new_cache_from_pmm(sizeof(mm_range_t), 0, NULL, NULL);
__assert(range_cache);
}
vmmrange_t *mm_alloc_range(void) {
mm_range_t *mm_alloc_range(void) {
return slab_allocate(range_cache);
}
void mm_free_range(vmmrange_t *range) {
void mm_free_range(mm_range_t *range) {
slab_free(range_cache, range);
}
static int rbtree_value_compare(void *addr, rbtree_t *node) {
vmmrange_t *range = container_of(node, vmmrange_t, rbtree_node);
mm_range_t *range = container_of(node, mm_range_t, rbtree_node);
void *range_top = RANGE_TOP(range);
if (addr >= range_top)
@@ -37,13 +36,13 @@ static int rbtree_value_compare(void *addr, rbtree_t *node) {
}
// get a range from an address
vmmrange_t *mm_get_range(vmmspace_t *space, void *addr) {
mm_range_t *mm_get_range(mm_space_t *space, void *addr) {
rbtree_t *rbtree = rbtree_lookup(space->ranges, addr, rbtree_value_compare);
return container_of(rbtree, vmmrange_t, rbtree_node);
return container_of(rbtree, mm_range_t, rbtree_node);
}
// get start of range that fits specific size from specific offset
void *mm_get_free_range(vmmspace_t *space, void *addr, size_t size) {
void *mm_get_free_range(mm_space_t *space, void *addr, size_t size) {
rbtree_t *rbtree = space->ranges;
if (addr == NULL)
addr = space->start;
@@ -53,7 +52,7 @@ void *mm_get_free_range(vmmspace_t *space, void *addr, size_t size) {
return addr;
rbtree = rbtree_first(rbtree);
vmmrange_t *range = container_of(rbtree, vmmrange_t, rbtree_node);
mm_range_t *range = container_of(rbtree, mm_range_t, rbtree_node);
// if theres free space before the first range
if (range->start != space->start && addr < range->start && (uintptr_t)range->start - (uintptr_t)addr >= size)
@@ -62,7 +61,7 @@ void *mm_get_free_range(vmmspace_t *space, void *addr, size_t size) {
// check for space between two ranges
rbtree_t *next = rbtree_successor(rbtree);
while (next) {
vmmrange_t *next_range = container_of(next, vmmrange_t, rbtree_node);
mm_range_t *next_range = container_of(next, mm_range_t, rbtree_node);
void *range_top = RANGE_TOP(range);
if (addr < range_top)
@@ -75,7 +74,7 @@ void *mm_get_free_range(vmmspace_t *space, void *addr, size_t size) {
}
rbtree = next;
range = container_of(rbtree, vmmrange_t, rbtree_node);
range = container_of(rbtree, mm_range_t, rbtree_node);
next = rbtree_successor(next);
}
@@ -92,8 +91,8 @@ void *mm_get_free_range(vmmspace_t *space, void *addr, size_t size) {
}
static int rbtree_compare(rbtree_t *a, rbtree_t *b) {
vmmrange_t *range_a = container_of(a, vmmrange_t, rbtree_node);
vmmrange_t *range_b = container_of(b, vmmrange_t, rbtree_node);
mm_range_t *range_a = container_of(a, mm_range_t, rbtree_node);
mm_range_t *range_b = container_of(b, mm_range_t, rbtree_node);
if (range_a->start == range_b->start)
return 0;
@@ -101,21 +100,21 @@ static int rbtree_compare(rbtree_t *a, rbtree_t *b) {
return range_a->start > range_b->start ? 1 : -1;
}
static bool ranges_compatible(vmmrange_t *prev, vmmrange_t *next) {
static bool ranges_compatible(mm_range_t *prev, mm_range_t *next) {
void *prev_range_top = RANGE_TOP(prev);
return prev_range_top == next->start && prev->flags == next->flags && prev->mmuflags == next->mmuflags && // general compatibility
((prev->flags & VMM_FLAGS_FILE) == 0 || (prev->vnode == next->vnode && prev->offset + prev->size == next->offset)); // same file mapping, if any
((prev->flags & MM_RANGE_FLAGS_FILE) == 0 || (prev->vnode == next->vnode && prev->offset + prev->size == next->offset)); // same file mapping, if any
}
void mm_insert_range(vmmspace_t *space, vmmrange_t *new_range) {
void mm_insert_range(mm_space_t *space, mm_range_t *new_range) {
rbtree_insert(&space->ranges, &new_range->rbtree_node, rbtree_compare);
rbtree_t *successor = rbtree_successor(&new_range->rbtree_node);
rbtree_t *predecessor = rbtree_predecessor(&new_range->rbtree_node);
vmmrange_t *next_range = successor ? container_of(successor, vmmrange_t, rbtree_node) : NULL;
vmmrange_t *prev_range = predecessor ? container_of(predecessor, vmmrange_t, rbtree_node) : NULL;
mm_range_t *next_range = successor ? container_of(successor, mm_range_t, rbtree_node) : NULL;
mm_range_t *prev_range = predecessor ? container_of(predecessor, mm_range_t, rbtree_node) : NULL;
// fragmentation checking
@@ -125,7 +124,7 @@ void mm_insert_range(vmmspace_t *space, vmmrange_t *new_range) {
rbtree_remove(&space->ranges, &next_range->rbtree_node);
mm_free_range(next_range);
if (new_range->flags & VMM_FLAGS_FILE) {
if (new_range->flags & MM_RANGE_FLAGS_FILE) {
VOP_RELEASE(new_range->vnode);
}
}
@@ -136,19 +135,19 @@ void mm_insert_range(vmmspace_t *space, vmmrange_t *new_range) {
rbtree_remove(&space->ranges, &new_range->rbtree_node);
mm_free_range(new_range);
if (prev_range->flags & VMM_FLAGS_FILE) {
if (prev_range->flags & MM_RANGE_FLAGS_FILE) {
VOP_RELEASE(prev_range->vnode);
}
}
}
void mm_destroy_range(vmmrange_t *range, uintmax_t _offset, size_t size, int flags) {
void mm_destroy_range(mm_range_t *range, uintmax_t _offset, size_t size, int flags) {
// TODO find first
uintmax_t top = _offset + size;
for (uintmax_t offset = _offset; offset < top; offset += PAGE_SIZE) {
void *vaddr = (void *)((uintptr_t)range->start + offset);
void *physical = arch_mmu_getphysical(current_vmm_context()->pagetable, vaddr);
void *physical = arch_mmu_getphysical(current_mm_context()->pagetable, vaddr);
if (physical == NULL)
continue;
@@ -156,34 +155,34 @@ void mm_destroy_range(vmmrange_t *range, uintmax_t _offset, size_t size, int fla
proc_t *proc = thread ? thread->proc : NULL;
cred_t *cred = proc ? &proc->cred : NULL;
if ((range->flags & VMM_FLAGS_FILE) && ((range->flags & VMM_FLAGS_SHARED) || vfs_iscacheable(range->vnode) == false)) {
if ((range->flags & MM_RANGE_FLAGS_FILE) && ((range->flags & MM_RANGE_FLAGS_SHARED) || vfs_iscacheable(range->vnode) == false)) {
// shared file mapping or non cacheable mapping
if (vfs_iscacheable(range->vnode) == false) {
// non cacheable mapping
VOP_LOCK(range->vnode);
__assert(VOP_MUNMAP(range->vnode, vaddr, range->offset + offset, mmuflagstovnodeflags(range->mmuflags) | (range->flags & VMM_FLAGS_SHARED ? V_FFLAGS_SHARED : 0), cred) == 0);
__assert(VOP_MUNMAP(range->vnode, vaddr, range->offset + offset, mm_mmu_flags_to_vnode_flags(range->mmuflags) | (range->flags & MM_RANGE_FLAGS_SHARED ? V_FFLAGS_SHARED : 0), cred) == 0);
VOP_UNLOCK(range->vnode);
} else if (arch_mmu_iswritable(current_vmm_context()->pagetable, vaddr)) {
} else if (arch_mmu_iswritable(current_mm_context()->pagetable, vaddr)) {
// dirty page cache mapping
arch_mmu_unmap(current_vmm_context()->pagetable, vaddr);
arch_mmu_unmap(current_mm_context()->pagetable, vaddr);
VOP_LOCK(range->vnode);
mm_cache_make_dirty(mm_get_page(physical));
VOP_UNLOCK(range->vnode);
mm_release_page(physical);
} else {
// non dirty page mapping
arch_mmu_unmap(current_vmm_context()->pagetable, vaddr);
arch_mmu_unmap(current_mm_context()->pagetable, vaddr);
mm_release_page(physical);
}
} else {
// anonymous, physical or private non character device mapping
arch_mmu_unmap(current_vmm_context()->pagetable, vaddr);
if ((range->flags & VMM_FLAGS_PHYSICAL) == 0)
arch_mmu_unmap(current_mm_context()->pagetable, vaddr);
if ((range->flags & MM_RANGE_FLAGS_PHYSICAL) == 0)
mm_release_page(physical);
}
}
if ((range->flags & VMM_FLAGS_FILE) && range->size == size)
if ((range->flags & MM_RANGE_FLAGS_FILE) && range->size == size)
VOP_RELEASE(range->vnode);
}
@@ -191,16 +190,16 @@ void mm_destroy_range(vmmrange_t *range, uintmax_t _offset, size_t size, int fla
if (((n) & (f)) == 0 && ((c) & (f))) \
m |= f;
static void change_mmu_range(vmmrange_t *range, void *base, size_t size, mmuflags_t new_flags) {
static void change_mmu_range(mm_range_t *range, void *base, size_t size, mmuflags_t new_flags) {
for (uintmax_t offset = 0; offset < size; offset += PAGE_SIZE) {
void *address = (void *)((uintptr_t)base + offset);
mmuflags_t current_flags;
// if page is not mapped, do nothing
if (arch_mmu_getflags(current_vmm_context()->pagetable, address, &current_flags) == false)
if (arch_mmu_getflags(current_mm_context()->pagetable, address, &current_flags) == false)
continue;
void *physical = arch_mmu_getphysical(current_vmm_context()->pagetable, address);
void *physical = arch_mmu_getphysical(current_mm_context()->pagetable, address);
uintmax_t mask = 0;
// check which flags are currently set and will be unset
@@ -209,9 +208,9 @@ static void change_mmu_range(vmmrange_t *range, void *base, size_t size, mmuflag
CHANGE_MASK_CHECK(mask, ARCH_MMU_FLAGS_USER, current_flags, new_flags);
CHANGE_MASK_CHECK(mask, ARCH_MMU_FLAGS_NOEXEC, current_flags, new_flags);
if ((range->flags & VMM_FLAGS_FILE) && (range->flags & VMM_FLAGS_SHARED) && (mask & ARCH_MMU_FLAGS_WRITE) && vfs_iscacheable(range->vnode)) {
if ((range->flags & MM_RANGE_FLAGS_FILE) && (range->flags & MM_RANGE_FLAGS_SHARED) && (mask & ARCH_MMU_FLAGS_WRITE) && vfs_iscacheable(range->vnode)) {
// removing write permissions from a writeable dirty shared mapped page, mark it as dirty, as
// it won't be marked dirty upon a vmm_unmap after this
// it won't be marked dirty upon a mm_unmap after this
page_t *page = mm_get_page(physical);
VOP_LOCK(range->vnode);
mm_cache_make_dirty(page);
@@ -220,21 +219,21 @@ static void change_mmu_range(vmmrange_t *range, void *base, size_t size, mmuflag
// we will only change the mapping if the permissions decreased
if (mask) {
arch_mmu_remap(current_vmm_context()->pagetable, physical, address, current_flags & ~mask);
arch_mmu_remap(current_mm_context()->pagetable, physical, address, current_flags & ~mask);
}
}
}
static inline bool can_write_vnode(vmmrange_t *range) {
static inline bool can_write_vnode(mm_range_t *range) {
VOP_LOCK(range->vnode);
int error = VOP_ACCESS(range->vnode, V_ACCESS_WRITE, &current_thread()->proc->cred);
VOP_UNLOCK(range->vnode);
return error == 0;
}
int mm_change_range(vmmspace_t *space, void *address, size_t size, bool free, int flags, mmuflags_t new_mmuflags) {
int mm_change_range(mm_space_t *space, void *address, size_t size, bool free, int flags, mmuflags_t new_mmuflags) {
void *top = (void *)((uintptr_t)address + size);
vmmrange_t *new_range = NULL;
mm_range_t *new_range = NULL;
if (space->ranges == NULL)
return 0;
@@ -251,7 +250,7 @@ int mm_change_range(vmmspace_t *space, void *address, size_t size, bool free, in
// get first range after address
rbtree_t *rbtree = rbtree_find_first_larger_equal(space->ranges, address, rbtree_value_compare);
vmmrange_t *range = container_of(rbtree, vmmrange_t, rbtree_node);
mm_range_t *range = container_of(rbtree, mm_range_t, rbtree_node);
if (rbtree == NULL)
goto leave;
@@ -259,27 +258,27 @@ int mm_change_range(vmmspace_t *space, void *address, size_t size, bool free, in
// check if we actually start at the predecessor
rbtree_t *predecessor = rbtree_predecessor(rbtree);
if (predecessor) {
vmmrange_t *predecessor_range = container_of(predecessor, vmmrange_t, rbtree_node);
mm_range_t *predecessor_range = container_of(predecessor, mm_range_t, rbtree_node);
if (RANGE_TOP(predecessor_range) > address) {
rbtree = predecessor;
range = predecessor_range;
}
}
// rbtree now has the first vmm range to be unmapped/remapped
// rbtree now has the first mm range to be unmapped/remapped
// is the range we want to change in the middle of a mapping?
if (address > range->start && top < RANGE_TOP(range)) {
// split the mapping
// check for write permission if changing a shared file mapping
if (free == false && (flags & VMM_FLAGS_CREDCHECK) && (range->flags & VMM_FLAGS_SHARED) &&
(range->flags & VMM_FLAGS_FILE) && can_write_vnode(range) == false) {
if (free == false && (flags & MM_RANGE_FLAGS_CREDCHECK) && (range->flags & MM_RANGE_FLAGS_SHARED) &&
(range->flags & MM_RANGE_FLAGS_FILE) && can_write_vnode(range) == false) {
error = EACCES;
goto leave;
}
vmmrange_t *split_range = mm_alloc_range();
mm_range_t *split_range = mm_alloc_range();
if (range == NULL) {
error = ENOMEM;
goto leave;
@@ -297,7 +296,7 @@ int mm_change_range(vmmspace_t *space, void *address, size_t size, bool free, in
split_range->size = (uintptr_t)RANGE_TOP(range) - (uintptr_t)split_range->start;
range->size = (uintptr_t)address - (uintptr_t)range->start;
if (range->flags & VMM_FLAGS_FILE) {
if (range->flags & MM_RANGE_FLAGS_FILE) {
VOP_HOLD(range->vnode);
split_range->offset += range->size + size;
}
@@ -313,7 +312,7 @@ int mm_change_range(vmmspace_t *space, void *address, size_t size, bool free, in
change_mmu_range(range, new_range->start, new_range->size, new_range->mmuflags);
if (range->flags & VMM_FLAGS_FILE) {
if (range->flags & MM_RANGE_FLAGS_FILE) {
new_range->vnode = range->vnode;
new_range->offset = range->offset + range->size;
VOP_HOLD(range->vnode);
@@ -331,8 +330,8 @@ int mm_change_range(vmmspace_t *space, void *address, size_t size, bool free, in
// shrink the mapping
// permission checking
if (free == false && (flags & VMM_FLAGS_CREDCHECK) && (range->flags & VMM_FLAGS_SHARED) &&
(range->flags & VMM_FLAGS_FILE) && can_write_vnode(range) == false) {
if (free == false && (flags & MM_RANGE_FLAGS_CREDCHECK) && (range->flags & MM_RANGE_FLAGS_SHARED) &&
(range->flags & MM_RANGE_FLAGS_FILE) && can_write_vnode(range) == false) {
error = EACCES;
goto leave;
}
@@ -352,7 +351,7 @@ int mm_change_range(vmmspace_t *space, void *address, size_t size, bool free, in
change_mmu_range(range, new_range->start, new_range->size, new_range->mmuflags);
if (range->flags & VMM_FLAGS_FILE) {
if (range->flags & MM_RANGE_FLAGS_FILE) {
new_range->vnode = range->vnode;
new_range->offset = range->offset + range->size;
VOP_HOLD(range->vnode);
@@ -375,7 +374,7 @@ int mm_change_range(vmmspace_t *space, void *address, size_t size, bool free, in
if (rbtree == NULL)
goto leave;
range = container_of(rbtree, vmmrange_t, rbtree_node);
range = container_of(rbtree, mm_range_t, rbtree_node);
if (RANGE_TOP(range) > top)
break;
@@ -388,8 +387,8 @@ int mm_change_range(vmmspace_t *space, void *address, size_t size, bool free, in
mm_free_range(range);
} else {
// permission check
if ((flags & VMM_FLAGS_CREDCHECK) && (range->flags & VMM_FLAGS_SHARED) &&
(range->flags & VMM_FLAGS_FILE) && can_write_vnode(range) == false) {
if ((flags & MM_RANGE_FLAGS_CREDCHECK) && (range->flags & MM_RANGE_FLAGS_SHARED) &&
(range->flags & MM_RANGE_FLAGS_FILE) && can_write_vnode(range) == false) {
error = EACCES;
goto leave;
}
@@ -404,8 +403,8 @@ int mm_change_range(vmmspace_t *space, void *address, size_t size, bool free, in
// move the start of the range
// permission check
if (free == false && (flags & VMM_FLAGS_CREDCHECK) && (range->flags & VMM_FLAGS_SHARED) &&
(range->flags & VMM_FLAGS_FILE) && can_write_vnode(range) == false) {
if (free == false && (flags & MM_RANGE_FLAGS_CREDCHECK) && (range->flags & MM_RANGE_FLAGS_SHARED) &&
(range->flags & MM_RANGE_FLAGS_FILE) && can_write_vnode(range) == false) {
error = EACCES;
goto leave;
}
@@ -417,7 +416,7 @@ int mm_change_range(vmmspace_t *space, void *address, size_t size, bool free, in
range->start = (void *)((uintptr_t)range->start + difference);
range->size -= difference;
if (range->flags & VMM_FLAGS_FILE)
if (range->flags & MM_RANGE_FLAGS_FILE)
range->offset += difference;
if (free == false) {
@@ -429,7 +428,7 @@ int mm_change_range(vmmspace_t *space, void *address, size_t size, bool free, in
change_mmu_range(range, new_range->start, new_range->size, new_range->mmuflags);
if (range->flags & VMM_FLAGS_FILE) {
if (range->flags & MM_RANGE_FLAGS_FILE) {
new_range->vnode = range->vnode;
new_range->offset = range->offset - difference;
VOP_HOLD(range->vnode);
+11 -11
View File
@@ -1,5 +1,5 @@
#include <kernel/slab.h>
#include <kernel/vmm.h>
#include <kernel/mm.h>
#include <kernel/page.h>
#include <logging.h>
#include <util.h>
@@ -47,7 +47,7 @@ static inline bool grow_cache(scache_t *cache) {
return false;
size_t byte_size = cache->slab_object_count * cache->true_size;
slab->base = vmm_map(NULL, byte_size, VMM_FLAGS_ALLOCATE, ARCH_MMU_FLAGS_READ | ARCH_MMU_FLAGS_WRITE | ARCH_MMU_FLAGS_NOEXEC, NULL);
slab->base = mm_map(NULL, byte_size, MM_RANGE_FLAGS_ALLOCATE, ARCH_MMU_FLAGS_READ | ARCH_MMU_FLAGS_WRITE | ARCH_MMU_FLAGS_NOEXEC, NULL);
if (unlikely(slab->base == NULL)) {
slab_free(slab_cache, slab);
return false;
@@ -68,7 +68,7 @@ static inline bool grow_cache(scache_t *cache) {
for (int j = 0; j < i; ++j)
slab_free(indirect_cache, indirect[j]);
vmm_unmap(slab->base, byte_size, 0);
mm_unmap(slab->base, byte_size, 0);
slab_free(slab_cache, slab);
return false;
@@ -454,9 +454,9 @@ static bool magazine_ctor(scache_t *, void *obj) {
return true;
}
static scache_t *create_new_from_vmm(size_t size, size_t alignment, bool (*ctor)(scache_t *, void *), void (*dtor)(scache_t *, void *)) {
static scache_t *create_new_from_mm(size_t size, size_t alignment, bool (*ctor)(scache_t *, void *), void (*dtor)(scache_t *, void *)) {
size_t cache_size = sizeof(scache_t) + sizeof(cache_per_cpu_t) * arch_smp_get_cpu_count();
scache_t *cache = vmm_map(NULL, cache_size, VMM_FLAGS_ALLOCATE, ARCH_MMU_FLAGS_READ | ARCH_MMU_FLAGS_WRITE | ARCH_MMU_FLAGS_NOEXEC, NULL);
scache_t *cache = mm_map(NULL, cache_size, MM_RANGE_FLAGS_ALLOCATE, ARCH_MMU_FLAGS_READ | ARCH_MMU_FLAGS_WRITE | ARCH_MMU_FLAGS_NOEXEC, NULL);
__assert(cache);
__assert(slab_initialize(cache, size, alignment, ctor, dtor));
return cache;
@@ -472,7 +472,7 @@ scache_t *slab_create_new_cache_from_pmm(size_t size, size_t alignment, bool (*c
return cache;
}
// initializes enough to allow for the vmm to bootstrap
// initializes enough to allow for the mm to bootstrap
void slab_early_init(void) {
size_t magazine_object_size = sizeof(magazine_t) + sizeof(void *) * MAGAZINE_SIZE;
__assert(magazine_object_size < SLAB_INDIRECT_CUTOFF);
@@ -483,11 +483,11 @@ void slab_early_init(void) {
void slab_init(void) {
size_t cache_size = sizeof(scache_t) + sizeof(cache_per_cpu_t) * arch_smp_get_cpu_count();
// the cache of caches needs for the slab and indirect caches to be up
slab_cache = create_new_from_vmm(sizeof(slab_t), 0, NULL, NULL);
indirect_cache = create_new_from_vmm(sizeof(slab_indirect_t), 0, NULL, NULL);
indirect_table_cache = create_new_from_vmm(sizeof(slab_indirect_t *) * 32, 0, NULL, NULL);
self_cache = create_new_from_vmm(cache_size, 0, NULL, NULL);
slab_cache = create_new_from_mm(sizeof(slab_t), 0, NULL, NULL);
indirect_cache = create_new_from_mm(sizeof(slab_indirect_t), 0, NULL, NULL);
indirect_table_cache = create_new_from_mm(sizeof(slab_indirect_t *) * 32, 0, NULL, NULL);
self_cache = create_new_from_mm(cache_size, 0, NULL, NULL);
}
INIT_ROUTINE_DEFINE(slab, INIT_ROUTINE_FLAGS_NONE, slab_init, vmm);
INIT_ROUTINE_DEFINE(slab, INIT_ROUTINE_FLAGS_NONE, slab_init, mm);
INIT_ROUTINE_DEFINE(slab_early, INIT_ROUTINE_FLAGS_NONE, slab_early_init, mm_page);