[Zion] Add a AddressSpaceUnmap syscall to free memory.

This commit is contained in:
Drew Galbraith 2023-11-19 18:55:44 -08:00
parent e668428d9d
commit 30b6511467
9 changed files with 60 additions and 18 deletions

View File

@ -74,32 +74,32 @@ void BinaryTree<K, V>::Delete(K key) {
}
RefPtr<BinaryNode> new_child = nullptr;
if (!node.left) {
if (!node->left) {
// No children.
// Right child only.
new_child = node.right;
} else if (!node.right) {
new_child = node->right;
} else if (!node->right) {
// Left child only.
new_child = node.left;
new_child = node->left;
} else {
// Find Successor.
auto successor = node.right;
while (successor.left) {
successor = successor.left;
auto successor = node->right;
while (successor->left) {
successor = successor->left;
}
new_child = successor;
if (successor != node.right) {
successor.parent.left = successor.right;
if (successor != node->right) {
successor->parent->left = successor->right;
}
}
if (node == root_) {
root_ = new_child;
} else {
if (node.parent.right == node) {
node.parent.right = new_child;
if (node->parent->right == node) {
node->parent->right = new_child;
} else {
node.parent.left = new_child;
node->parent->left = new_child;
}
}
}

View File

@ -11,6 +11,7 @@ add_executable(zion
interrupt/interrupt.cpp
interrupt/interrupt_enter.s
interrupt/timer.cpp
lib/memory_mapping_tree.cpp
lib/message_queue.cpp
loader/init_loader.cpp
memory/kernel_heap.cpp

View File

@ -19,6 +19,8 @@ SYS1(ThreadWait, z_cap_t, thread_cap);
SYS4(AddressSpaceMap, z_cap_t, vmas_cap, uint64_t, vmas_offset, z_cap_t,
vmmo_cap, uint64_t*, vaddr);
SYS3(AddressSpaceUnmap, z_cap_t, vmas_cap, uint64_t, lower_addr, uint64_t,
upper_addr);
SYS2(MemoryObjectCreate, uint64_t, size, z_cap_t*, vmmo_cap);
SYS3(MemoryObjectCreatePhysical, uint64_t, paddr, uint64_t, size, z_cap_t*,

View File

@ -21,7 +21,7 @@ const uint64_t kZionThreadWait = 0x13;
// Memory Calls
const uint64_t kZionAddressSpaceMap = 0x21;
const uint64_t kZionAddressSpaceUnMap = 0x21;
const uint64_t kZionAddressSpaceUnmap = 0x22;
const uint64_t kZionMemoryObjectCreate = 0x30;
const uint64_t kZionMemoryObjectCreatePhysical = 0x31;

View File

@ -28,9 +28,32 @@ glcr::ErrorCode MemoryMappingTree::AddInMemoryObject(
return glcr::OK;
}
glcr::ErrorCode FreeMemoryRange(uint64_t vaddr_base, uint64_t vaddr_limit) {
dbgln("Unhandled free memory range!");
return glcr::OK;
glcr::ErrorCode MemoryMappingTree::FreeMemoryRange(uint64_t vaddr_base,
uint64_t vaddr_limit) {
if (vaddr_limit <= vaddr_base) {
return glcr::INVALID_ARGUMENT;
}
auto predecessor_or = mapping_tree_.Predecessor(vaddr_base);
if (predecessor_or && predecessor_or.value().get().vaddr_limit > vaddr_base) {
return glcr::FAILED_PRECONDITION;
}
auto last_predecessor_or = mapping_tree_.Predecessor(vaddr_limit);
if (last_predecessor_or &&
last_predecessor_or.value().get().vaddr_limit > vaddr_limit) {
return glcr::FAILED_PRECONDITION;
}
auto find_or = mapping_tree_.Find(vaddr_base);
if (find_or) {
mapping_tree_.Delete(vaddr_base);
}
while (true) {
auto successor_or = mapping_tree_.Successor(vaddr_base);
if (!successor_or || successor_or.value().get().vaddr_base >= vaddr_limit) {
return glcr::OK;
}
mapping_tree_.Delete(successor_or.value().get().vaddr_base);
}
}
glcr::ErrorOr<uint64_t> MemoryMappingTree::GetPhysicalPageAtVaddr(

View File

@ -76,6 +76,11 @@ class AddressSpace : public KernelObject {
[[nodiscard]] glcr::ErrorOr<uint64_t> MapInMemoryObject(
const glcr::RefPtr<MemoryObject>& mem_obj);
[[nodiscard]] glcr::ErrorCode FreeAddressRange(uint64_t vaddr_base,
uint64_t vaddr_limit) {
return mapping_tree_.FreeMemoryRange(vaddr_base, vaddr_limit);
}
// Kernel Mappings.
uint64_t AllocateKernelStack();

View File

@ -15,10 +15,19 @@ z_err_t AddressSpaceMap(ZAddressSpaceMapReq* req) {
// FIXME: Validation necessary.
if (req->vmas_offset != 0) {
vmas->MapInMemoryObject(req->vmas_offset, vmmo);
RET_ERR(vmas->MapInMemoryObject(req->vmas_offset, vmmo));
*req->vaddr = req->vmas_offset;
} else {
*req->vaddr = vmas->MapInMemoryObject(vmmo);
ASSIGN_OR_RETURN(*req->vaddr, vmas->MapInMemoryObject(vmmo));
}
return glcr::OK;
}
z_err_t AddressSpaceUnmap(ZAddressSpaceUnmapReq* req) {
auto& curr_proc = gScheduler->CurrentProcess();
auto vmas_cap = curr_proc.GetCapability(req->vmas_cap);
RET_ERR(ValidateCapability<AddressSpace>(vmas_cap, kZionPerm_Write));
auto vmas = vmas_cap->obj<AddressSpace>();
return vmas->FreeAddressRange(req->lower_addr, req->upper_addr);
}

View File

@ -3,3 +3,4 @@
#include "include/zcall.h"
z_err_t AddressSpaceMap(ZAddressSpaceMapReq* req);
z_err_t AddressSpaceUnmap(ZAddressSpaceUnmapReq* req);

View File

@ -60,6 +60,7 @@ extern "C" z_err_t SyscallHandler(uint64_t call_id, void* req) {
CASE(ThreadWait);
// syscall/address_space.h
CASE(AddressSpaceMap);
CASE(AddressSpaceUnmap);
// syscall/memory_object.h
CASE(MemoryObjectCreate);
CASE(MemoryObjectCreatePhysical);