aboutsummaryrefslogtreecommitdiff
path: root/arch/riscv64/kernel/vmem.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/riscv64/kernel/vmem.c')
-rw-r--r--arch/riscv64/kernel/vmem.c43
1 files changed, 22 insertions, 21 deletions
diff --git a/arch/riscv64/kernel/vmem.c b/arch/riscv64/kernel/vmem.c
index 4986c1f..bd7906b 100644
--- a/arch/riscv64/kernel/vmem.c
+++ b/arch/riscv64/kernel/vmem.c
@@ -297,6 +297,9 @@ stat_t map_vpage(struct vmem *branch, pm_t paddr, vm_t vaddr, vmflags_t flags,
while (top != order) {
size_t idx = vm_to_index(vaddr, top);
+ /* what if we create one high-level page and a low-level page
+ * doesn't have enough memory? I think that situation would fail
+ * the unit tests I currently have */
if (__unused((pm_t)branch->leaf[idx])) {
struct vmem *leaf = __create_leaf();
if (!leaf)
@@ -602,25 +605,28 @@ stat_t setup_rpc_stack(struct tcb *t)
vmflags_t flags = VM_V | VM_R | VM_W;
/* note how VM_U is missing, userspace messing about will be done later */
- for (size_t i = 0; i < rpc_pages; ++i) {
- pm_t page = alloc_page(BASE_PAGE);
- if (!page)
- return ERR_OOMEM;
+ pm_t page = alloc_page(MM_O1);
+ if (!page)
+ return ERR_OOMEM;
- if (map_vpage(t->rpc.vmem, page,
- RPC_STACK_BASE + BASE_PAGE_SIZE * i,
- flags, BASE_PAGE))
- return ERR_OOMEM;
+ if (map_vpage(t->rpc.vmem, page, RPC_STACK_BASE, flags, BASE_PAGE)) {
+ free_page(MM_O1, page);
+ return ERR_OOMEM;
}
- /* we allocated a second order page for rpc stack usage */
- t->rpc_stack = RPC_STACK_BASE + order_size(MM_O1);
-
- /* slightly hacky maybe but we know the first pte is at RPC_STACK_BASE,
- * which means that it must also be the leaf */
t->arch.rpc_leaf = (struct vmem *)__find_vmem(t->rpc.vmem,
RPC_STACK_BASE,
NULL);
+
+ for (size_t i = 0; i < rpc_pages; ++i) {
+ t->arch.rpc_leaf->leaf[i] = (struct vmem *)to_pte(
+ (pm_t)__pa(page + i * BASE_PAGE_SIZE),
+ vp_flags(flags)
+ );
+ }
+
+ t->rpc_stack = RPC_STACK_BASE + order_size(MM_O1);
+
/* we count downward in base pages, the top page is *always* reserved */
t->arch.rpc_idx = rpc_pages - 1;
/** @todo we could mark the first stack page accessible here already */
@@ -632,14 +638,9 @@ stat_t setup_rpc_stack(struct tcb *t)
void destroy_rpc_stack(struct tcb *t)
{
- for (size_t i = 0; i < rpc_pages; ++i) {
- pm_t page = 0; enum mm_order order = BASE_PAGE;
- if (stat_vpage(t->rpc.vmem, RPC_STACK_BASE + BASE_PAGE_SIZE * i,
- &page, &order, NULL))
- return;
-
- free_page(order, page);
- }
+ pm_t *pte = (pm_t *)t->arch.rpc_leaf;
+ pm_t page = (pm_t)pte_addr(*pte);
+ free_page(MM_O1, page);
}
void reset_rpc_stack(struct tcb *t)