mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-11-01 15:08:21 +00:00
mm: rename vmm api to mm
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
#include <logging.h>
|
#include <logging.h>
|
||||||
#include <kernel/vmm.h>
|
#include <kernel/mm.h>
|
||||||
#include <arch/mmu.h>
|
#include <arch/mmu.h>
|
||||||
#include <kernel/alloc.h>
|
#include <kernel/alloc.h>
|
||||||
#include <kernel/interrupt.h>
|
#include <kernel/interrupt.h>
|
||||||
@@ -274,7 +274,7 @@ void arch_apic_init() {
|
|||||||
|
|
||||||
void *paddr = (void *) rdmsr(MSR_IA32APICBASE);
|
void *paddr = (void *) rdmsr(MSR_IA32APICBASE);
|
||||||
|
|
||||||
lapic_address = vmm_map(NULL, PAGE_SIZE, VMM_FLAGS_PHYSICAL, ARCH_MMU_FLAGS_READ | ARCH_MMU_FLAGS_WRITE | ARCH_MMU_FLAGS_NOEXEC, paddr);
|
lapic_address = mm_map(NULL, PAGE_SIZE, MM_RANGE_FLAGS_PHYSICAL, ARCH_MMU_FLAGS_READ | ARCH_MMU_FLAGS_WRITE | ARCH_MMU_FLAGS_NOEXEC, paddr);
|
||||||
__assert(lapic_address);
|
__assert(lapic_address);
|
||||||
|
|
||||||
// map I/O apics to memory
|
// map I/O apics to memory
|
||||||
@@ -286,7 +286,7 @@ void arch_apic_init() {
|
|||||||
struct acpi_madt_ioapic *entry = getentry(ACPI_MADT_ENTRY_TYPE_IOAPIC, i);
|
struct acpi_madt_ioapic *entry = getentry(ACPI_MADT_ENTRY_TYPE_IOAPIC, i);
|
||||||
|
|
||||||
__assert((entry->address % PAGE_SIZE) == 0);
|
__assert((entry->address % PAGE_SIZE) == 0);
|
||||||
ioapics[i].addr = vmm_map(NULL, PAGE_SIZE, VMM_FLAGS_PHYSICAL, ARCH_MMU_FLAGS_READ | ARCH_MMU_FLAGS_WRITE | ARCH_MMU_FLAGS_NOEXEC, (void *)(uint64_t)entry->address);
|
ioapics[i].addr = mm_map(NULL, PAGE_SIZE, MM_RANGE_FLAGS_PHYSICAL, ARCH_MMU_FLAGS_READ | ARCH_MMU_FLAGS_WRITE | ARCH_MMU_FLAGS_NOEXEC, (void *)(uint64_t)entry->address);
|
||||||
__assert(ioapics[i].addr);
|
__assert(ioapics[i].addr);
|
||||||
ioapics[i].base = entry->gsi_base;
|
ioapics[i].base = entry->gsi_base;
|
||||||
ioapics[i].top = ioapics[i].base + ((readioapic(ioapics[i].addr, IOAPIC_REG_ENTRY_COUNT) >> 16) & 0xff) + 1;
|
ioapics[i].top = ioapics[i].base + ((readioapic(ioapics[i].addr, IOAPIC_REG_ENTRY_COUNT) >> 16) & 0xff) + 1;
|
||||||
|
|||||||
@@ -349,7 +349,7 @@ void arch_cpu_init() {
|
|||||||
current_cpu()->topology_node = topology_nodes[topology_depth - 1];
|
current_cpu()->topology_node = topology_nodes[topology_depth - 1];
|
||||||
|
|
||||||
// allocate ists
|
// allocate ists
|
||||||
uint64_t *ist1 = vmm_map(NULL, PAGE_SIZE * 4, VMM_FLAGS_ALLOCATE, ARCH_MMU_FLAGS_READ | ARCH_MMU_FLAGS_WRITE | ARCH_MMU_FLAGS_NOEXEC, NULL);
|
uint64_t *ist1 = mm_map(NULL, PAGE_SIZE * 4, MM_RANGE_FLAGS_ALLOCATE, ARCH_MMU_FLAGS_READ | ARCH_MMU_FLAGS_WRITE | ARCH_MMU_FLAGS_NOEXEC, NULL);
|
||||||
__assert(ist1);
|
__assert(ist1);
|
||||||
|
|
||||||
// the cpu automatically aligns to 16 bytes when pushing the interrupt frame, so save ourselves the trouble:
|
// the cpu automatically aligns to 16 bytes when pushing the interrupt frame, so save ourselves the trouble:
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <logging.h>
|
#include <logging.h>
|
||||||
#include <arch/hpet.h>
|
#include <arch/hpet.h>
|
||||||
#include <kernel/vmm.h>
|
#include <kernel/mm.h>
|
||||||
#include <kernel/interrupt.h>
|
#include <kernel/interrupt.h>
|
||||||
#include <arch/tsc.h>
|
#include <arch/tsc.h>
|
||||||
#include <kernel/kernel_args.h>
|
#include <kernel/kernel_args.h>
|
||||||
@@ -103,7 +103,7 @@ static timekeeper_source_info_t *hpet_init(void) {
|
|||||||
__assert(table->address.address_space_id == ACPI_AS_ID_SYS_MEM);
|
__assert(table->address.address_space_id == ACPI_AS_ID_SYS_MEM);
|
||||||
|
|
||||||
uint64_t page_offset = table->address.address % PAGE_SIZE;
|
uint64_t page_offset = table->address.address % PAGE_SIZE;
|
||||||
hpet_private.hpet = vmm_map(NULL, (PAGE_SIZE + page_offset), VMM_FLAGS_PHYSICAL, ARCH_MMU_FLAGS_READ | ARCH_MMU_FLAGS_WRITE | ARCH_MMU_FLAGS_NOEXEC, (void *)(table->address.address - page_offset));
|
hpet_private.hpet = mm_map(NULL, (PAGE_SIZE + page_offset), MM_RANGE_FLAGS_PHYSICAL, ARCH_MMU_FLAGS_READ | ARCH_MMU_FLAGS_WRITE | ARCH_MMU_FLAGS_NOEXEC, (void *)(table->address.address - page_offset));
|
||||||
__assert(hpet_private.hpet);
|
__assert(hpet_private.hpet);
|
||||||
hpet_private.hpet = (void *)((uintptr_t)hpet_private.hpet + page_offset);
|
hpet_private.hpet = (void *)((uintptr_t)hpet_private.hpet + page_offset);
|
||||||
|
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ static timekeeper_source_info_t *kvm_timer_init(void) {
|
|||||||
|
|
||||||
int page_offset = (uintptr_t)virtual_address % PAGE_SIZE;
|
int page_offset = (uintptr_t)virtual_address % PAGE_SIZE;
|
||||||
void *virtual_page = (void *)((uintptr_t)virtual_address - page_offset);
|
void *virtual_page = (void *)((uintptr_t)virtual_address - page_offset);
|
||||||
void *physical_page = vmm_getphysical(virtual_page, 0);
|
void *physical_page = mm_get_physical_address(virtual_page, 0);
|
||||||
__assert(physical_page);
|
__assert(physical_page);
|
||||||
|
|
||||||
timekeeper_source_info->private = (void *)((uintptr_t)physical_page + page_offset);
|
timekeeper_source_info->private = (void *)((uintptr_t)physical_page + page_offset);
|
||||||
|
|||||||
@@ -75,10 +75,10 @@ int arch_ldt_set_entry(unsigned int which, ldt_entry_t entry) {
|
|||||||
done = 0;
|
done = 0;
|
||||||
|
|
||||||
for (int i = 0; i < arch_smp_cpusawake; ++i) {
|
for (int i = 0; i < arch_smp_cpusawake; ++i) {
|
||||||
// reading the vmm context like this is racey but there are no ill side effects other than spurious shootdowns
|
// reading the mm context like this is racey but there are no ill side effects other than spurious shootdowns
|
||||||
// if a cpu changes to this vmmctx, they will already have done a ldt invalidation.
|
// if a cpu changes to this mmctx, they will already have done a ldt invalidation.
|
||||||
// if it changes out of it, same thing
|
// if it changes out of it, same thing
|
||||||
if (smp_cpus[i] == current_cpu() || (smp_cpus[i]->vmmctx != current_thread()->vmmctx))
|
if (smp_cpus[i] == current_cpu() || (smp_cpus[i]->mmctx != current_thread()->mmctx))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
++shootdown_total;
|
++shootdown_total;
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <logging.h>
|
#include <logging.h>
|
||||||
#include <kernel/interrupt.h>
|
#include <kernel/interrupt.h>
|
||||||
#include <kernel/vmm.h>
|
#include <kernel/mm.h>
|
||||||
#include <arch/cpu.h>
|
#include <arch/cpu.h>
|
||||||
#include <arch/smp.h>
|
#include <arch/smp.h>
|
||||||
#include <kernel/init.h>
|
#include <kernel/init.h>
|
||||||
@@ -264,10 +264,10 @@ void arch_mmu_invalidate_range(void *page, size_t size) {
|
|||||||
old_ipl = interrupt_raiseipl(IPL_DPC);
|
old_ipl = interrupt_raiseipl(IPL_DPC);
|
||||||
|
|
||||||
for (int i = 0; i < arch_smp_cpusawake; ++i) {
|
for (int i = 0; i < arch_smp_cpusawake; ++i) {
|
||||||
// reading the vmm context like this is racey but there are no ill side effects other than spurious shootdowns
|
// reading the mm context like this is racey but there are no ill side effects other than spurious shootdowns
|
||||||
// if a cpu changes to this vmmctx, they will already have done a tlb invalidation.
|
// if a cpu changes to this mmctx, they will already have done a tlb invalidation.
|
||||||
// if it changes out of it, same thing
|
// if it changes out of it, same thing
|
||||||
if (smp_cpus[i] == current_cpu() || (user_shootdown && smp_cpus[i]->vmmctx != current_thread()->vmmctx))
|
if (smp_cpus[i] == current_cpu() || (user_shootdown && smp_cpus[i]->mmctx != current_thread()->mmctx))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
spinlock_acquire(&smp_cpus[i]->shootdown_lock);
|
spinlock_acquire(&smp_cpus[i]->shootdown_lock);
|
||||||
@@ -339,16 +339,16 @@ static void pfisr(isr_t *self, context_t *ctx) {
|
|||||||
arch_cpu_user_access_end();
|
arch_cpu_user_access_end();
|
||||||
|
|
||||||
interrupt_set(true);
|
interrupt_set(true);
|
||||||
int vmmerror = 0;
|
int mm_error = 0;
|
||||||
|
|
||||||
vmmerror |= VMM_ACTION_READ; // valid x86 PTEs will always have read permission (present) and actions will always have a read because of that.
|
mm_error |= MM_FAULT_ACTION_READ; // valid x86 PTEs will always have read permission (present) and actions will always have a read because of that.
|
||||||
if (ctx->error & ERROR_WRITE)
|
if (ctx->error & ERROR_WRITE)
|
||||||
vmmerror |= VMM_ACTION_WRITE;
|
mm_error |= MM_FAULT_ACTION_WRITE;
|
||||||
|
|
||||||
if (ctx->error & ERROR_FETCH)
|
if (ctx->error & ERROR_FETCH)
|
||||||
vmmerror |= VMM_ACTION_EXEC;
|
mm_error |= MM_FAULT_ACTION_EXEC;
|
||||||
|
|
||||||
if (vmm_pagefault((void *)ctx->cr2, ctx->cs != 8, vmmerror) == false) {
|
if (mm_handle_page_fault((void *)ctx->cr2, ctx->cs != 8, mm_error) == false) {
|
||||||
if (thread && thread->usercopyctx) {
|
if (thread && thread->usercopyctx) {
|
||||||
memcpy(ctx, thread->usercopyctx, sizeof(context_t));
|
memcpy(ctx, thread->usercopyctx, sizeof(context_t));
|
||||||
ctx->rflags &= ~ARCH_CONTEXT_RFLAGS_AC;
|
ctx->rflags &= ~ARCH_CONTEXT_RFLAGS_AC;
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ static void cpuwakeup(struct limine_mp_info *info) {
|
|||||||
dpc_init();
|
dpc_init();
|
||||||
arch_extracontext_detect();
|
arch_extracontext_detect();
|
||||||
arch_mmu_apswitch();
|
arch_mmu_apswitch();
|
||||||
vmm_apinit();
|
mm_apinit();
|
||||||
|
|
||||||
arch_apic_initap();
|
arch_apic_initap();
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
#include <kernel/alloc.h>
|
#include <kernel/alloc.h>
|
||||||
#include <kernel/timekeeper.h>
|
#include <kernel/timekeeper.h>
|
||||||
#include <kernel/slab.h>
|
#include <kernel/slab.h>
|
||||||
#include <kernel/vmm.h>
|
#include <kernel/mm.h>
|
||||||
#include <arch/cpu.h>
|
#include <arch/cpu.h>
|
||||||
#include <kernel/page.h>
|
#include <kernel/page.h>
|
||||||
#include <hashtable.h>
|
#include <hashtable.h>
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <logging.h>
|
#include <logging.h>
|
||||||
#include <util.h>
|
#include <util.h>
|
||||||
#include <kernel/vmm.h>
|
#include <kernel/mm.h>
|
||||||
#include <kernel/page.h>
|
#include <kernel/page.h>
|
||||||
#include <kernel/abi.h>
|
#include <kernel/abi.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
#include <kernel/slab.h>
|
#include <kernel/slab.h>
|
||||||
#include <kernel/alloc.h>
|
#include <kernel/alloc.h>
|
||||||
#include <kernel/timekeeper.h>
|
#include <kernel/timekeeper.h>
|
||||||
#include <kernel/vmm.h>
|
#include <kernel/mm.h>
|
||||||
#include <logging.h>
|
#include <logging.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <kernel/abi.h>
|
#include <kernel/abi.h>
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
#include <kernel/slab.h>
|
#include <kernel/slab.h>
|
||||||
#include <kernel/alloc.h>
|
#include <kernel/alloc.h>
|
||||||
#include <kernel/timekeeper.h>
|
#include <kernel/timekeeper.h>
|
||||||
#include <kernel/vmm.h>
|
#include <kernel/mm.h>
|
||||||
#include <logging.h>
|
#include <logging.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <kernel/abi.h>
|
#include <kernel/abi.h>
|
||||||
|
|||||||
@@ -4,12 +4,12 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <kernel/alloc.h>
|
#include <kernel/alloc.h>
|
||||||
#include <kernel/timekeeper.h>
|
#include <kernel/timekeeper.h>
|
||||||
#include <kernel/vmm.h>
|
#include <kernel/mm.h>
|
||||||
#include <util.h>
|
#include <util.h>
|
||||||
#include <kernel/abi.h>
|
#include <kernel/abi.h>
|
||||||
#include <kernel/devfs.h>
|
#include <kernel/devfs.h>
|
||||||
#include <kernel/page.h>
|
#include <kernel/page.h>
|
||||||
#include <kernel/vmm.h>
|
#include <kernel/mm.h>
|
||||||
#include <arch/cpu.h>
|
#include <arch/cpu.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <kernel/mm.h>
|
#include <kernel/mm.h>
|
||||||
|
|||||||
@@ -1,9 +1,98 @@
|
|||||||
#ifndef _MM_H
|
#ifndef _MM_H
|
||||||
#define _MM_H
|
#define _MM_H
|
||||||
|
|
||||||
|
#include <arch/mmu.h>
|
||||||
|
#include <mutex.h>
|
||||||
#include <kernel/page.h>
|
#include <kernel/page.h>
|
||||||
#include <kernel/vfs.h>
|
#include <kernel/vfs.h>
|
||||||
#include <kernel/vmm.h>
|
#include <rbtree.h>
|
||||||
|
|
||||||
|
#define MM_RANGE_FLAGS_PAGESIZE 1
|
||||||
|
#define MM_RANGE_FLAGS_ALLOCATE 2
|
||||||
|
#define MM_RANGE_FLAGS_PHYSICAL 4
|
||||||
|
#define MM_RANGE_FLAGS_FILE 8
|
||||||
|
#define MM_RANGE_FLAGS_EXACT 16
|
||||||
|
#define MM_RANGE_FLAGS_SHARED 32
|
||||||
|
#define MM_RANGE_FLAGS_REPLACE 64
|
||||||
|
#define MM_RANGE_FLAGS_CREDCHECK 128
|
||||||
|
|
||||||
|
#define MM_PERMANENT_RANGE_FLAGS_MASK (MM_RANGE_FLAGS_FILE | MM_RANGE_FLAGS_SHARED | MM_RANGE_FLAGS_PHYSICAL)
|
||||||
|
|
||||||
|
#define MM_FAULT_ACTION_READ 1
|
||||||
|
#define MM_FAULT_ACTION_WRITE 2
|
||||||
|
#define MM_FAULT_ACTION_EXEC 4
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
vnode_t *node;
|
||||||
|
uintmax_t offset;
|
||||||
|
} mm_map_file_desc_t;
|
||||||
|
|
||||||
|
typedef struct mm_range_t{
|
||||||
|
rbtree_t rbtree_node;
|
||||||
|
void *start;
|
||||||
|
size_t size;
|
||||||
|
int flags;
|
||||||
|
mmuflags_t mmuflags;
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
vnode_t *vnode;
|
||||||
|
size_t offset;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
} mm_range_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
mutex_t lock;
|
||||||
|
rbtree_t *ranges;
|
||||||
|
void *start;
|
||||||
|
void *end;
|
||||||
|
} mm_space_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
mm_space_t space;
|
||||||
|
pagetableptr_t pagetable;
|
||||||
|
} mm_context_t;
|
||||||
|
|
||||||
|
extern mm_context_t mm_kernel_ctx;
|
||||||
|
|
||||||
|
static inline mmuflags_t mm_vnode_flags_to_mmu_flags(int flags) {
|
||||||
|
mmuflags_t mmuflags = ARCH_MMU_FLAGS_USER;
|
||||||
|
if (flags & V_FFLAGS_READ)
|
||||||
|
mmuflags |= ARCH_MMU_FLAGS_READ;
|
||||||
|
if (flags & V_FFLAGS_WRITE)
|
||||||
|
mmuflags |= ARCH_MMU_FLAGS_WRITE;
|
||||||
|
if ((flags & V_FFLAGS_EXEC) == 0)
|
||||||
|
mmuflags |= ARCH_MMU_FLAGS_NOEXEC;
|
||||||
|
|
||||||
|
return mmuflags;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int mm_mmu_flags_to_vnode_flags(mmuflags_t mmuflags) {
|
||||||
|
int flags = 0;
|
||||||
|
if (mmuflags & ARCH_MMU_FLAGS_READ)
|
||||||
|
flags |= V_FFLAGS_READ;
|
||||||
|
if (mmuflags & ARCH_MMU_FLAGS_WRITE)
|
||||||
|
flags |= V_FFLAGS_WRITE;
|
||||||
|
if ((mmuflags & ARCH_MMU_FLAGS_NOEXEC) == 0)
|
||||||
|
flags |= V_FFLAGS_EXEC;
|
||||||
|
|
||||||
|
return flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mm_change_mmu_flags(void *base, size_t size, mmuflags_t mmuflags, int flags);
|
||||||
|
void mm_destroy_context(mm_context_t *context);
|
||||||
|
mm_context_t *mm_fork_context(mm_context_t *oldcontext);
|
||||||
|
void *mm_map(void *addr, size_t size, int flags, mmuflags_t mmuflags, void *private);
|
||||||
|
void mm_unmap(void *addr, size_t size, int flags);
|
||||||
|
bool mm_handle_page_fault(void *addr, bool user, int actions);
|
||||||
|
mm_context_t *mm_create_context();
|
||||||
|
void mm_switch_context(mm_context_t *ctx);
|
||||||
|
|
||||||
|
#define MM_GET_PHYSICAL_ADDRESS_FLAGS_HOLD 1
|
||||||
|
#define MM_GET_PHYSICAL_ADDRESS_FLAGS_LOCK 2
|
||||||
|
void *mm_get_physical_address(void *addr, int flags);
|
||||||
|
void mm_apinit();
|
||||||
|
void mm_init();
|
||||||
|
|
||||||
extern size_t mm_cache_cached_pages;
|
extern size_t mm_cache_cached_pages;
|
||||||
|
|
||||||
@@ -18,12 +107,12 @@ int mm_cache_sync(void);
|
|||||||
int mm_cache_evict(page_t *page);
|
int mm_cache_evict(page_t *page);
|
||||||
|
|
||||||
void mm_range_init(void);
|
void mm_range_init(void);
|
||||||
vmmrange_t *mm_alloc_range(void);
|
mm_range_t *mm_alloc_range(void);
|
||||||
void mm_free_range(vmmrange_t *range);
|
void mm_free_range(mm_range_t *range);
|
||||||
vmmrange_t *mm_get_range(vmmspace_t *space, void *addr);
|
mm_range_t *mm_get_range(mm_space_t *space, void *addr);
|
||||||
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);
|
||||||
void mm_insert_range(vmmspace_t *space, vmmrange_t *new_range);
|
void mm_insert_range(mm_space_t *space, mm_range_t *new_range);
|
||||||
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);
|
||||||
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);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
#define _PROC_H
|
#define _PROC_H
|
||||||
|
|
||||||
#include <arch/context.h>
|
#include <arch/context.h>
|
||||||
#include <kernel/vmm.h>
|
#include <kernel/mm.h>
|
||||||
#include <kernel/abi.h>
|
#include <kernel/abi.h>
|
||||||
#include <kernel/vfs.h>
|
#include <kernel/vfs.h>
|
||||||
#include <semaphore.h>
|
#include <semaphore.h>
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
#define _THREAD_H
|
#define _THREAD_H
|
||||||
|
|
||||||
#include <arch/context.h>
|
#include <arch/context.h>
|
||||||
#include <kernel/vmm.h>
|
#include <kernel/mm.h>
|
||||||
#include <kernel/abi.h>
|
#include <kernel/abi.h>
|
||||||
#include <kernel/signal.h>
|
#include <kernel/signal.h>
|
||||||
#include <kernel/event.h>
|
#include <kernel/event.h>
|
||||||
@@ -35,7 +35,7 @@ typedef struct thread_t {
|
|||||||
extracontext_t extracontext;
|
extracontext_t extracontext;
|
||||||
void *kernelstack;
|
void *kernelstack;
|
||||||
size_t kernelstacksize;
|
size_t kernelstacksize;
|
||||||
vmmcontext_t *vmmctx;
|
mm_context_t *mmctx;
|
||||||
tid_t tid;
|
tid_t tid;
|
||||||
int flags;
|
int flags;
|
||||||
bool sleepintstatus;
|
bool sleepintstatus;
|
||||||
|
|||||||
@@ -1,96 +0,0 @@
|
|||||||
#ifndef _VMM_H
|
|
||||||
#define _VMM_H
|
|
||||||
|
|
||||||
#include <arch/mmu.h>
|
|
||||||
#include <mutex.h>
|
|
||||||
#include <kernel/vfs.h>
|
|
||||||
#include <rbtree.h>
|
|
||||||
|
|
||||||
#define VMM_FLAGS_PAGESIZE 1
|
|
||||||
#define VMM_FLAGS_ALLOCATE 2
|
|
||||||
#define VMM_FLAGS_PHYSICAL 4
|
|
||||||
#define VMM_FLAGS_FILE 8
|
|
||||||
#define VMM_FLAGS_EXACT 16
|
|
||||||
#define VMM_FLAGS_SHARED 32
|
|
||||||
#define VMM_FLAGS_REPLACE 64
|
|
||||||
#define VMM_FLAGS_CREDCHECK 128
|
|
||||||
|
|
||||||
#define VMM_PERMANENT_FLAGS_MASK (VMM_FLAGS_FILE | VMM_FLAGS_SHARED | VMM_FLAGS_PHYSICAL)
|
|
||||||
|
|
||||||
#define VMM_ACTION_READ 1
|
|
||||||
#define VMM_ACTION_WRITE 2
|
|
||||||
#define VMM_ACTION_EXEC 4
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
vnode_t *node;
|
|
||||||
uintmax_t offset;
|
|
||||||
} vmmfiledesc_t;
|
|
||||||
|
|
||||||
typedef struct vmmrange_t{
|
|
||||||
rbtree_t rbtree_node;
|
|
||||||
void *start;
|
|
||||||
size_t size;
|
|
||||||
int flags;
|
|
||||||
mmuflags_t mmuflags;
|
|
||||||
union {
|
|
||||||
struct {
|
|
||||||
vnode_t *vnode;
|
|
||||||
size_t offset;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
} vmmrange_t;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
mutex_t lock;
|
|
||||||
rbtree_t *ranges;
|
|
||||||
void *start;
|
|
||||||
void *end;
|
|
||||||
} vmmspace_t;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
vmmspace_t space;
|
|
||||||
pagetableptr_t pagetable;
|
|
||||||
} vmmcontext_t;
|
|
||||||
|
|
||||||
extern vmmcontext_t vmm_kernelctx;
|
|
||||||
|
|
||||||
static inline mmuflags_t vnodeflagstommuflags(int flags) {
|
|
||||||
mmuflags_t mmuflags = ARCH_MMU_FLAGS_USER;
|
|
||||||
if (flags & V_FFLAGS_READ)
|
|
||||||
mmuflags |= ARCH_MMU_FLAGS_READ;
|
|
||||||
if (flags & V_FFLAGS_WRITE)
|
|
||||||
mmuflags |= ARCH_MMU_FLAGS_WRITE;
|
|
||||||
if ((flags & V_FFLAGS_EXEC) == 0)
|
|
||||||
mmuflags |= ARCH_MMU_FLAGS_NOEXEC;
|
|
||||||
|
|
||||||
return mmuflags;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int mmuflagstovnodeflags(mmuflags_t mmuflags) {
|
|
||||||
int flags = 0;
|
|
||||||
if (mmuflags & ARCH_MMU_FLAGS_READ)
|
|
||||||
flags |= V_FFLAGS_READ;
|
|
||||||
if (mmuflags & ARCH_MMU_FLAGS_WRITE)
|
|
||||||
flags |= V_FFLAGS_WRITE;
|
|
||||||
if ((mmuflags & ARCH_MMU_FLAGS_NOEXEC) == 0)
|
|
||||||
flags |= V_FFLAGS_EXEC;
|
|
||||||
|
|
||||||
return flags;
|
|
||||||
}
|
|
||||||
|
|
||||||
int vmm_changemmuflags(void *base, size_t size, mmuflags_t mmuflags, int flags);
|
|
||||||
void vmm_destroycontext(vmmcontext_t *context);
|
|
||||||
vmmcontext_t *vmm_fork(vmmcontext_t *oldcontext);
|
|
||||||
void *vmm_map(void *addr, size_t size, int flags, mmuflags_t mmuflags, void *private);
|
|
||||||
void vmm_unmap(void *addr, size_t size, int flags);
|
|
||||||
bool vmm_pagefault(void *addr, bool user, int actions);
|
|
||||||
vmmcontext_t *vmm_newcontext();
|
|
||||||
void vmm_switchcontext(vmmcontext_t *ctx);
|
|
||||||
|
|
||||||
#define VMM_GET_PHYSICAL_FLAGS_HOLD 1
|
|
||||||
#define VMM_GET_PHYSICAL_FLAGS_LOCK 2
|
|
||||||
void *vmm_getphysical(void *addr, int flags);
|
|
||||||
void vmm_apinit();
|
|
||||||
void vmm_init();
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -7,7 +7,7 @@
|
|||||||
#include <arch/msr.h>
|
#include <arch/msr.h>
|
||||||
#include <arch/ist.h>
|
#include <arch/ist.h>
|
||||||
#include <kernel/interrupt.h>
|
#include <kernel/interrupt.h>
|
||||||
#include <kernel/vmm.h>
|
#include <kernel/mm.h>
|
||||||
#include <kernel/timer.h>
|
#include <kernel/timer.h>
|
||||||
#include <kernel/scheduler.h>
|
#include <kernel/scheduler.h>
|
||||||
#include <kernel/dpc.h>
|
#include <kernel/dpc.h>
|
||||||
@@ -23,7 +23,7 @@ typedef struct cpu_t {
|
|||||||
|
|
||||||
struct cpu_t *self; // expected to be here by other code
|
struct cpu_t *self; // expected to be here by other code
|
||||||
|
|
||||||
vmmcontext_t *vmmctx; // expected to be here by other code
|
mm_context_t *mmctx; // expected to be here by other code
|
||||||
|
|
||||||
long hardware_id; // expected to be here by other code
|
long hardware_id; // expected to be here by other code
|
||||||
long internal_id; // expected to be here by other code
|
long internal_id; // expected to be here by other code
|
||||||
@@ -131,13 +131,13 @@ static inline cpu_t *current_cpu(void) {
|
|||||||
return cpu;
|
return cpu;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline vmmcontext_t *current_vmm_context(void) {
|
static inline mm_context_t *current_mm_context(void) {
|
||||||
vmmcontext_t *context;
|
mm_context_t *context;
|
||||||
asm volatile ("mov %%gs:16, %%rax" : "=a"(context) : : "memory");
|
asm volatile ("mov %%gs:16, %%rax" : "=a"(context) : : "memory");
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void set_current_vmm_context(vmmcontext_t *context) {
|
static inline void set_current_mm_context(mm_context_t *context) {
|
||||||
asm volatile ("mov %%rax, %%gs:16" : : "a"(context) : "memory");
|
asm volatile ("mov %%rax, %%gs:16" : : "a"(context) : "memory");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ static void pci_archinit() {
|
|||||||
void *phys = (void *)mcfgentries[i].address;
|
void *phys = (void *)mcfgentries[i].address;
|
||||||
uintmax_t pageoffset = (uintptr_t)phys % PAGE_SIZE;
|
uintmax_t pageoffset = (uintptr_t)phys % PAGE_SIZE;
|
||||||
size_t mappingsize = pageoffset + MCFG_MAPPING_SIZE(mcfgentries[i].end_bus - mcfgentries[i].start_bus + 1);
|
size_t mappingsize = pageoffset + MCFG_MAPPING_SIZE(mcfgentries[i].end_bus - mcfgentries[i].start_bus + 1);
|
||||||
void *virt = vmm_map(NULL, mappingsize, VMM_FLAGS_PHYSICAL,
|
void *virt = mm_map(NULL, mappingsize, MM_RANGE_FLAGS_PHYSICAL,
|
||||||
ARCH_MMU_FLAGS_READ | ARCH_MMU_FLAGS_WRITE | ARCH_MMU_FLAGS_NOEXEC | ARCH_MMU_FLAGS_UC, phys);
|
ARCH_MMU_FLAGS_READ | ARCH_MMU_FLAGS_WRITE | ARCH_MMU_FLAGS_NOEXEC | ARCH_MMU_FLAGS_UC, phys);
|
||||||
__assert(virt);
|
__assert(virt);
|
||||||
mcfgentries[i].address = (uintptr_t)virt + pageoffset;
|
mcfgentries[i].address = (uintptr_t)virt + pageoffset;
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ void uacpi_kernel_free(void *ptr) {
|
|||||||
|
|
||||||
void *uacpi_kernel_map(uacpi_phys_addr physical, uacpi_size length) {
|
void *uacpi_kernel_map(uacpi_phys_addr physical, uacpi_size length) {
|
||||||
uintmax_t pageoffset = (uintptr_t)physical % PAGE_SIZE;
|
uintmax_t pageoffset = (uintptr_t)physical % PAGE_SIZE;
|
||||||
void *virt = vmm_map(NULL, ROUND_UP(length + pageoffset, PAGE_SIZE), VMM_FLAGS_PHYSICAL,
|
void *virt = mm_map(NULL, ROUND_UP(length + pageoffset, PAGE_SIZE), MM_RANGE_FLAGS_PHYSICAL,
|
||||||
ARCH_MMU_FLAGS_READ | ARCH_MMU_FLAGS_WRITE | ARCH_MMU_FLAGS_NOEXEC,
|
ARCH_MMU_FLAGS_READ | ARCH_MMU_FLAGS_WRITE | ARCH_MMU_FLAGS_NOEXEC,
|
||||||
(void*)ROUND_DOWN(physical, PAGE_SIZE));
|
(void*)ROUND_DOWN(physical, PAGE_SIZE));
|
||||||
|
|
||||||
@@ -74,7 +74,7 @@ void uacpi_kernel_unmap(void *ptr, uacpi_size length) {
|
|||||||
uintmax_t pageoffset = (uintptr_t)ptr % PAGE_SIZE;
|
uintmax_t pageoffset = (uintptr_t)ptr % PAGE_SIZE;
|
||||||
|
|
||||||
uintptr_t addr = (uintptr_t)ptr;
|
uintptr_t addr = (uintptr_t)ptr;
|
||||||
vmm_unmap((void*)ROUND_DOWN(addr, PAGE_SIZE), ROUND_UP(length + pageoffset, PAGE_SIZE), 0);
|
mm_unmap((void*)ROUND_DOWN(addr, PAGE_SIZE), ROUND_UP(length + pageoffset, PAGE_SIZE), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
uacpi_status uacpi_kernel_raw_memory_read(uacpi_phys_addr address, uacpi_u8 width, uacpi_u64 *out) {
|
uacpi_status uacpi_kernel_raw_memory_read(uacpi_phys_addr address, uacpi_u8 width, uacpi_u64 *out) {
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
#include <kernel/alloc.h>
|
#include <kernel/alloc.h>
|
||||||
#include <kernel/devfs.h>
|
#include <kernel/devfs.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <kernel/vmm.h>
|
#include <kernel/mm.h>
|
||||||
#include <kernel/usercopy.h>
|
#include <kernel/usercopy.h>
|
||||||
|
|
||||||
#define DISK_READ(desc, it, lba, size) (desc)->read(desc->private, it, lba, size)
|
#define DISK_READ(desc, it, lba, size) (desc)->read(desc->private, it, lba, size)
|
||||||
@@ -200,7 +200,7 @@ static int registerdesc(blockdesc_t *desc, char *name) {
|
|||||||
|
|
||||||
static int detectpart(blockdesc_t *desc) {
|
static int detectpart(blockdesc_t *desc) {
|
||||||
// read first two sectors
|
// read first two sectors
|
||||||
void *sects = vmm_map(NULL, desc->blocksize * 2, VMM_FLAGS_ALLOCATE, MAP_FLAGS, NULL);
|
void *sects = mm_map(NULL, desc->blocksize * 2, MM_RANGE_FLAGS_ALLOCATE, MAP_FLAGS, NULL);
|
||||||
__assert(sects);
|
__assert(sects);
|
||||||
__assert(disk_read_direct(desc, sects, 0, 2) == 0);
|
__assert(disk_read_direct(desc, sects, 0, 2) == 0);
|
||||||
|
|
||||||
@@ -216,7 +216,7 @@ static int detectpart(blockdesc_t *desc) {
|
|||||||
else if (bootmagic == MBR_BOOT_MAGIC)
|
else if (bootmagic == MBR_BOOT_MAGIC)
|
||||||
ret = PART_MBR;
|
ret = PART_MBR;
|
||||||
|
|
||||||
vmm_unmap(sects, desc->blocksize * 2, 0);
|
mm_unmap(sects, desc->blocksize * 2, 0);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -241,7 +241,7 @@ static bool gptentryvalid(blockdesc_t *desc, gptheader_t *header, gptentry_t *en
|
|||||||
|
|
||||||
static void dogpt(blockdesc_t *desc, char *name) {
|
static void dogpt(blockdesc_t *desc, char *name) {
|
||||||
// get header
|
// get header
|
||||||
void *lba1 = vmm_map(NULL, desc->blocksize, VMM_FLAGS_ALLOCATE, MAP_FLAGS, NULL);
|
void *lba1 = mm_map(NULL, desc->blocksize, MM_RANGE_FLAGS_ALLOCATE, MAP_FLAGS, NULL);
|
||||||
__assert(lba1);
|
__assert(lba1);
|
||||||
__assert(disk_read_direct(desc, lba1, 1, 1) == 0);
|
__assert(disk_read_direct(desc, lba1, 1, 1) == 0);
|
||||||
gptheader_t *header = lba1;
|
gptheader_t *header = lba1;
|
||||||
@@ -249,7 +249,7 @@ static void dogpt(blockdesc_t *desc, char *name) {
|
|||||||
// get partition table
|
// get partition table
|
||||||
size_t tablebytesize = header->entrybytesize * header->entrycount;
|
size_t tablebytesize = header->entrybytesize * header->entrycount;
|
||||||
size_t tablelbasize = ROUND_UP(tablebytesize, desc->blocksize) / desc->blocksize;
|
size_t tablelbasize = ROUND_UP(tablebytesize, desc->blocksize) / desc->blocksize;
|
||||||
void *tablebuffer = vmm_map(NULL, tablelbasize * desc->blocksize, VMM_FLAGS_ALLOCATE, MAP_FLAGS, NULL);
|
void *tablebuffer = mm_map(NULL, tablelbasize * desc->blocksize, MM_RANGE_FLAGS_ALLOCATE, MAP_FLAGS, NULL);
|
||||||
__assert(tablebuffer);
|
__assert(tablebuffer);
|
||||||
__assert(disk_read_direct(desc, tablebuffer, header->entryarraylbastart, tablelbasize) == 0);
|
__assert(disk_read_direct(desc, tablebuffer, header->entryarraylbastart, tablelbasize) == 0);
|
||||||
|
|
||||||
@@ -277,13 +277,13 @@ static void dogpt(blockdesc_t *desc, char *name) {
|
|||||||
__assert(registerdesc(partdesc, partname) == 0);
|
__assert(registerdesc(partdesc, partname) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
vmm_unmap(tablebuffer, tablelbasize * desc->blocksize, 0);
|
mm_unmap(tablebuffer, tablelbasize * desc->blocksize, 0);
|
||||||
vmm_unmap(lba1, desc->blocksize, 0);
|
mm_unmap(lba1, desc->blocksize, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dombr(blockdesc_t *desc, char *name) {
|
static void dombr(blockdesc_t *desc, char *name) {
|
||||||
// get entries
|
// get entries
|
||||||
void *lba0 = vmm_map(NULL, desc->blocksize, VMM_FLAGS_ALLOCATE, MAP_FLAGS, NULL);
|
void *lba0 = mm_map(NULL, desc->blocksize, MM_RANGE_FLAGS_ALLOCATE, MAP_FLAGS, NULL);
|
||||||
__assert(lba0);
|
__assert(lba0);
|
||||||
__assert(disk_read_direct(desc, lba0, 0, 1) == 0);
|
__assert(disk_read_direct(desc, lba0, 0, 1) == 0);
|
||||||
mbrentry_t *mbrents = (mbrentry_t *)((uintptr_t)lba0 + MBR_ENTRIES_OFFSET);
|
mbrentry_t *mbrents = (mbrentry_t *)((uintptr_t)lba0 + MBR_ENTRIES_OFFSET);
|
||||||
@@ -310,7 +310,7 @@ static void dombr(blockdesc_t *desc, char *name) {
|
|||||||
__assert(registerdesc(partdesc, partname) == 0);
|
__assert(registerdesc(partdesc, partname) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
vmm_unmap(lba0, desc->blocksize, 0);
|
mm_unmap(lba0, desc->blocksize, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void block_register(blockdesc_t *desc, char *name) {
|
void block_register(blockdesc_t *desc, char *name) {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#include <kernel/pci.h>
|
#include <kernel/pci.h>
|
||||||
#include <logging.h>
|
#include <logging.h>
|
||||||
#include <kernel/vmm.h>
|
#include <kernel/mm.h>
|
||||||
#include <util.h>
|
#include <util.h>
|
||||||
#include <kernel/page.h>
|
#include <kernel/page.h>
|
||||||
#include <kernel/alloc.h>
|
#include <kernel/alloc.h>
|
||||||
|
|||||||
+5
-5
@@ -144,7 +144,7 @@ static int mmap(int minor, void *addr, uintmax_t offset, int flags) {
|
|||||||
if (flags & V_FFLAGS_SHARED) {
|
if (flags & V_FFLAGS_SHARED) {
|
||||||
// make sure offset is ALWAYS page aligned when doing a shared mapping
|
// make sure offset is ALWAYS page aligned when doing a shared mapping
|
||||||
__assert((offset % PAGE_SIZE) == 0);
|
__assert((offset % PAGE_SIZE) == 0);
|
||||||
return arch_mmu_map(current_vmm_context()->pagetable, FROM_HHDM((void *)((uintptr_t)fbs[minor]->address + offset)), addr, vnodeflagstommuflags(flags)) ? 0 : ENOMEM;
|
return arch_mmu_map(current_mm_context()->pagetable, FROM_HHDM((void *)((uintptr_t)fbs[minor]->address + offset)), addr, mm_vnode_flags_to_mmu_flags(flags)) ? 0 : ENOMEM;
|
||||||
} else {
|
} else {
|
||||||
size_t size = offset + PAGE_SIZE < end ? PAGE_SIZE : end - offset;
|
size_t size = offset + PAGE_SIZE < end ? PAGE_SIZE : end - offset;
|
||||||
paddr = mm_alloc_page(MEMORY_SECTION_DEFAULT);
|
paddr = mm_alloc_page(MEMORY_SECTION_DEFAULT);
|
||||||
@@ -153,7 +153,7 @@ static int mmap(int minor, void *addr, uintmax_t offset, int flags) {
|
|||||||
|
|
||||||
memcpy(MAKE_HHDM(paddr), (void *)((uintptr_t)fbs[minor]->address + offset), size);
|
memcpy(MAKE_HHDM(paddr), (void *)((uintptr_t)fbs[minor]->address + offset), size);
|
||||||
|
|
||||||
if (arch_mmu_map(current_vmm_context()->pagetable, paddr, addr, vnodeflagstommuflags(flags) | ARCH_MMU_FLAGS_WC) == false) {
|
if (arch_mmu_map(current_mm_context()->pagetable, paddr, addr, mm_vnode_flags_to_mmu_flags(flags) | ARCH_MMU_FLAGS_WC) == false) {
|
||||||
mm_release_page(paddr);
|
mm_release_page(paddr);
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
}
|
}
|
||||||
@@ -163,9 +163,9 @@ static int mmap(int minor, void *addr, uintmax_t offset, int flags) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int munmap(int minor, void *addr, uintmax_t offset, int flags) {
|
static int munmap(int minor, void *addr, uintmax_t offset, int flags) {
|
||||||
void *phys = arch_mmu_getphysical(current_vmm_context()->pagetable, addr);
|
void *phys = arch_mmu_getphysical(current_mm_context()->pagetable, addr);
|
||||||
bool release = (flags & V_FFLAGS_SHARED) && arch_mmu_iswritable(current_vmm_context()->pagetable, addr);
|
bool release = (flags & V_FFLAGS_SHARED) && arch_mmu_iswritable(current_mm_context()->pagetable, addr);
|
||||||
arch_mmu_unmap(current_vmm_context()->pagetable, addr);
|
arch_mmu_unmap(current_mm_context()->pagetable, addr);
|
||||||
arch_mmu_invalidate_range(addr, PAGE_SIZE);
|
arch_mmu_invalidate_range(addr, PAGE_SIZE);
|
||||||
if (release)
|
if (release)
|
||||||
mm_release_page(phys);
|
mm_release_page(phys);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#include <kernel/iovec.h>
|
#include <kernel/iovec.h>
|
||||||
#include <kernel/vmm.h>
|
#include <kernel/mm.h>
|
||||||
#include <kernel/usercopy.h>
|
#include <kernel/usercopy.h>
|
||||||
|
|
||||||
static inline bool iovec_iterator_finished(iovec_iterator_t *iovec_iterator) {
|
static inline bool iovec_iterator_finished(iovec_iterator_t *iovec_iterator) {
|
||||||
@@ -246,7 +246,7 @@ int iovec_iterator_next_page(iovec_iterator_t *iovec_iterator, size_t *page_offs
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *phys = vmm_getphysical((void *)((uintptr_t)addr - offset_in_page), VMM_GET_PHYSICAL_FLAGS_HOLD | VMM_GET_PHYSICAL_FLAGS_LOCK);
|
void *phys = mm_get_physical_address((void *)((uintptr_t)addr - offset_in_page), MM_GET_PHYSICAL_ADDRESS_FLAGS_HOLD | MM_GET_PHYSICAL_ADDRESS_FLAGS_LOCK);
|
||||||
if (phys == NULL)
|
if (phys == NULL)
|
||||||
return EFAULT;
|
return EFAULT;
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -2,7 +2,7 @@
|
|||||||
#include <arch/pci.h>
|
#include <arch/pci.h>
|
||||||
#include <kernel/pci.h>
|
#include <kernel/pci.h>
|
||||||
#include <kernel/alloc.h>
|
#include <kernel/alloc.h>
|
||||||
#include <kernel/vmm.h>
|
#include <kernel/mm.h>
|
||||||
#include <kernel/init.h>
|
#include <kernel/init.h>
|
||||||
|
|
||||||
uint8_t pci_read8(int bus, int device, int function, uint32_t offset) {
|
uint8_t pci_read8(int bus, int device, int function, uint32_t offset) {
|
||||||
@@ -185,7 +185,7 @@ void pci_msisetmask(pcienum_t *e, int vector, int value) {
|
|||||||
|
|
||||||
void *pci_mapbar(pcibar_t bar) {
|
void *pci_mapbar(pcibar_t bar) {
|
||||||
__assert(bar.mmio);
|
__assert(bar.mmio);
|
||||||
return vmm_map(NULL, bar.length, VMM_FLAGS_PHYSICAL, BAR_MAP_FLAGS | (bar.prefetchable ? ARCH_MMU_FLAGS_WT : ARCH_MMU_FLAGS_UC), (void *)bar.address);
|
return mm_map(NULL, bar.length, MM_RANGE_FLAGS_PHYSICAL, BAR_MAP_FLAGS | (bar.prefetchable ? ARCH_MMU_FLAGS_WT : ARCH_MMU_FLAGS_UC), (void *)bar.address);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define BAR_IO 1
|
#define BAR_IO 1
|
||||||
|
|||||||
@@ -102,4 +102,4 @@ void term_init() {
|
|||||||
logging_sethook(term_putchar);
|
logging_sethook(term_putchar);
|
||||||
}
|
}
|
||||||
|
|
||||||
INIT_ROUTINE_DEFINE(term, INIT_ROUTINE_FLAGS_NONE, term_init, vmm);
|
INIT_ROUTINE_DEFINE(term, INIT_ROUTINE_FLAGS_NONE, term_init, mm);
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
#include <kernel/pci.h>
|
#include <kernel/pci.h>
|
||||||
#include <kernel/page.h>
|
#include <kernel/page.h>
|
||||||
#include <kernel/usb.h>
|
#include <kernel/usb.h>
|
||||||
#include <kernel/vmm.h>
|
#include <kernel/mm.h>
|
||||||
#include <list.h>
|
#include <list.h>
|
||||||
#include <logging.h>
|
#include <logging.h>
|
||||||
#include <util.h>
|
#include <util.h>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#include <kernel/xhci.h>
|
#include <kernel/xhci.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <kernel/alloc.h>
|
#include <kernel/alloc.h>
|
||||||
#include <kernel/vmm.h>
|
#include <kernel/mm.h>
|
||||||
#include <kernel/page.h>
|
#include <kernel/page.h>
|
||||||
#include <logging.h>
|
#include <logging.h>
|
||||||
|
|
||||||
@@ -70,7 +70,7 @@ int xhci_data_xfer(xhci_ctrl_t *xhci, xhci_device_t *dev, usb_xfer_t *xfer, xhci
|
|||||||
// This should never be called with user pages. Doing so is a bug. For user-fronting code, use
|
// This should never be called with user pages. Doing so is a bug. For user-fronting code, use
|
||||||
// the scatter-gather variant
|
// the scatter-gather variant
|
||||||
__assert(!IS_USER_ADDRESS(xfer->data));
|
__assert(!IS_USER_ADDRESS(xfer->data));
|
||||||
void *page = vmm_getphysical(xfer->data - page_offset, VMM_GET_PHYSICAL_FLAGS_HOLD);
|
void *page = mm_get_physical_address(xfer->data - page_offset, MM_GET_PHYSICAL_ADDRESS_FLAGS_HOLD);
|
||||||
__assert(page != NULL);
|
__assert(page != NULL);
|
||||||
trb.parameters = (uint64_t)page + page_offset;
|
trb.parameters = (uint64_t)page + page_offset;
|
||||||
}
|
}
|
||||||
@@ -242,7 +242,7 @@ int xhci_control_xfer(xhci_ctrl_t *xhci, xhci_device_t *dev, usb_xfer_t *xfer, x
|
|||||||
mm_hold_page(xfer->data - page_offset);
|
mm_hold_page(xfer->data - page_offset);
|
||||||
data_trb.parameters = (uint64_t)xfer->data;
|
data_trb.parameters = (uint64_t)xfer->data;
|
||||||
} else {
|
} else {
|
||||||
void *page = vmm_getphysical(xfer->data - page_offset, VMM_GET_PHYSICAL_FLAGS_HOLD);
|
void *page = mm_get_physical_address(xfer->data - page_offset, MM_GET_PHYSICAL_ADDRESS_FLAGS_HOLD);
|
||||||
if (page == NULL) {
|
if (page == NULL) {
|
||||||
xhci_ring_unreserve(ring, trb_count);
|
xhci_ring_unreserve(ring, trb_count);
|
||||||
return EFAULT;
|
return EFAULT;
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#include <kernel/mm.h>
|
#include <kernel/mm.h>
|
||||||
#include <kernel/vmm.h>
|
|
||||||
#include <util.h>
|
#include <util.h>
|
||||||
#include <logging.h>
|
#include <logging.h>
|
||||||
#include <kernel/timekeeper.h>
|
#include <kernel/timekeeper.h>
|
||||||
@@ -487,7 +486,7 @@ static void writer() {
|
|||||||
|
|
||||||
void mm_cache_init(void) {
|
void mm_cache_init(void) {
|
||||||
MUTEX_INIT(&mutex);
|
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);
|
__assert(table);
|
||||||
memset(table, 0, TABLE_SIZE * sizeof(page_t *));
|
memset(table, 0, TABLE_SIZE * sizeof(page_t *));
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#include <kernel/vmm.h>
|
#include <kernel/mm.h>
|
||||||
#include <logging.h>
|
#include <logging.h>
|
||||||
#include <kernel/page.h>
|
#include <kernel/page.h>
|
||||||
#include <util.h>
|
#include <util.h>
|
||||||
@@ -6,29 +6,28 @@
|
|||||||
#include <limine.h>
|
#include <limine.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <kernel/slab.h>
|
#include <kernel/slab.h>
|
||||||
#include <kernel/mm.h>
|
|
||||||
#include <kernel/init.h>
|
#include <kernel/init.h>
|
||||||
|
|
||||||
// ranges are separated into kernel and user. the kernel has a temporary user context
|
// ranges are separated into kernel and user. the kernel has a temporary user context
|
||||||
vmmcontext_t vmm_kernelctx;
|
mm_context_t mm_kernel_ctx;
|
||||||
static vmmspace_t kernelspace = {
|
static mm_space_t kernelspace = {
|
||||||
.start = KERNELSPACE_START,
|
.start = KERNELSPACE_START,
|
||||||
.end = KERNELSPACE_END
|
.end = KERNELSPACE_END
|
||||||
};
|
};
|
||||||
|
|
||||||
// returns a pointer to the space of vaddr
|
// 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)
|
if (USERSPACE_START <= vaddr && vaddr < USERSPACE_END)
|
||||||
return ¤t_vmm_context()->space;
|
return ¤t_mm_context()->space;
|
||||||
else if (KERNELSPACE_START <= vaddr && vaddr < KERNELSPACE_END)
|
else if (KERNELSPACE_START <= vaddr && vaddr < KERNELSPACE_END)
|
||||||
return &kernelspace;
|
return &kernelspace;
|
||||||
else
|
else
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int vmm_range_compare(rbtree_t *a, rbtree_t *b) {
|
static int mm_range_compare(rbtree_t *a, rbtree_t *b) {
|
||||||
vmmrange_t *range_a = container_of(a, vmmrange_t, rbtree_node);
|
mm_range_t *range_a = container_of(a, mm_range_t, rbtree_node);
|
||||||
vmmrange_t *range_b = container_of(b, vmmrange_t, rbtree_node);
|
mm_range_t *range_b = container_of(b, mm_range_t, rbtree_node);
|
||||||
|
|
||||||
if (range_a->start == range_b->start)
|
if (range_a->start == range_b->start)
|
||||||
return 0;
|
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;
|
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);
|
base = (void *)ROUND_DOWN((uintptr_t)base, PAGE_SIZE);
|
||||||
|
|
||||||
if (flags & VMM_FLAGS_PAGESIZE)
|
if (flags & MM_RANGE_FLAGS_PAGESIZE)
|
||||||
size *= PAGE_SIZE;
|
size *= PAGE_SIZE;
|
||||||
else
|
else
|
||||||
size = ROUND_UP(size, PAGE_SIZE);
|
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)
|
if (size == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
vmmspace_t *space = getspace(base);
|
mm_space_t *space = getspace(base);
|
||||||
if (space == NULL)
|
if (space == NULL)
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
|
|
||||||
@@ -63,40 +62,40 @@ int vmm_changemmuflags(void *base, size_t size, mmuflags_t mmuflags, int flags)
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void printspace(vmmspace_t *space) {
|
static void printspace(mm_space_t *space) {
|
||||||
printf("vmm: ranges:\n");
|
printf("mm: ranges:\n");
|
||||||
rbtree_t *rbtree = rbtree_first(space->ranges);
|
rbtree_t *rbtree = rbtree_first(space->ranges);
|
||||||
while (rbtree) {
|
while (rbtree) {
|
||||||
vmmrange_t *range = container_of(rbtree, vmmrange_t, rbtree_node);
|
mm_range_t *range = container_of(rbtree, mm_range_t, rbtree_node);
|
||||||
printf("vmm: address %p size %lx flags %x\n", range->start, range->size, range->flags);
|
printf("mm: address %p size %lx flags %x\n", range->start, range->size, range->flags);
|
||||||
rbtree = rbtree_successor(rbtree);
|
rbtree = rbtree_successor(rbtree);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *zeropage;
|
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) {
|
if (user == false && addr > USERSPACE_END) {
|
||||||
printf("vmm: kernel access\n");
|
printf("mm: kernel access\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
addr = (void *)ROUND_DOWN((uintptr_t)addr, PAGE_SIZE);
|
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)) {
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
MUTEX_ACQUIRE(&space->lock);
|
MUTEX_ACQUIRE(&space->lock);
|
||||||
vmmrange_t *range = mm_get_range(space, addr);
|
mm_range_t *range = mm_get_range(space, addr);
|
||||||
|
|
||||||
bool status = false;
|
bool status = false;
|
||||||
|
|
||||||
if (range == NULL) {
|
if (range == NULL) {
|
||||||
printf("vmm: no range\n");
|
printf("mm: no range\n");
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,16 +104,16 @@ bool vmm_pagefault(void *addr, bool user, int actions) {
|
|||||||
int invalidactions = 0;
|
int invalidactions = 0;
|
||||||
|
|
||||||
if ((range->mmuflags & ARCH_MMU_FLAGS_READ) == 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)
|
if ((range->mmuflags & ARCH_MMU_FLAGS_WRITE) == 0)
|
||||||
invalidactions |= VMM_ACTION_WRITE;
|
invalidactions |= MM_FAULT_ACTION_WRITE;
|
||||||
|
|
||||||
if ((range->mmuflags & ARCH_MMU_FLAGS_NOEXEC))
|
if ((range->mmuflags & ARCH_MMU_FLAGS_NOEXEC))
|
||||||
invalidactions |= VMM_ACTION_EXEC;
|
invalidactions |= MM_FAULT_ACTION_EXEC;
|
||||||
|
|
||||||
if (invalidactions & actions) {
|
if (invalidactions & actions) {
|
||||||
printf("vmm: bad action\n");
|
printf("mm: bad action\n");
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -122,14 +121,14 @@ bool vmm_pagefault(void *addr, bool user, int actions) {
|
|||||||
proc_t *proc = thread ? thread->proc : NULL;
|
proc_t *proc = thread ? thread->proc : NULL;
|
||||||
cred_t *cred = proc ? &proc->cred : 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
|
// 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;
|
uintmax_t mapoffset = (uintptr_t)addr - (uintptr_t)range->start;
|
||||||
if (vfs_iscacheable(range->vnode) == false) {
|
if (vfs_iscacheable(range->vnode) == false) {
|
||||||
// map non cacheable vnodes
|
// map non cacheable vnodes
|
||||||
VOP_LOCK(range->vnode);
|
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);
|
VOP_UNLOCK(range->vnode);
|
||||||
status = true;
|
status = true;
|
||||||
} else {
|
} else {
|
||||||
@@ -139,17 +138,17 @@ bool vmm_pagefault(void *addr, bool user, int actions) {
|
|||||||
|
|
||||||
if (error == ENXIO || error == ENOMEM) {
|
if (error == ENXIO || error == ENOMEM) {
|
||||||
if (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
|
// address is past the last page of the file
|
||||||
signal_signalthread(current_thread(), SIGBUS, true);
|
signal_signalthread(current_thread(), SIGBUS, true);
|
||||||
status = true;
|
status = true;
|
||||||
} else if (error) {
|
} 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;
|
status = false;
|
||||||
} else {
|
} 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) {
|
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));
|
mm_release_page(mm_get_page_address(res));
|
||||||
signal_signalthread(current_thread(), SIGBUS, true);
|
signal_signalthread(current_thread(), SIGBUS, true);
|
||||||
status = 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
|
// writeable range: allocate a new page, zero it and map it
|
||||||
void *new_page = mm_alloc_page(MEMORY_SECTION_DEFAULT);
|
void *new_page = mm_alloc_page(MEMORY_SECTION_DEFAULT);
|
||||||
if (new_page == NULL) {
|
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);
|
signal_signalthread(current_thread(), SIGBUS, true);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(MAKE_HHDM(new_page), 0, PAGE_SIZE);
|
memset(MAKE_HHDM(new_page), 0, PAGE_SIZE);
|
||||||
|
|
||||||
if (!arch_mmu_map(current_vmm_context()->pagetable, new_page, addr, range->mmuflags)) {
|
if (!arch_mmu_map(current_mm_context()->pagetable, new_page, addr, range->mmuflags)) {
|
||||||
printf("vmm: out of memory to map page (sending SIGBUS)\n");
|
printf("mm: out of memory to map page (sending SIGBUS)\n");
|
||||||
signal_signalthread(current_thread(), SIGBUS, true);
|
signal_signalthread(current_thread(), SIGBUS, true);
|
||||||
mm_release_page(new_page);
|
mm_release_page(new_page);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// read-only range: map a shared zero page
|
// read-only range: map a shared zero page
|
||||||
if (!arch_mmu_map(current_vmm_context()->pagetable, zeropage, addr, range->mmuflags)) {
|
if (!arch_mmu_map(current_mm_context()->pagetable, zeropage, addr, range->mmuflags)) {
|
||||||
printf("vmm: out of memory to map zero page into address space (sending SIGBUS)\n");
|
printf("mm: out of memory to map zero page into address space (sending SIGBUS)\n");
|
||||||
signal_signalthread(current_thread(), SIGBUS, true);
|
signal_signalthread(current_thread(), SIGBUS, true);
|
||||||
} else {
|
} else {
|
||||||
mm_hold_page(zeropage);
|
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
|
// 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);
|
page_t *oldpage = mm_get_page(oldphys);
|
||||||
|
|
||||||
if ( ((range->flags & VMM_FLAGS_FILE) && (range->flags & VMM_FLAGS_SHARED)) ||
|
if ( ((range->flags & MM_RANGE_FLAGS_FILE) && (range->flags & MM_RANGE_FLAGS_SHARED)) ||
|
||||||
((range->flags & VMM_FLAGS_FILE) == 0 && oldpage->refcount == 1)) {
|
((range->flags & MM_RANGE_FLAGS_FILE) == 0 && oldpage->refcount == 1)) {
|
||||||
// shared file or anon with refcount == 1, remap it as writable
|
// shared file or anon with refcount == 1, remap it as writable
|
||||||
|
|
||||||
arch_mmu_remap(current_vmm_context()->pagetable, oldphys, addr, range->mmuflags);
|
arch_mmu_remap(current_mm_context()->pagetable, oldphys, addr, range->mmuflags);
|
||||||
if ((range->flags & VMM_FLAGS_FILE) && vfs_iscacheable(range->vnode)) {
|
if ((range->flags & MM_RANGE_FLAGS_FILE) && vfs_iscacheable(range->vnode)) {
|
||||||
// and if its a cache page, mark it as dirty
|
// and if its a cache page, mark it as dirty
|
||||||
VOP_LOCK(range->vnode);
|
VOP_LOCK(range->vnode);
|
||||||
mm_cache_make_dirty(mm_get_page(oldphys));
|
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
|
// do copy on write
|
||||||
void *newphys = mm_alloc_page(MEMORY_SECTION_DEFAULT);
|
void *newphys = mm_alloc_page(MEMORY_SECTION_DEFAULT);
|
||||||
if (newphys == NULL) {
|
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);
|
signal_signalthread(current_thread(), SIGBUS, true);
|
||||||
status = true;
|
status = true;
|
||||||
} else {
|
} else {
|
||||||
memcpy(MAKE_HHDM(newphys), MAKE_HHDM(oldphys), PAGE_SIZE);
|
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);
|
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);
|
mm_release_page(oldphys);
|
||||||
|
|
||||||
status = true;
|
status = true;
|
||||||
@@ -231,16 +230,16 @@ bool vmm_pagefault(void *addr, bool user, int actions) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
static int lock_page(vmmspace_t *space, void *vaddr) {
|
static int lock_page(mm_space_t *space, void *vaddr) {
|
||||||
vmmrange_t *range = mm_get_range(space, vaddr);
|
mm_range_t *range = mm_get_range(space, vaddr);
|
||||||
if (!range)
|
if (!range)
|
||||||
return ENOENT;
|
return ENOENT;
|
||||||
|
|
||||||
void *mapped_address = arch_mmu_getphysical(current_vmm_context()->pagetable, vaddr);
|
void *mapped_address = arch_mmu_getphysical(current_mm_context()->pagetable, vaddr);
|
||||||
bool present = arch_mmu_ispresent(current_vmm_context()->pagetable, vaddr);
|
bool present = arch_mmu_ispresent(current_mm_context()->pagetable, vaddr);
|
||||||
bool writable = arch_mmu_iswritable(current_vmm_context()->pagetable, vaddr);
|
bool writable = arch_mmu_iswritable(current_mm_context()->pagetable, vaddr);
|
||||||
bool file_mapping = range->flags & VMM_FLAGS_FILE;
|
bool file_mapping = range->flags & MM_RANGE_FLAGS_FILE;
|
||||||
bool private = (range->flags & VMM_FLAGS_SHARED) == 0 || file_mapping == false;
|
bool private = (range->flags & MM_RANGE_FLAGS_SHARED) == 0 || file_mapping == false;
|
||||||
void *real_phys;
|
void *real_phys;
|
||||||
|
|
||||||
// TODO anon with refcount == 1 can go into another cas
|
// 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);
|
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);
|
arch_mmu_invalidate_range(vaddr, PAGE_SIZE);
|
||||||
if (file_mapping == false || vfs_iscacheable(range->vnode))
|
if (file_mapping == false || vfs_iscacheable(range->vnode))
|
||||||
mm_release_page(mapped_address);
|
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);
|
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)
|
if (space == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@@ -277,29 +276,28 @@ void *vmm_getphysical(void *addr, int flags) {
|
|||||||
|
|
||||||
void *physical;
|
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;
|
physical = NULL;
|
||||||
goto leave;
|
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);
|
mm_hold_page(physical);
|
||||||
|
|
||||||
leave:
|
|
||||||
MUTEX_RELEASE(&space->lock);
|
MUTEX_RELEASE(&space->lock);
|
||||||
return physical + ((uintptr_t)addr - (uintptr_t)aligned_addr);
|
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)
|
if (addr == NULL)
|
||||||
addr = KERNELSPACE_START;
|
addr = KERNELSPACE_START;
|
||||||
|
|
||||||
// XXX maps where addr is not page aligned can break
|
// XXX maps where addr is not page aligned can break
|
||||||
addr = (void *)ROUND_DOWN((uintptr_t)addr, PAGE_SIZE);
|
addr = (void *)ROUND_DOWN((uintptr_t)addr, PAGE_SIZE);
|
||||||
if (flags & VMM_FLAGS_PAGESIZE)
|
if (flags & MM_RANGE_FLAGS_PAGESIZE)
|
||||||
size *= PAGE_SIZE;
|
size *= PAGE_SIZE;
|
||||||
else
|
else
|
||||||
size = ROUND_UP(size, PAGE_SIZE);
|
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)
|
if (size == 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
vmmspace_t *space = getspace(addr);
|
mm_space_t *space = getspace(addr);
|
||||||
if (space == NULL)
|
if (space == NULL)
|
||||||
return 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;
|
mmuflags |= ARCH_MMU_FLAGS_GLOBAL;
|
||||||
|
|
||||||
MUTEX_ACQUIRE(&space->lock);
|
MUTEX_ACQUIRE(&space->lock);
|
||||||
vmmrange_t *range = NULL;
|
mm_range_t *range = NULL;
|
||||||
|
|
||||||
void *start = mm_get_free_range(space, addr, size);
|
void *start = mm_get_free_range(space, addr, size);
|
||||||
void *retaddr = NULL;
|
void *retaddr = NULL;
|
||||||
if (((flags & VMM_FLAGS_EXACT) && start != addr) || start == NULL)
|
if (((flags & MM_RANGE_FLAGS_EXACT) && start != addr) || start == NULL)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
range = mm_alloc_range();
|
range = mm_alloc_range();
|
||||||
if (range == NULL)
|
if (range == NULL)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
if (flags & VMM_FLAGS_REPLACE) {
|
if (flags & MM_RANGE_FLAGS_REPLACE) {
|
||||||
__assert(addr);
|
__assert(addr);
|
||||||
retaddr = addr;
|
retaddr = addr;
|
||||||
range->start = addr;
|
range->start = addr;
|
||||||
range->size = size;
|
range->size = size;
|
||||||
range->flags = VMM_PERMANENT_FLAGS_MASK & flags;
|
range->flags = MM_PERMANENT_RANGE_FLAGS_MASK & flags;
|
||||||
range->mmuflags = mmuflags;
|
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
|
// make the memory inacessible
|
||||||
mm_change_range(space, addr, size, false, flags, 0);
|
mm_change_range(space, addr, size, false, flags, 0);
|
||||||
arch_mmu_invalidate_range(addr, size);
|
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;
|
retaddr = start;
|
||||||
range->start = start;
|
range->start = start;
|
||||||
range->size = size;
|
range->size = size;
|
||||||
range->flags = VMM_PERMANENT_FLAGS_MASK & flags;
|
range->flags = MM_PERMANENT_RANGE_FLAGS_MASK & flags;
|
||||||
range->mmuflags = mmuflags;
|
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
|
// 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);
|
__assert((desc->offset % PAGE_SIZE) == 0);
|
||||||
range->vnode = desc->node;
|
range->vnode = desc->node;
|
||||||
range->offset = desc->offset;
|
range->offset = desc->offset;
|
||||||
VOP_HOLD(desc->node);
|
VOP_HOLD(desc->node);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flags & VMM_FLAGS_PHYSICAL) {
|
if (flags & MM_RANGE_FLAGS_PHYSICAL) {
|
||||||
// map to allocated virtual memory
|
// map to allocated virtual memory
|
||||||
for (uintmax_t i = 0; i < size; i += PAGE_SIZE) {
|
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)
|
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
|
// invalidate here just to be sure
|
||||||
arch_mmu_invalidate_range(start, size);
|
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;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (flags & VMM_FLAGS_ALLOCATE) {
|
} else if (flags & MM_RANGE_FLAGS_ALLOCATE) {
|
||||||
// allocate to virtual memory
|
// allocate to virtual memory
|
||||||
for (uintmax_t i = 0; i < size; i += PAGE_SIZE) {
|
for (uintmax_t i = 0; i < size; i += PAGE_SIZE) {
|
||||||
void *allocated = mm_alloc_page(MEMORY_SECTION_DEFAULT);
|
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;
|
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) {
|
for (uintmax_t j = 0; j < size; j += PAGE_SIZE) {
|
||||||
void *virt = (void *)((uintptr_t)start + i);
|
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) {
|
if (physical) {
|
||||||
mm_release_page(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;
|
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);
|
addr = (void *)ROUND_DOWN((uintptr_t)addr, PAGE_SIZE);
|
||||||
|
|
||||||
if (flags & VMM_FLAGS_PAGESIZE)
|
if (flags & MM_RANGE_FLAGS_PAGESIZE)
|
||||||
size *= PAGE_SIZE;
|
size *= PAGE_SIZE;
|
||||||
else
|
else
|
||||||
size = ROUND_UP(size, PAGE_SIZE);
|
size = ROUND_UP(size, PAGE_SIZE);
|
||||||
@@ -418,7 +416,7 @@ void vmm_unmap(void *addr, size_t size, int flags) {
|
|||||||
if (size == 0)
|
if (size == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
vmmspace_t *space = getspace(addr);
|
mm_space_t *space = getspace(addr);
|
||||||
if (space == NULL)
|
if (space == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -437,7 +435,7 @@ void vmm_unmap(void *addr, size_t size, int flags) {
|
|||||||
static scache_t *ctxcache;
|
static scache_t *ctxcache;
|
||||||
|
|
||||||
static bool ctxctor(scache_t *cache, void *obj) {
|
static bool ctxctor(scache_t *cache, void *obj) {
|
||||||
vmmcontext_t *ctx = obj;
|
mm_context_t *ctx = obj;
|
||||||
ctx->space.start = USERSPACE_START;
|
ctx->space.start = USERSPACE_START;
|
||||||
ctx->space.end = USERSPACE_END;
|
ctx->space.end = USERSPACE_END;
|
||||||
MUTEX_INIT(&ctx->space.lock);
|
MUTEX_INIT(&ctx->space.lock);
|
||||||
@@ -445,13 +443,13 @@ static bool ctxctor(scache_t *cache, void *obj) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
vmmcontext_t *vmm_newcontext() {
|
mm_context_t *mm_create_context() {
|
||||||
if (ctxcache == NULL) {
|
if (ctxcache == NULL) {
|
||||||
ctxcache = slab_newcache(sizeof(vmmcontext_t), 0, ctxctor, NULL);
|
ctxcache = slab_newcache(sizeof(mm_context_t), 0, ctxctor, NULL);
|
||||||
__assert(ctxcache);
|
__assert(ctxcache);
|
||||||
}
|
}
|
||||||
|
|
||||||
vmmcontext_t *ctx = slab_allocate(ctxcache);
|
mm_context_t *ctx = slab_allocate(ctxcache);
|
||||||
if (ctx == NULL)
|
if (ctx == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@@ -464,19 +462,19 @@ vmmcontext_t *vmm_newcontext() {
|
|||||||
return ctx;
|
return ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
void vmm_destroycontext(vmmcontext_t *context) {
|
void mm_destroy_context(mm_context_t *context) {
|
||||||
vmmcontext_t *oldctx = current_thread()->vmmctx;
|
mm_context_t *oldctx = current_thread()->mmctx;
|
||||||
vmm_switchcontext(context);
|
mm_switch_context(context);
|
||||||
vmm_unmap(context->space.start, context->space.end - context->space.start, 0);
|
mm_unmap(context->space.start, context->space.end - context->space.start, 0);
|
||||||
vmm_switchcontext(oldctx);
|
mm_switch_context(oldctx);
|
||||||
arch_mmu_destroytable(context->pagetable);
|
arch_mmu_destroytable(context->pagetable);
|
||||||
|
|
||||||
context->space.ranges = NULL;
|
context->space.ranges = NULL;
|
||||||
slab_free(ctxcache, context);
|
slab_free(ctxcache, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
vmmcontext_t *vmm_fork(vmmcontext_t *oldcontext) {
|
mm_context_t *mm_fork_context(mm_context_t *oldcontext) {
|
||||||
vmmcontext_t *newcontext = vmm_newcontext();
|
mm_context_t *newcontext = mm_create_context();
|
||||||
if (newcontext == NULL)
|
if (newcontext == NULL)
|
||||||
return 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;
|
rbtree_t *rbtree = oldcontext->space.ranges ? rbtree_first(oldcontext->space.ranges) : NULL;
|
||||||
while (rbtree) {
|
while (rbtree) {
|
||||||
vmmrange_t *range = container_of(rbtree, vmmrange_t, rbtree_node);
|
mm_range_t *range = container_of(rbtree, mm_range_t, rbtree_node);
|
||||||
vmmrange_t *newrange = mm_alloc_range();
|
mm_range_t *newrange = mm_alloc_range();
|
||||||
if (newrange == NULL)
|
if (newrange == NULL)
|
||||||
goto error;
|
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);
|
rbtree_insert(&newcontext->space.ranges, &newrange->rbtree_node, mm_range_compare);
|
||||||
if (range->flags & VMM_FLAGS_FILE)
|
if (range->flags & MM_RANGE_FLAGS_FILE)
|
||||||
VOP_HOLD(range->vnode);
|
VOP_HOLD(range->vnode);
|
||||||
|
|
||||||
// copy any pages that are mapped
|
// copy any pages that are mapped
|
||||||
@@ -522,14 +520,14 @@ vmmcontext_t *vmm_fork(vmmcontext_t *oldcontext) {
|
|||||||
return newcontext;
|
return newcontext;
|
||||||
error:
|
error:
|
||||||
MUTEX_RELEASE(&oldcontext->space.lock);
|
MUTEX_RELEASE(&oldcontext->space.lock);
|
||||||
vmm_destroycontext(newcontext);
|
mm_destroy_context(newcontext);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void vmm_switchcontext(vmmcontext_t *ctx) {
|
void mm_switch_context(mm_context_t *ctx) {
|
||||||
if (current_thread())
|
if (current_thread())
|
||||||
current_thread()->vmmctx = ctx;
|
current_thread()->mmctx = ctx;
|
||||||
set_current_vmm_context(ctx);
|
set_current_mm_context(ctx);
|
||||||
arch_mmu_switch(ctx->pagetable);
|
arch_mmu_switch(ctx->pagetable);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -542,18 +540,18 @@ extern void *_rodata_end;
|
|||||||
|
|
||||||
extern volatile struct limine_memmap_request mm_page_limine_map;
|
extern volatile struct limine_memmap_request mm_page_limine_map;
|
||||||
|
|
||||||
void vmm_init() {
|
void mm_init() {
|
||||||
// set up initial state
|
// set up initial state
|
||||||
mm_range_init();
|
mm_range_init();
|
||||||
MUTEX_INIT(&kernelspace.lock);
|
MUTEX_INIT(&kernelspace.lock);
|
||||||
|
|
||||||
vmm_kernelctx.pagetable = arch_mmu_newtable();
|
mm_kernel_ctx.pagetable = arch_mmu_newtable();
|
||||||
__assert(vmm_kernelctx.pagetable);
|
__assert(mm_kernel_ctx.pagetable);
|
||||||
|
|
||||||
vmm_kernelctx.space.start = USERSPACE_START;
|
mm_kernel_ctx.space.start = USERSPACE_START;
|
||||||
vmm_kernelctx.space.end = USERSPACE_END;
|
mm_kernel_ctx.space.end = USERSPACE_END;
|
||||||
|
|
||||||
vmm_switchcontext(&vmm_kernelctx);
|
mm_switch_context(&mm_kernel_ctx);
|
||||||
|
|
||||||
// map HHDM
|
// map HHDM
|
||||||
for (uint64_t i = 0; i < mm_page_limine_map.response->entry_count; ++i) {
|
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)
|
if (e->type == LIMINE_MEMMAP_FRAMEBUFFER)
|
||||||
mmuflags |= ARCH_MMU_FLAGS_WC;
|
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
|
// 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(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(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(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(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(&_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
|
// 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
|
// zero page
|
||||||
zeropage = mm_alloc_page(MEMORY_SECTION_DEFAULT);
|
zeropage = mm_alloc_page(MEMORY_SECTION_DEFAULT);
|
||||||
@@ -584,8 +582,8 @@ void vmm_init() {
|
|||||||
printspace(&kernelspace);
|
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() {
|
void mm_apinit() {
|
||||||
vmm_switchcontext(&vmm_kernelctx);
|
mm_switch_context(&mm_kernel_ctx);
|
||||||
}
|
}
|
||||||
+57
-58
@@ -1,30 +1,29 @@
|
|||||||
#include <kernel/vmm.h>
|
#include <kernel/mm.h>
|
||||||
#include <logging.h>
|
#include <logging.h>
|
||||||
#include <kernel/page.h>
|
#include <kernel/page.h>
|
||||||
#include <util.h>
|
#include <util.h>
|
||||||
#include <arch/cpu.h>
|
#include <arch/cpu.h>
|
||||||
#include <kernel/slab.h>
|
#include <kernel/slab.h>
|
||||||
#include <kernel/mm.h>
|
|
||||||
|
|
||||||
#define RANGE_TOP(x) (void *)((uintptr_t)x->start + x->size)
|
#define RANGE_TOP(x) (void *)((uintptr_t)x->start + x->size)
|
||||||
|
|
||||||
static scache_t *range_cache;
|
static scache_t *range_cache;
|
||||||
|
|
||||||
void mm_range_init(void) {
|
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);
|
__assert(range_cache);
|
||||||
}
|
}
|
||||||
|
|
||||||
vmmrange_t *mm_alloc_range(void) {
|
mm_range_t *mm_alloc_range(void) {
|
||||||
return slab_allocate(range_cache);
|
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);
|
slab_free(range_cache, range);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rbtree_value_compare(void *addr, rbtree_t *node) {
|
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);
|
void *range_top = RANGE_TOP(range);
|
||||||
|
|
||||||
if (addr >= range_top)
|
if (addr >= range_top)
|
||||||
@@ -37,13 +36,13 @@ static int rbtree_value_compare(void *addr, rbtree_t *node) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// get a range from an address
|
// 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);
|
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
|
// 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;
|
rbtree_t *rbtree = space->ranges;
|
||||||
if (addr == NULL)
|
if (addr == NULL)
|
||||||
addr = space->start;
|
addr = space->start;
|
||||||
@@ -53,7 +52,7 @@ void *mm_get_free_range(vmmspace_t *space, void *addr, size_t size) {
|
|||||||
return addr;
|
return addr;
|
||||||
|
|
||||||
rbtree = rbtree_first(rbtree);
|
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 theres free space before the first range
|
||||||
if (range->start != space->start && addr < range->start && (uintptr_t)range->start - (uintptr_t)addr >= size)
|
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
|
// check for space between two ranges
|
||||||
rbtree_t *next = rbtree_successor(rbtree);
|
rbtree_t *next = rbtree_successor(rbtree);
|
||||||
while (next) {
|
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);
|
void *range_top = RANGE_TOP(range);
|
||||||
if (addr < range_top)
|
if (addr < range_top)
|
||||||
@@ -75,7 +74,7 @@ void *mm_get_free_range(vmmspace_t *space, void *addr, size_t size) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
rbtree = next;
|
rbtree = next;
|
||||||
range = container_of(rbtree, vmmrange_t, rbtree_node);
|
range = container_of(rbtree, mm_range_t, rbtree_node);
|
||||||
|
|
||||||
next = rbtree_successor(next);
|
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) {
|
static int rbtree_compare(rbtree_t *a, rbtree_t *b) {
|
||||||
vmmrange_t *range_a = container_of(a, vmmrange_t, rbtree_node);
|
mm_range_t *range_a = container_of(a, mm_range_t, rbtree_node);
|
||||||
vmmrange_t *range_b = container_of(b, vmmrange_t, rbtree_node);
|
mm_range_t *range_b = container_of(b, mm_range_t, rbtree_node);
|
||||||
|
|
||||||
if (range_a->start == range_b->start)
|
if (range_a->start == range_b->start)
|
||||||
return 0;
|
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;
|
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);
|
void *prev_range_top = RANGE_TOP(prev);
|
||||||
|
|
||||||
return prev_range_top == next->start && prev->flags == next->flags && prev->mmuflags == next->mmuflags && // general compatibility
|
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_insert(&space->ranges, &new_range->rbtree_node, rbtree_compare);
|
||||||
|
|
||||||
rbtree_t *successor = rbtree_successor(&new_range->rbtree_node);
|
rbtree_t *successor = rbtree_successor(&new_range->rbtree_node);
|
||||||
rbtree_t *predecessor = rbtree_predecessor(&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;
|
mm_range_t *next_range = successor ? container_of(successor, mm_range_t, rbtree_node) : NULL;
|
||||||
vmmrange_t *prev_range = predecessor ? container_of(predecessor, vmmrange_t, rbtree_node) : NULL;
|
mm_range_t *prev_range = predecessor ? container_of(predecessor, mm_range_t, rbtree_node) : NULL;
|
||||||
|
|
||||||
// fragmentation checking
|
// 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);
|
rbtree_remove(&space->ranges, &next_range->rbtree_node);
|
||||||
mm_free_range(next_range);
|
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);
|
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);
|
rbtree_remove(&space->ranges, &new_range->rbtree_node);
|
||||||
mm_free_range(new_range);
|
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);
|
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
|
// TODO find first
|
||||||
uintmax_t top = _offset + size;
|
uintmax_t top = _offset + size;
|
||||||
|
|
||||||
for (uintmax_t offset = _offset; offset < top; offset += PAGE_SIZE) {
|
for (uintmax_t offset = _offset; offset < top; offset += PAGE_SIZE) {
|
||||||
void *vaddr = (void *)((uintptr_t)range->start + offset);
|
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)
|
if (physical == NULL)
|
||||||
continue;
|
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;
|
proc_t *proc = thread ? thread->proc : NULL;
|
||||||
cred_t *cred = proc ? &proc->cred : 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
|
// shared file mapping or non cacheable mapping
|
||||||
if (vfs_iscacheable(range->vnode) == false) {
|
if (vfs_iscacheable(range->vnode) == false) {
|
||||||
// non cacheable mapping
|
// non cacheable mapping
|
||||||
VOP_LOCK(range->vnode);
|
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);
|
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
|
// dirty page cache mapping
|
||||||
arch_mmu_unmap(current_vmm_context()->pagetable, vaddr);
|
arch_mmu_unmap(current_mm_context()->pagetable, vaddr);
|
||||||
VOP_LOCK(range->vnode);
|
VOP_LOCK(range->vnode);
|
||||||
mm_cache_make_dirty(mm_get_page(physical));
|
mm_cache_make_dirty(mm_get_page(physical));
|
||||||
VOP_UNLOCK(range->vnode);
|
VOP_UNLOCK(range->vnode);
|
||||||
mm_release_page(physical);
|
mm_release_page(physical);
|
||||||
} else {
|
} else {
|
||||||
// non dirty page mapping
|
// non dirty page mapping
|
||||||
arch_mmu_unmap(current_vmm_context()->pagetable, vaddr);
|
arch_mmu_unmap(current_mm_context()->pagetable, vaddr);
|
||||||
mm_release_page(physical);
|
mm_release_page(physical);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// anonymous, physical or private non character device mapping
|
// anonymous, physical or private non character device mapping
|
||||||
arch_mmu_unmap(current_vmm_context()->pagetable, vaddr);
|
arch_mmu_unmap(current_mm_context()->pagetable, vaddr);
|
||||||
if ((range->flags & VMM_FLAGS_PHYSICAL) == 0)
|
if ((range->flags & MM_RANGE_FLAGS_PHYSICAL) == 0)
|
||||||
mm_release_page(physical);
|
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);
|
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))) \
|
if (((n) & (f)) == 0 && ((c) & (f))) \
|
||||||
m |= 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) {
|
for (uintmax_t offset = 0; offset < size; offset += PAGE_SIZE) {
|
||||||
void *address = (void *)((uintptr_t)base + offset);
|
void *address = (void *)((uintptr_t)base + offset);
|
||||||
|
|
||||||
mmuflags_t current_flags;
|
mmuflags_t current_flags;
|
||||||
// if page is not mapped, do nothing
|
// if page is not mapped, do nothing
|
||||||
if (arch_mmu_getflags(current_vmm_context()->pagetable, address, ¤t_flags) == false)
|
if (arch_mmu_getflags(current_mm_context()->pagetable, address, ¤t_flags) == false)
|
||||||
continue;
|
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;
|
uintmax_t mask = 0;
|
||||||
// check which flags are currently set and will be unset
|
// 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_USER, current_flags, new_flags);
|
||||||
CHANGE_MASK_CHECK(mask, ARCH_MMU_FLAGS_NOEXEC, 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
|
// 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);
|
page_t *page = mm_get_page(physical);
|
||||||
VOP_LOCK(range->vnode);
|
VOP_LOCK(range->vnode);
|
||||||
mm_cache_make_dirty(page);
|
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
|
// we will only change the mapping if the permissions decreased
|
||||||
if (mask) {
|
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);
|
VOP_LOCK(range->vnode);
|
||||||
int error = VOP_ACCESS(range->vnode, V_ACCESS_WRITE, ¤t_thread()->proc->cred);
|
int error = VOP_ACCESS(range->vnode, V_ACCESS_WRITE, ¤t_thread()->proc->cred);
|
||||||
VOP_UNLOCK(range->vnode);
|
VOP_UNLOCK(range->vnode);
|
||||||
return error == 0;
|
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);
|
void *top = (void *)((uintptr_t)address + size);
|
||||||
vmmrange_t *new_range = NULL;
|
mm_range_t *new_range = NULL;
|
||||||
|
|
||||||
if (space->ranges == NULL)
|
if (space->ranges == NULL)
|
||||||
return 0;
|
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
|
// get first range after address
|
||||||
rbtree_t *rbtree = rbtree_find_first_larger_equal(space->ranges, address, rbtree_value_compare);
|
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)
|
if (rbtree == NULL)
|
||||||
goto leave;
|
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
|
// check if we actually start at the predecessor
|
||||||
rbtree_t *predecessor = rbtree_predecessor(rbtree);
|
rbtree_t *predecessor = rbtree_predecessor(rbtree);
|
||||||
if (predecessor) {
|
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) {
|
if (RANGE_TOP(predecessor_range) > address) {
|
||||||
rbtree = predecessor;
|
rbtree = predecessor;
|
||||||
range = predecessor_range;
|
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?
|
// is the range we want to change in the middle of a mapping?
|
||||||
if (address > range->start && top < RANGE_TOP(range)) {
|
if (address > range->start && top < RANGE_TOP(range)) {
|
||||||
// split the mapping
|
// split the mapping
|
||||||
|
|
||||||
// check for write permission if changing a shared file mapping
|
// check for write permission if changing a shared file mapping
|
||||||
if (free == false && (flags & VMM_FLAGS_CREDCHECK) && (range->flags & VMM_FLAGS_SHARED) &&
|
if (free == false && (flags & MM_RANGE_FLAGS_CREDCHECK) && (range->flags & MM_RANGE_FLAGS_SHARED) &&
|
||||||
(range->flags & VMM_FLAGS_FILE) && can_write_vnode(range) == false) {
|
(range->flags & MM_RANGE_FLAGS_FILE) && can_write_vnode(range) == false) {
|
||||||
error = EACCES;
|
error = EACCES;
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
vmmrange_t *split_range = mm_alloc_range();
|
mm_range_t *split_range = mm_alloc_range();
|
||||||
if (range == NULL) {
|
if (range == NULL) {
|
||||||
error = ENOMEM;
|
error = ENOMEM;
|
||||||
goto leave;
|
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;
|
split_range->size = (uintptr_t)RANGE_TOP(range) - (uintptr_t)split_range->start;
|
||||||
range->size = (uintptr_t)address - (uintptr_t)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);
|
VOP_HOLD(range->vnode);
|
||||||
split_range->offset += range->size + size;
|
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);
|
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->vnode = range->vnode;
|
||||||
new_range->offset = range->offset + range->size;
|
new_range->offset = range->offset + range->size;
|
||||||
VOP_HOLD(range->vnode);
|
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
|
// shrink the mapping
|
||||||
|
|
||||||
// permission checking
|
// permission checking
|
||||||
if (free == false && (flags & VMM_FLAGS_CREDCHECK) && (range->flags & VMM_FLAGS_SHARED) &&
|
if (free == false && (flags & MM_RANGE_FLAGS_CREDCHECK) && (range->flags & MM_RANGE_FLAGS_SHARED) &&
|
||||||
(range->flags & VMM_FLAGS_FILE) && can_write_vnode(range) == false) {
|
(range->flags & MM_RANGE_FLAGS_FILE) && can_write_vnode(range) == false) {
|
||||||
error = EACCES;
|
error = EACCES;
|
||||||
goto leave;
|
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);
|
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->vnode = range->vnode;
|
||||||
new_range->offset = range->offset + range->size;
|
new_range->offset = range->offset + range->size;
|
||||||
VOP_HOLD(range->vnode);
|
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)
|
if (rbtree == NULL)
|
||||||
goto leave;
|
goto leave;
|
||||||
|
|
||||||
range = container_of(rbtree, vmmrange_t, rbtree_node);
|
range = container_of(rbtree, mm_range_t, rbtree_node);
|
||||||
if (RANGE_TOP(range) > top)
|
if (RANGE_TOP(range) > top)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -388,8 +387,8 @@ int mm_change_range(vmmspace_t *space, void *address, size_t size, bool free, in
|
|||||||
mm_free_range(range);
|
mm_free_range(range);
|
||||||
} else {
|
} else {
|
||||||
// permission check
|
// permission check
|
||||||
if ((flags & VMM_FLAGS_CREDCHECK) && (range->flags & VMM_FLAGS_SHARED) &&
|
if ((flags & MM_RANGE_FLAGS_CREDCHECK) && (range->flags & MM_RANGE_FLAGS_SHARED) &&
|
||||||
(range->flags & VMM_FLAGS_FILE) && can_write_vnode(range) == false) {
|
(range->flags & MM_RANGE_FLAGS_FILE) && can_write_vnode(range) == false) {
|
||||||
error = EACCES;
|
error = EACCES;
|
||||||
goto leave;
|
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
|
// move the start of the range
|
||||||
|
|
||||||
// permission check
|
// permission check
|
||||||
if (free == false && (flags & VMM_FLAGS_CREDCHECK) && (range->flags & VMM_FLAGS_SHARED) &&
|
if (free == false && (flags & MM_RANGE_FLAGS_CREDCHECK) && (range->flags & MM_RANGE_FLAGS_SHARED) &&
|
||||||
(range->flags & VMM_FLAGS_FILE) && can_write_vnode(range) == false) {
|
(range->flags & MM_RANGE_FLAGS_FILE) && can_write_vnode(range) == false) {
|
||||||
error = EACCES;
|
error = EACCES;
|
||||||
goto leave;
|
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->start = (void *)((uintptr_t)range->start + difference);
|
||||||
range->size -= difference;
|
range->size -= difference;
|
||||||
|
|
||||||
if (range->flags & VMM_FLAGS_FILE)
|
if (range->flags & MM_RANGE_FLAGS_FILE)
|
||||||
range->offset += difference;
|
range->offset += difference;
|
||||||
|
|
||||||
if (free == false) {
|
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);
|
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->vnode = range->vnode;
|
||||||
new_range->offset = range->offset - difference;
|
new_range->offset = range->offset - difference;
|
||||||
VOP_HOLD(range->vnode);
|
VOP_HOLD(range->vnode);
|
||||||
|
|||||||
+11
-11
@@ -1,5 +1,5 @@
|
|||||||
#include <kernel/slab.h>
|
#include <kernel/slab.h>
|
||||||
#include <kernel/vmm.h>
|
#include <kernel/mm.h>
|
||||||
#include <kernel/page.h>
|
#include <kernel/page.h>
|
||||||
#include <logging.h>
|
#include <logging.h>
|
||||||
#include <util.h>
|
#include <util.h>
|
||||||
@@ -47,7 +47,7 @@ static inline bool grow_cache(scache_t *cache) {
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
size_t byte_size = cache->slab_object_count * cache->true_size;
|
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)) {
|
if (unlikely(slab->base == NULL)) {
|
||||||
slab_free(slab_cache, slab);
|
slab_free(slab_cache, slab);
|
||||||
return false;
|
return false;
|
||||||
@@ -68,7 +68,7 @@ static inline bool grow_cache(scache_t *cache) {
|
|||||||
for (int j = 0; j < i; ++j)
|
for (int j = 0; j < i; ++j)
|
||||||
slab_free(indirect_cache, indirect[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);
|
slab_free(slab_cache, slab);
|
||||||
return false;
|
return false;
|
||||||
@@ -454,9 +454,9 @@ static bool magazine_ctor(scache_t *, void *obj) {
|
|||||||
return true;
|
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();
|
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(cache);
|
||||||
__assert(slab_initialize(cache, size, alignment, ctor, dtor));
|
__assert(slab_initialize(cache, size, alignment, ctor, dtor));
|
||||||
return cache;
|
return cache;
|
||||||
@@ -472,7 +472,7 @@ scache_t *slab_create_new_cache_from_pmm(size_t size, size_t alignment, bool (*c
|
|||||||
return cache;
|
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) {
|
void slab_early_init(void) {
|
||||||
size_t magazine_object_size = sizeof(magazine_t) + sizeof(void *) * MAGAZINE_SIZE;
|
size_t magazine_object_size = sizeof(magazine_t) + sizeof(void *) * MAGAZINE_SIZE;
|
||||||
__assert(magazine_object_size < SLAB_INDIRECT_CUTOFF);
|
__assert(magazine_object_size < SLAB_INDIRECT_CUTOFF);
|
||||||
@@ -483,11 +483,11 @@ void slab_early_init(void) {
|
|||||||
void slab_init(void) {
|
void slab_init(void) {
|
||||||
size_t cache_size = sizeof(scache_t) + sizeof(cache_per_cpu_t) * arch_smp_get_cpu_count();
|
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
|
// 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);
|
slab_cache = create_new_from_mm(sizeof(slab_t), 0, NULL, NULL);
|
||||||
indirect_cache = create_new_from_vmm(sizeof(slab_indirect_t), 0, NULL, NULL);
|
indirect_cache = create_new_from_mm(sizeof(slab_indirect_t), 0, NULL, NULL);
|
||||||
indirect_table_cache = create_new_from_vmm(sizeof(slab_indirect_t *) * 32, 0, NULL, NULL);
|
indirect_table_cache = create_new_from_mm(sizeof(slab_indirect_t *) * 32, 0, NULL, NULL);
|
||||||
self_cache = create_new_from_vmm(cache_size, 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);
|
INIT_ROUTINE_DEFINE(slab_early, INIT_ROUTINE_FLAGS_NONE, slab_early_init, mm_page);
|
||||||
|
|||||||
+10
-10
@@ -3,7 +3,7 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <kernel/alloc.h>
|
#include <kernel/alloc.h>
|
||||||
#include <util.h>
|
#include <util.h>
|
||||||
#include <kernel/vmm.h>
|
#include <kernel/mm.h>
|
||||||
#include <kernel/usercopy.h>
|
#include <kernel/usercopy.h>
|
||||||
#include <arch/cpu.h>
|
#include <arch/cpu.h>
|
||||||
|
|
||||||
@@ -67,7 +67,7 @@ static int load(vnode_t *vnode, elfph64_t *ph) {
|
|||||||
size_t firstpagecount = PAGE_SIZE - firstpageoffset;
|
size_t firstpagecount = PAGE_SIZE - firstpageoffset;
|
||||||
firstpagecount = fsize > firstpagecount ? firstpagecount : fsize;
|
firstpagecount = fsize > firstpagecount ? firstpagecount : fsize;
|
||||||
void *page = (void *)ROUND_DOWN(mempos, PAGE_SIZE);
|
void *page = (void *)ROUND_DOWN(mempos, PAGE_SIZE);
|
||||||
if (vmm_map(page, PAGE_SIZE, VMM_FLAGS_EXACT | VMM_FLAGS_ALLOCATE, ARCH_MMU_FLAGS_USER | ARCH_MMU_FLAGS_READ | ARCH_MMU_FLAGS_WRITE, NULL) == NULL)
|
if (mm_map(page, PAGE_SIZE, MM_RANGE_FLAGS_EXACT | MM_RANGE_FLAGS_ALLOCATE, ARCH_MMU_FLAGS_USER | ARCH_MMU_FLAGS_READ | ARCH_MMU_FLAGS_WRITE, NULL) == NULL)
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
|
|
||||||
error = readexact(vnode, (void *)mempos, firstpagecount, foffset);
|
error = readexact(vnode, (void *)mempos, firstpagecount, foffset);
|
||||||
@@ -98,7 +98,7 @@ static int load(vnode_t *vnode, elfph64_t *ph) {
|
|||||||
mempos += remainingmsize;
|
mempos += remainingmsize;
|
||||||
}
|
}
|
||||||
|
|
||||||
error = vmm_changemmuflags(page, PAGE_SIZE, mmuflags, 0);
|
error = mm_change_mmu_flags(page, PAGE_SIZE, mmuflags, 0);
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
@@ -106,11 +106,11 @@ static int load(vnode_t *vnode, elfph64_t *ph) {
|
|||||||
// map middle of file
|
// map middle of file
|
||||||
size_t filepagecount = fsize / PAGE_SIZE;
|
size_t filepagecount = fsize / PAGE_SIZE;
|
||||||
if (filepagecount) {
|
if (filepagecount) {
|
||||||
vmmfiledesc_t vfd = {
|
mm_map_file_desc_t vfd = {
|
||||||
.node = vnode,
|
.node = vnode,
|
||||||
.offset = foffset
|
.offset = foffset
|
||||||
};
|
};
|
||||||
if (vmm_map((void *)mempos, filepagecount, VMM_FLAGS_EXACT | VMM_FLAGS_PAGESIZE | VMM_FLAGS_FILE, mmuflags, &vfd) == NULL)
|
if (mm_map((void *)mempos, filepagecount, MM_RANGE_FLAGS_EXACT | MM_RANGE_FLAGS_PAGESIZE | MM_RANGE_FLAGS_FILE, mmuflags, &vfd) == NULL)
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
size_t bytesize = filepagecount * PAGE_SIZE;
|
size_t bytesize = filepagecount * PAGE_SIZE;
|
||||||
mempos += bytesize;
|
mempos += bytesize;
|
||||||
@@ -122,7 +122,7 @@ static int load(vnode_t *vnode, elfph64_t *ph) {
|
|||||||
// map end of file
|
// map end of file
|
||||||
size_t lastpagecount = fsize % PAGE_SIZE;
|
size_t lastpagecount = fsize % PAGE_SIZE;
|
||||||
if (lastpagecount) {
|
if (lastpagecount) {
|
||||||
if (vmm_map((void *)mempos, PAGE_SIZE, VMM_FLAGS_EXACT | VMM_FLAGS_ALLOCATE, ARCH_MMU_FLAGS_USER | ARCH_MMU_FLAGS_READ | ARCH_MMU_FLAGS_WRITE, NULL) == NULL)
|
if (mm_map((void *)mempos, PAGE_SIZE, MM_RANGE_FLAGS_EXACT | MM_RANGE_FLAGS_ALLOCATE, ARCH_MMU_FLAGS_USER | ARCH_MMU_FLAGS_READ | ARCH_MMU_FLAGS_WRITE, NULL) == NULL)
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
|
|
||||||
error = readexact(vnode, (void *)mempos, lastpagecount, foffset);
|
error = readexact(vnode, (void *)mempos, lastpagecount, foffset);
|
||||||
@@ -135,7 +135,7 @@ static int load(vnode_t *vnode, elfph64_t *ph) {
|
|||||||
|
|
||||||
msize -= msize > PAGE_SIZE ? PAGE_SIZE : msize;
|
msize -= msize > PAGE_SIZE ? PAGE_SIZE : msize;
|
||||||
|
|
||||||
error = vmm_changemmuflags((void *)mempos, PAGE_SIZE, mmuflags, 0);
|
error = mm_change_mmu_flags((void *)mempos, PAGE_SIZE, mmuflags, 0);
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
@@ -144,7 +144,7 @@ static int load(vnode_t *vnode, elfph64_t *ph) {
|
|||||||
|
|
||||||
// zero some parts if needed
|
// zero some parts if needed
|
||||||
if (msize) {
|
if (msize) {
|
||||||
if (vmm_map((void *)mempos, msize, VMM_FLAGS_EXACT, mmuflags, NULL) == NULL)
|
if (mm_map((void *)mempos, msize, MM_RANGE_FLAGS_EXACT, mmuflags, NULL) == NULL)
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -255,12 +255,12 @@ void *elf_preparestack(void *top, auxv64list_t *auxv64, char **argv, char **envp
|
|||||||
|
|
||||||
size_t initialsizeround = ROUND_UP(initialsize, PAGE_SIZE);
|
size_t initialsizeround = ROUND_UP(initialsize, PAGE_SIZE);
|
||||||
void *initialpagebase = (void *)((uintptr_t)top - initialsizeround);
|
void *initialpagebase = (void *)((uintptr_t)top - initialsizeround);
|
||||||
if (vmm_map(initialpagebase, initialsizeround, VMM_FLAGS_ALLOCATE | VMM_FLAGS_EXACT, STACK_MMUFLAGS, NULL) == NULL)
|
if (mm_map(initialpagebase, initialsizeround, MM_RANGE_FLAGS_ALLOCATE | MM_RANGE_FLAGS_EXACT, STACK_MMUFLAGS, NULL) == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
void *stackbase = (void *)((uintptr_t)top - STACK_SIZE);
|
void *stackbase = (void *)((uintptr_t)top - STACK_SIZE);
|
||||||
size_t unallocatedsize = STACK_SIZE - initialsizeround;
|
size_t unallocatedsize = STACK_SIZE - initialsizeround;
|
||||||
if (vmm_map(stackbase, unallocatedsize, VMM_FLAGS_EXACT, STACK_MMUFLAGS, NULL) == NULL)
|
if (mm_map(stackbase, unallocatedsize, MM_RANGE_FLAGS_EXACT, STACK_MMUFLAGS, NULL) == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
top = (void *)((uintptr_t)top - STACK_TOP_BUFFER);
|
top = (void *)((uintptr_t)top - STACK_TOP_BUFFER);
|
||||||
|
|||||||
@@ -367,11 +367,11 @@ void proc_run_init() {
|
|||||||
|
|
||||||
printf("proc: loading %s\n", init_path);
|
printf("proc: loading %s\n", init_path);
|
||||||
|
|
||||||
vmmcontext_t *vmmctx = vmm_newcontext();
|
mm_context_t *mmctx = mm_create_context();
|
||||||
__assert(vmmctx);
|
__assert(mmctx);
|
||||||
|
|
||||||
// leave kernel context to load elf
|
// leave kernel context to load elf
|
||||||
vmm_switchcontext(vmmctx);
|
mm_switch_context(mmctx);
|
||||||
|
|
||||||
proc_t *proc = proc_create();
|
proc_t *proc = proc_create();
|
||||||
__assert(proc);
|
__assert(proc);
|
||||||
@@ -440,7 +440,7 @@ void proc_run_init() {
|
|||||||
__assert(stack);
|
__assert(stack);
|
||||||
|
|
||||||
// reenter kernel context
|
// reenter kernel context
|
||||||
vmm_switchcontext(&vmm_kernelctx);
|
mm_switch_context(&mm_kernel_ctx);
|
||||||
|
|
||||||
thread_t *uthread = sched_newthread(entry, PAGE_SIZE * 16, 1, proc, stack);
|
thread_t *uthread = sched_newthread(entry, PAGE_SIZE * 16, 1, proc, stack);
|
||||||
__assert(uthread);
|
__assert(uthread);
|
||||||
@@ -448,7 +448,7 @@ void proc_run_init() {
|
|||||||
proc->threadlist = uthread;
|
proc->threadlist = uthread;
|
||||||
uthread->procnext = NULL;
|
uthread->procnext = NULL;
|
||||||
|
|
||||||
uthread->vmmctx = vmmctx;
|
uthread->mmctx = mmctx;
|
||||||
sched_queue(uthread);
|
sched_queue(uthread);
|
||||||
|
|
||||||
VOP_RELEASE(initnode);
|
VOP_RELEASE(initnode);
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
#include <logging.h>
|
#include <logging.h>
|
||||||
#include <arch/cpu.h>
|
#include <arch/cpu.h>
|
||||||
#include <spinlock.h>
|
#include <spinlock.h>
|
||||||
#include <kernel/vmm.h>
|
#include <kernel/mm.h>
|
||||||
#include <kernel/alloc.h>
|
#include <kernel/alloc.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <kernel/elf.h>
|
#include <kernel/elf.h>
|
||||||
@@ -25,8 +25,8 @@ static __attribute__((noreturn)) void switch_thread(thread_t *thread) {
|
|||||||
|
|
||||||
current_cpu()->thread = thread;
|
current_cpu()->thread = thread;
|
||||||
|
|
||||||
if(current == NULL || thread->vmmctx != current->vmmctx)
|
if(current == NULL || thread->mmctx != current->mmctx)
|
||||||
vmm_switchcontext(thread->vmmctx);
|
mm_switch_context(thread->mmctx);
|
||||||
|
|
||||||
current_cpu()->intstatus = ARCH_CONTEXT_INTSTATUS(&thread->context);
|
current_cpu()->intstatus = ARCH_CONTEXT_INTSTATUS(&thread->context);
|
||||||
thread->cpu = current_cpu();
|
thread->cpu = current_cpu();
|
||||||
@@ -350,7 +350,7 @@ void sched_ap_entry() {
|
|||||||
dpc_prepare(¤t_cpu()->reschedule_dpc, sched_reschedule_dpc);
|
dpc_prepare(¤t_cpu()->reschedule_dpc, sched_reschedule_dpc);
|
||||||
set_up_bitmaps();
|
set_up_bitmaps();
|
||||||
|
|
||||||
current_cpu()->schedulerstack = vmm_map(NULL, SCHEDULER_STACK_SIZE, VMM_FLAGS_ALLOCATE, ARCH_MMU_FLAGS_READ | ARCH_MMU_FLAGS_WRITE | ARCH_MMU_FLAGS_NOEXEC, NULL);
|
current_cpu()->schedulerstack = mm_map(NULL, SCHEDULER_STACK_SIZE, MM_RANGE_FLAGS_ALLOCATE, ARCH_MMU_FLAGS_READ | ARCH_MMU_FLAGS_WRITE | ARCH_MMU_FLAGS_NOEXEC, NULL);
|
||||||
__assert(current_cpu()->schedulerstack);
|
__assert(current_cpu()->schedulerstack);
|
||||||
current_cpu()->schedulerstack = (void *)((uintptr_t)current_cpu()->schedulerstack + SCHEDULER_STACK_SIZE);
|
current_cpu()->schedulerstack = (void *)((uintptr_t)current_cpu()->schedulerstack + SCHEDULER_STACK_SIZE);
|
||||||
|
|
||||||
@@ -381,7 +381,7 @@ void sched_init() {
|
|||||||
|
|
||||||
__assert(bitmap_init(&sched_idle_cpu_bitmap, arch_smp_get_cpu_count()) == 0);
|
__assert(bitmap_init(&sched_idle_cpu_bitmap, arch_smp_get_cpu_count()) == 0);
|
||||||
|
|
||||||
current_cpu()->schedulerstack = vmm_map(NULL, SCHEDULER_STACK_SIZE, VMM_FLAGS_ALLOCATE, ARCH_MMU_FLAGS_READ | ARCH_MMU_FLAGS_WRITE | ARCH_MMU_FLAGS_NOEXEC, NULL);
|
current_cpu()->schedulerstack = mm_map(NULL, SCHEDULER_STACK_SIZE, MM_RANGE_FLAGS_ALLOCATE, ARCH_MMU_FLAGS_READ | ARCH_MMU_FLAGS_WRITE | ARCH_MMU_FLAGS_NOEXEC, NULL);
|
||||||
__assert(current_cpu()->schedulerstack);
|
__assert(current_cpu()->schedulerstack);
|
||||||
current_cpu()->schedulerstack = (void *)((uintptr_t)current_cpu()->schedulerstack + SCHEDULER_STACK_SIZE);
|
current_cpu()->schedulerstack = (void *)((uintptr_t)current_cpu()->schedulerstack + SCHEDULER_STACK_SIZE);
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
#include <kernel/abi.h>
|
#include <kernel/abi.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <kernel/timekeeper.h>
|
#include <kernel/timekeeper.h>
|
||||||
#include <kernel/vmm.h>
|
#include <kernel/mm.h>
|
||||||
|
|
||||||
syscallret_t syscall_clockget(context_t *, int clockid, timespec_t *tp) {
|
syscallret_t syscall_clockget(context_t *, int clockid, timespec_t *tp) {
|
||||||
syscallret_t ret = {
|
syscallret_t ret = {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
#include <kernel/alloc.h>
|
#include <kernel/alloc.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <kernel/vmm.h>
|
#include <kernel/mm.h>
|
||||||
#include <arch/cpu.h>
|
#include <arch/cpu.h>
|
||||||
#include <kernel/elf.h>
|
#include <kernel/elf.h>
|
||||||
#include <kernel/scheduler.h>
|
#include <kernel/scheduler.h>
|
||||||
@@ -67,8 +67,8 @@ static syscallret_t execve(context_t *context, char *upath, char *uargv[], char
|
|||||||
size_t envsize = 0;
|
size_t envsize = 0;
|
||||||
char **argv = NULL;
|
char **argv = NULL;
|
||||||
char **envp = NULL;
|
char **envp = NULL;
|
||||||
vmmcontext_t *vmmctx = NULL;
|
mm_context_t *mmctx = NULL;
|
||||||
vmmcontext_t *oldctx = current_vmm_context();
|
mm_context_t *oldctx = current_mm_context();
|
||||||
vnode_t *node = NULL;
|
vnode_t *node = NULL;
|
||||||
vnode_t *refnode = NULL;
|
vnode_t *refnode = NULL;
|
||||||
char *interp = NULL;
|
char *interp = NULL;
|
||||||
@@ -237,13 +237,13 @@ static syscallret_t execve(context_t *context, char *upath, char *uargv[], char
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vmmctx = vmm_newcontext();
|
mmctx = mm_create_context();
|
||||||
if (vmmctx == NULL) {
|
if (mmctx == NULL) {
|
||||||
ret.errno = ENOMEM;
|
ret.errno = ENOMEM;
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
vmm_switchcontext(vmmctx);
|
mm_switch_context(mmctx);
|
||||||
|
|
||||||
auxv64list_t auxv64;
|
auxv64list_t auxv64;
|
||||||
void *entry;
|
void *entry;
|
||||||
@@ -321,7 +321,7 @@ static syscallret_t execve(context_t *context, char *upath, char *uargv[], char
|
|||||||
proc->signals.actions[i].address = SIG_IGN;
|
proc->signals.actions[i].address = SIG_IGN;
|
||||||
}
|
}
|
||||||
|
|
||||||
vmm_destroycontext(oldctx);
|
mm_destroy_context(oldctx);
|
||||||
CTX_SP(context) = (uint64_t)stack;
|
CTX_SP(context) = (uint64_t)stack;
|
||||||
CTX_IP(context) = (uint64_t)entry;
|
CTX_IP(context) = (uint64_t)entry;
|
||||||
|
|
||||||
@@ -339,9 +339,9 @@ static syscallret_t execve(context_t *context, char *upath, char *uargv[], char
|
|||||||
if (envp)
|
if (envp)
|
||||||
freevec(envp);
|
freevec(envp);
|
||||||
|
|
||||||
if (vmmctx && ret.errno) {
|
if (mmctx && ret.errno) {
|
||||||
vmm_switchcontext(oldctx);
|
mm_switch_context(oldctx);
|
||||||
vmm_destroycontext(vmmctx);
|
mm_destroy_context(mmctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (refnode)
|
if (refnode)
|
||||||
|
|||||||
@@ -27,9 +27,9 @@ syscallret_t syscall_fork(context_t *ctx) {
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
nthread->vmmctx = vmm_fork(current_thread()->vmmctx);
|
nthread->mmctx = mm_fork_context(current_thread()->mmctx);
|
||||||
|
|
||||||
if (nthread->vmmctx == NULL) {
|
if (nthread->mmctx == NULL) {
|
||||||
ret.errno = ENOMEM;
|
ret.errno = ENOMEM;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#include <kernel/syscalls.h>
|
#include <kernel/syscalls.h>
|
||||||
#include <kernel/slab.h>
|
#include <kernel/slab.h>
|
||||||
#include <kernel/vmm.h>
|
#include <kernel/mm.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <hashtable.h>
|
#include <hashtable.h>
|
||||||
#include <kernel/poll.h>
|
#include <kernel/poll.h>
|
||||||
@@ -66,7 +66,7 @@ syscallret_t syscall_futex(context_t *, uint32_t *futexp, int op, uint32_t value
|
|||||||
if (unlikely(ret.errno))
|
if (unlikely(ret.errno))
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
uint32_t *physical = vmm_getphysical(futexp, 0);
|
uint32_t *physical = mm_get_physical_address(futexp, 0);
|
||||||
futex_t *futex = getfutex(physical);
|
futex_t *futex = getfutex(physical);
|
||||||
|
|
||||||
switch (op) {
|
switch (op) {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#include <kernel/syscalls.h>
|
#include <kernel/syscalls.h>
|
||||||
#include <kernel/file.h>
|
#include <kernel/file.h>
|
||||||
#include <kernel/vmm.h>
|
#include <kernel/mm.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <kernel/alloc.h>
|
#include <kernel/alloc.h>
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#include <kernel/syscalls.h>
|
#include <kernel/syscalls.h>
|
||||||
#include <kernel/abi.h>
|
#include <kernel/abi.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <kernel/vmm.h>
|
#include <kernel/mm.h>
|
||||||
#include <logging.h>
|
#include <logging.h>
|
||||||
|
|
||||||
#define PROT_READ 0x01
|
#define PROT_READ 0x01
|
||||||
@@ -59,21 +59,21 @@ syscallret_t syscall_mmap(context_t *context, void *hint, size_t len, int prot,
|
|||||||
mmuflags |= ARCH_MMU_FLAGS_NOEXEC;
|
mmuflags |= ARCH_MMU_FLAGS_NOEXEC;
|
||||||
|
|
||||||
bool isfile = (flags & MAP_ANONYMOUS) == 0;
|
bool isfile = (flags & MAP_ANONYMOUS) == 0;
|
||||||
int vmmflags = 0;
|
int mm_flags = 0;
|
||||||
|
|
||||||
if (flags & MAP_FIXED)
|
if (flags & MAP_FIXED)
|
||||||
vmmflags |= VMM_FLAGS_REPLACE;
|
mm_flags |= MM_RANGE_FLAGS_REPLACE;
|
||||||
|
|
||||||
if (flags & MAP_FIXED_NOREPLACE)
|
if (flags & MAP_FIXED_NOREPLACE)
|
||||||
vmmflags |= VMM_FLAGS_EXACT;
|
mm_flags |= MM_RANGE_FLAGS_EXACT;
|
||||||
|
|
||||||
if ((flags & MAP_ANONYMOUS) == 0)
|
if ((flags & MAP_ANONYMOUS) == 0)
|
||||||
vmmflags |= VMM_FLAGS_FILE;
|
mm_flags |= MM_RANGE_FLAGS_FILE;
|
||||||
|
|
||||||
if (flags & MAP_SHARED)
|
if (flags & MAP_SHARED)
|
||||||
vmmflags |= VMM_FLAGS_SHARED;
|
mm_flags |= MM_RANGE_FLAGS_SHARED;
|
||||||
|
|
||||||
vmmfiledesc_t vfd;
|
mm_map_file_desc_t vfd;
|
||||||
file_t *file = NULL;
|
file_t *file = NULL;
|
||||||
if (isfile) {
|
if (isfile) {
|
||||||
// make sure offset is page aligned
|
// make sure offset is page aligned
|
||||||
@@ -99,7 +99,7 @@ syscallret_t syscall_mmap(context_t *context, void *hint, size_t len, int prot,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// if the vnode is not cacheable, we need to make sure we can map it
|
// if the vnode is not cacheable, we need to make sure we can map it
|
||||||
// TODO move this check to vmm_map once the return value of mmap is fixed to return an errno
|
// TODO move this check to mm_map once the return value of mmap is fixed to return an errno
|
||||||
if (vfs_iscacheable(file->vnode) == false) {
|
if (vfs_iscacheable(file->vnode) == false) {
|
||||||
ret.errno = VOP_MMAP(file->vnode, VOP_MMAP_ADDRESS_MMAP_SUPPORTED, 0, 0, NULL);
|
ret.errno = VOP_MMAP(file->vnode, VOP_MMAP_ADDRESS_MMAP_SUPPORTED, 0, 0, NULL);
|
||||||
if (ret.errno)
|
if (ret.errno)
|
||||||
@@ -113,7 +113,7 @@ syscallret_t syscall_mmap(context_t *context, void *hint, size_t len, int prot,
|
|||||||
if (hint < USERSPACE_START)
|
if (hint < USERSPACE_START)
|
||||||
hint = USERSPACE_MMAP_START;
|
hint = USERSPACE_MMAP_START;
|
||||||
|
|
||||||
ret.ret = (uint64_t)vmm_map(hint, len, vmmflags, mmuflags, &vfd);
|
ret.ret = (uint64_t)mm_map(hint, len, mm_flags, mmuflags, &vfd);
|
||||||
if (ret.ret == 0)
|
if (ret.ret == 0)
|
||||||
ret.errno = ENOMEM;
|
ret.errno = ENOMEM;
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#include <kernel/syscalls.h>
|
#include <kernel/syscalls.h>
|
||||||
#include <kernel/vmm.h>
|
#include <kernel/mm.h>
|
||||||
#include <kernel/alloc.h>
|
#include <kernel/alloc.h>
|
||||||
#include <kernel/vfs.h>
|
#include <kernel/vfs.h>
|
||||||
#include <logging.h>
|
#include <logging.h>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#include <kernel/syscalls.h>
|
#include <kernel/syscalls.h>
|
||||||
#include <kernel/abi.h>
|
#include <kernel/abi.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <kernel/vmm.h>
|
#include <kernel/mm.h>
|
||||||
#include <logging.h>
|
#include <logging.h>
|
||||||
|
|
||||||
#define PROT_READ 0x01
|
#define PROT_READ 0x01
|
||||||
@@ -37,7 +37,7 @@ syscallret_t syscall_mprotect(context_t *context, void *address, size_t len, int
|
|||||||
if ((prot & PROT_EXEC) == 0)
|
if ((prot & PROT_EXEC) == 0)
|
||||||
mmuflags |= ARCH_MMU_FLAGS_NOEXEC;
|
mmuflags |= ARCH_MMU_FLAGS_NOEXEC;
|
||||||
|
|
||||||
ret.errno = vmm_changemmuflags(address, len, mmuflags, VMM_FLAGS_CREDCHECK);
|
ret.errno = mm_change_mmu_flags(address, len, mmuflags, MM_RANGE_FLAGS_CREDCHECK);
|
||||||
ret.ret = ret.errno ? -1 : 0;
|
ret.ret = ret.errno ? -1 : 0;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#include <kernel/syscalls.h>
|
#include <kernel/syscalls.h>
|
||||||
#include <kernel/vmm.h>
|
#include <kernel/mm.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
syscallret_t syscall_munmap(context_t *ctx, void *addr, size_t length) {
|
syscallret_t syscall_munmap(context_t *ctx, void *addr, size_t length) {
|
||||||
@@ -18,7 +18,7 @@ syscallret_t syscall_munmap(context_t *ctx, void *addr, size_t length) {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
vmm_unmap(addr, length, 0);
|
mm_unmap(addr, length, 0);
|
||||||
|
|
||||||
ret.ret = 0;
|
ret.ret = 0;
|
||||||
ret.errno = 0;
|
ret.errno = 0;
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ syscallret_t syscall_newthread(context_t *, void *entry, void *stack) {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
thread->vmmctx = current_thread()->vmmctx;
|
thread->mmctx = current_thread()->mmctx;
|
||||||
|
|
||||||
bool intstatus = interrupt_set(false);
|
bool intstatus = interrupt_set(false);
|
||||||
spinlock_acquire(&proc->threadlistlock);
|
spinlock_acquire(&proc->threadlistlock);
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#include <kernel/syscalls.h>
|
#include <kernel/syscalls.h>
|
||||||
#include <kernel/file.h>
|
#include <kernel/file.h>
|
||||||
#include <kernel/poll.h>
|
#include <kernel/poll.h>
|
||||||
#include <kernel/vmm.h>
|
#include <kernel/mm.h>
|
||||||
#include <logging.h>
|
#include <logging.h>
|
||||||
#include <kernel/alloc.h>
|
#include <kernel/alloc.h>
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#include <kernel/syscalls.h>
|
#include <kernel/syscalls.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <kernel/vmm.h>
|
#include <kernel/mm.h>
|
||||||
#include <kernel/timer.h>
|
#include <kernel/timer.h>
|
||||||
#include <arch/cpu.h>
|
#include <arch/cpu.h>
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ thread_t *sched_newthread(void *ip, size_t kstacksize, int nice, proc_t *proc, v
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
thread->kernelstack = vmm_map(NULL, kstacksize, VMM_FLAGS_ALLOCATE, ARCH_MMU_FLAGS_WRITE | ARCH_MMU_FLAGS_READ | ARCH_MMU_FLAGS_NOEXEC, NULL);
|
thread->kernelstack = mm_map(NULL, kstacksize, MM_RANGE_FLAGS_ALLOCATE, ARCH_MMU_FLAGS_WRITE | ARCH_MMU_FLAGS_READ | ARCH_MMU_FLAGS_NOEXEC, NULL);
|
||||||
if (thread->kernelstack == NULL) {
|
if (thread->kernelstack == NULL) {
|
||||||
arch_extracontext_free(&thread->extracontext);
|
arch_extracontext_free(&thread->extracontext);
|
||||||
slab_free(thread_cache, thread);
|
slab_free(thread_cache, thread);
|
||||||
@@ -32,8 +32,8 @@ thread_t *sched_newthread(void *ip, size_t kstacksize, int nice, proc_t *proc, v
|
|||||||
|
|
||||||
thread->kernelstacktop = (void *)((uintptr_t)thread->kernelstack + kstacksize);
|
thread->kernelstacktop = (void *)((uintptr_t)thread->kernelstack + kstacksize);
|
||||||
|
|
||||||
// non kernel thread vmm contexts are handled by the caller
|
// non kernel thread mm contexts are handled by the caller
|
||||||
thread->vmmctx = proc ? NULL : &vmm_kernelctx;
|
thread->mmctx = proc ? NULL : &mm_kernel_ctx;
|
||||||
thread->proc = proc;
|
thread->proc = proc;
|
||||||
thread->kernelstacksize = kstacksize;
|
thread->kernelstacksize = kstacksize;
|
||||||
thread->nice = nice;
|
thread->nice = nice;
|
||||||
@@ -57,7 +57,7 @@ thread_t *sched_newthread(void *ip, size_t kstacksize, int nice, proc_t *proc, v
|
|||||||
}
|
}
|
||||||
|
|
||||||
void sched_destroythread(thread_t *thread) {
|
void sched_destroythread(thread_t *thread) {
|
||||||
vmm_unmap(thread->kernelstack, thread->kernelstacksize, 0);
|
mm_unmap(thread->kernelstack, thread->kernelstacksize, 0);
|
||||||
arch_extracontext_free(&thread->extracontext);
|
arch_extracontext_free(&thread->extracontext);
|
||||||
slab_free(thread_cache, thread);
|
slab_free(thread_cache, thread);
|
||||||
}
|
}
|
||||||
@@ -84,18 +84,18 @@ __attribute__((noreturn)) void sched_threadexit() {
|
|||||||
thread_t *thread = current_thread();
|
thread_t *thread = current_thread();
|
||||||
proc_t *proc = thread->proc;
|
proc_t *proc = thread->proc;
|
||||||
|
|
||||||
vmmcontext_t *oldctx = thread->vmmctx;
|
mm_context_t *oldctx = thread->mmctx;
|
||||||
vmm_switchcontext(&vmm_kernelctx);
|
mm_switch_context(&mm_kernel_ctx);
|
||||||
|
|
||||||
if (proc) {
|
if (proc) {
|
||||||
__atomic_fetch_sub(&proc->runningthreadcount, 1, __ATOMIC_SEQ_CST);
|
__atomic_fetch_sub(&proc->runningthreadcount, 1, __ATOMIC_SEQ_CST);
|
||||||
__assert(oldctx != &vmm_kernelctx);
|
__assert(oldctx != &mm_kernel_ctx);
|
||||||
if (proc->runningthreadcount == 0) {
|
if (proc->runningthreadcount == 0) {
|
||||||
if (thread->shouldexit)
|
if (thread->shouldexit)
|
||||||
proc->status = -1;
|
proc->status = -1;
|
||||||
|
|
||||||
proc_exit();
|
proc_exit();
|
||||||
vmm_destroycontext(oldctx);
|
mm_destroy_context(oldctx);
|
||||||
PROC_RELEASE(proc);
|
PROC_RELEASE(proc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user