Luna/kernel/src/sys/allocate_memory.cpp
apio 139c0b5eb1
Kernel: Make a UserVM wrapper around Bitmap and use that to allocate user VM
This lets us allocate more than one page of memory from the user side.
2023-01-13 19:05:20 +01:00

54 lines
1.5 KiB
C++

#include "Log.h"
#include "arch/MMU.h"
#include "memory/MemoryManager.h"
#include "sys/Syscall.h"
#include "thread/Scheduler.h"
#include <bits/mmap-flags.h>
#include <luna/Alignment.h>
constexpr uintptr_t USERSPACE_HEAP_BASE = 0x3000000;
Result<u64> sys_allocate_memory(Registers*, SyscallArgs args)
{
usize size = (usize)args[0];
int flags = (int)args[1];
if (flags < 0) return err(EINVAL);
if (size == 0) return 0;
size = align_up<ARCH_PAGE_SIZE>(size);
Thread* current = Scheduler::current();
u64 address = TRY(current->vm_allocator->alloc_several_pages(size / ARCH_PAGE_SIZE));
int mmu_flags = MMU::User | MMU::NoExecute;
if (flags & PROT_WRITE) mmu_flags |= MMU::ReadWrite;
if (flags & PROT_EXEC) mmu_flags &= ~MMU::NoExecute;
if (flags == PROT_NONE) mmu_flags = MMU::NoExecute;
kdbgln("allocate_memory: allocating memory at %#lx, size=%zu", address, size);
return MemoryManager::alloc_at(address, size / ARCH_PAGE_SIZE, mmu_flags);
}
Result<u64> sys_deallocate_memory(Registers*, SyscallArgs args)
{
u64 address = (u64)args[0];
usize size = (usize)args[1];
if (size == 0) return 0;
size = align_up<ARCH_PAGE_SIZE>(size);
Thread* current = Scheduler::current();
TRY(current->vm_allocator->free_several_pages(address, size / ARCH_PAGE_SIZE));
kdbgln("deallocate_memory: deallocating memory at %#lx, size=%zu", address, size);
TRY(MemoryManager::unmap_owned(address, size / ARCH_PAGE_SIZE));
return { 0 };
}