summaryrefslogtreecommitdiff
path: root/kernel/memory/virtalloc.c
diff options
context:
space:
mode:
authorFreya Murphy <freya@freyacat.org>2025-04-25 10:02:29 -0400
committerFreya Murphy <freya@freyacat.org>2025-04-25 10:06:00 -0400
commit7876e466c222ed015bc65c7ab4f63d05596ede2c (patch)
treea4f541a79a06b612e8b8846414e880b281c439a0 /kernel/memory/virtalloc.c
parentmake alloc_pages_at() able to allocate noncontiguous physical pages (diff)
downloadcomus-7876e466c222ed015bc65c7ab4f63d05596ede2c.tar.gz
comus-7876e466c222ed015bc65c7ab4f63d05596ede2c.tar.bz2
comus-7876e466c222ed015bc65c7ab4f63d05596ede2c.zip
virt ctx clone
Diffstat (limited to 'kernel/memory/virtalloc.c')
-rw-r--r--kernel/memory/virtalloc.c34
1 files changed, 34 insertions, 0 deletions
diff --git a/kernel/memory/virtalloc.c b/kernel/memory/virtalloc.c
index 3690eae..a077532 100644
--- a/kernel/memory/virtalloc.c
+++ b/kernel/memory/virtalloc.c
@@ -96,6 +96,40 @@ void virtaddr_init(struct virt_ctx *ctx)
ctx->is_allocating = false;
}
+int virtaddr_clone(struct virt_ctx *old, struct virt_ctx *new)
+{
+ // copy over data
+ memcpy(new, old, sizeof(struct virt_ctx));
+
+ // allocate new space
+ new->alloc_nodes = kalloc(sizeof(struct virt_addr_node) * new->alloc_node_count);
+ if (new->alloc_nodes == NULL)
+ return 1;
+
+ // update prev/next in new allocation space
+ update_node_ptrs(old->alloc_nodes, new->alloc_nodes, old->alloc_node_count, new->alloc_node_count);
+
+ // update bootstrap nodes
+ for (size_t i = 0; i < new->used_node_count; i++) {
+ struct virt_addr_node *prev, *next;
+
+ if (i >= BOOTSTRAP_VIRT_ALLOC_NODES)
+ break;
+
+ // get prev
+ prev = i > 0 ? &new->bootstrap_nodes[i-1] : NULL;
+ next = i < BOOTSTRAP_VIRT_ALLOC_NODES - 1 ? &new->bootstrap_nodes[i+1] : NULL;
+
+ new->bootstrap_nodes[i].prev = prev;
+ new->bootstrap_nodes[i].next = next;
+ }
+
+ // get starting node
+ new->start_node = &new->bootstrap_nodes[0]; // for now
+
+ return 0;
+}
+
static void merge_back(struct virt_ctx *ctx, struct virt_addr_node *node)
{
while (node->prev) {