From 9a7dbf05942474a53e526b367f8fd9c01bc72d2a Mon Sep 17 00:00:00 2001 From: kamkow1 Date: Fri, 16 Jan 2026 22:09:16 +0100 Subject: [PATCH] Properly implement liballoc_free () --- include/m/syscall_defs.h | 2 ++ kernel/proc/mem.c | 17 ++++++++++++ kernel/proc/mem.h | 23 +++++++++++++++++ kernel/proc/mutex.c | 14 +++++----- kernel/proc/mutex.h | 5 ++-- kernel/proc/resource.c | 4 ++- kernel/proc/resource.h | 11 ++------ kernel/proc/src.mk | 6 +++-- kernel/syscall/syscall.c | 56 ++++++++++++++++++++++++++++++++++++++++ libmsl/alloc/liballoc.c | 17 ++++++++++-- libmsl/m/proc.c | 8 ++++++ libmsl/m/proc.h | 3 ++- 12 files changed, 142 insertions(+), 24 deletions(-) create mode 100644 kernel/proc/mem.c create mode 100644 kernel/proc/mem.h diff --git a/include/m/syscall_defs.h b/include/m/syscall_defs.h index fcf91bd..be4122d 100644 --- a/include/m/syscall_defs.h +++ b/include/m/syscall_defs.h @@ -12,5 +12,7 @@ #define SYS_PROC_MUTEX_UNLOCK 9 #define SYS_PROC_SPAWN_THREAD 10 #define SYS_PROC_SCHED 11 +#define SYS_PROC_TRANSLATE_V2P 12 +#define SYS_PROC_MEM_UNREF 13 #endif // _M_SYSCALL_DEFS_H diff --git a/kernel/proc/mem.c b/kernel/proc/mem.c new file mode 100644 index 0000000..7f4b9ff --- /dev/null +++ b/kernel/proc/mem.c @@ -0,0 +1,17 @@ +#include +#include +#include +#include +#include + +void proc_mem_unref (struct proc* proc, struct proc_resource_mem* mem, size_t pages) { + spin_lock_ctx_t ctxrs; + + spin_lock (&mem->resource->lock, &ctxrs); + mem->alive_pages -= pages; + ptrdiff_t current_pages = mem->alive_pages; + spin_unlock (&mem->resource->lock, &ctxrs); + + if (current_pages <= 0) + proc_drop_resource (proc, mem->resource); +} diff --git a/kernel/proc/mem.h b/kernel/proc/mem.h new file mode 100644 index 0000000..121fd16 --- /dev/null +++ b/kernel/proc/mem.h @@ -0,0 +1,23 @@ +#ifndef _KERNEL_PROC_MEM_H +#define _KERNEL_PROC_MEM_H + +#include + +struct proc; +struct proc_resource; + +struct proc_resource_mem { + struct proc_resource* resource; + + uintptr_t paddr; + size_t pages; + ptrdiff_t alive_pages; +}; + +struct proc_resource_mem_init { + size_t pages; +}; + +void proc_mem_unref (struct proc* proc, struct proc_resource_mem* mem, size_t pages); + +#endif // _KERNEL_PROC_MEM_H diff --git a/kernel/proc/mutex.c b/kernel/proc/mutex.c index 5403d35..d185140 100644 --- a/kernel/proc/mutex.c +++ b/kernel/proc/mutex.c @@ -10,16 +10,16 @@ void proc_mutex_lock (struct proc* proc, struct proc_mutex* mutex) { spin_lock_ctx_t ctxmt; try: - spin_lock (&mutex->lock, &ctxmt); + spin_lock (&mutex->resource->lock, &ctxmt); if (!mutex->locked || mutex->owner == proc) { mutex->locked = true; mutex->owner = proc; - spin_unlock (&mutex->lock, &ctxmt); + spin_unlock (&mutex->resource->lock, &ctxmt); return; } - spin_unlock (&mutex->lock, &ctxmt); + spin_unlock (&mutex->resource->lock, &ctxmt); proc_suspend (proc, &mutex->suspension_q); @@ -29,10 +29,10 @@ try: bool proc_mutex_unlock (struct proc* proc, struct proc_mutex* mutex) { spin_lock_ctx_t ctxmt, ctxsq; - spin_lock (&mutex->lock, &ctxmt); + spin_lock (&mutex->resource->lock, &ctxmt); if (mutex->owner != proc) { - spin_unlock (&mutex->lock, &ctxmt); + spin_unlock (&mutex->resource->lock, &ctxmt); return false; } @@ -47,7 +47,7 @@ bool proc_mutex_unlock (struct proc* proc, struct proc_mutex* mutex) { mutex->owner = resumed_proc; spin_unlock (&mutex->suspension_q.lock, &ctxsq); - spin_unlock (&mutex->lock, &ctxmt); + spin_unlock (&mutex->resource->lock, &ctxmt); proc_resume (resumed_proc); return true; @@ -58,7 +58,7 @@ bool proc_mutex_unlock (struct proc* proc, struct proc_mutex* mutex) { mutex->locked = false; mutex->owner = NULL; - spin_unlock (&mutex->lock, &ctxmt); + spin_unlock (&mutex->resource->lock, &ctxmt); return true; } diff --git a/kernel/proc/mutex.h b/kernel/proc/mutex.h index 79e1a9b..d142b37 100644 --- a/kernel/proc/mutex.h +++ b/kernel/proc/mutex.h @@ -3,12 +3,13 @@ #include #include -#include struct proc; +struct proc_resource; struct proc_mutex { - spin_lock_t lock; + struct proc_resource* resource; + bool locked; struct proc_suspension_q suspension_q; struct proc* owner; diff --git a/kernel/proc/resource.c b/kernel/proc/resource.c index 124fba5..482db4d 100644 --- a/kernel/proc/resource.c +++ b/kernel/proc/resource.c @@ -52,7 +52,7 @@ static bool proc_create_resource_mem (struct proc_resource_mem* mem, return false; mem->paddr = paddr; - mem->pages = init->pages; + mem->pages = mem->alive_pages = init->pages; return true; } @@ -101,12 +101,14 @@ struct proc_resource* proc_create_resource (struct proc* proc, int rid, int type struct proc_resource_mem_init* mem_init = data; proc_create_resource_mem (&resource->u.mem, mem_init); resource->ops.cleanup = &proc_cleanup_resource_mem; + resource->u.mem.resource = resource; DEBUG ("PR_MEM resource=%p type=%d rid=%d paddr=%p, pages=%zu\n", resource, resource->type, resource->rid, resource->u.mem.paddr, resource->u.mem.pages); } break; case PR_MUTEX: { proc_create_resource_mutex (&resource->u.mutex); resource->ops.cleanup = &proc_cleanup_resource_mutex; + resource->u.mutex.resource = resource; DEBUG ("PR_MUTEX resource=%p, type=%d rid=%d\n", resource, resource->type, resource->rid); } break; default: { diff --git a/kernel/proc/resource.h b/kernel/proc/resource.h index 9535487..1c31d59 100644 --- a/kernel/proc/resource.h +++ b/kernel/proc/resource.h @@ -3,6 +3,7 @@ #include #include +#include #include #include @@ -13,15 +14,7 @@ #define RV_PUBLIC 1 struct proc; - -struct proc_resource_mem { - uintptr_t paddr; - size_t pages; -}; - -struct proc_resource_mem_init { - size_t pages; -}; +struct proc_resource; struct proc_resource { int type; diff --git a/kernel/proc/src.mk b/kernel/proc/src.mk index db5603a..6e5fd28 100644 --- a/kernel/proc/src.mk +++ b/kernel/proc/src.mk @@ -1,7 +1,9 @@ c += proc/proc.c \ proc/resource.c \ - proc/mutex.c + proc/mutex.c \ + proc/mem.c o += proc/proc.o \ proc/resource.o \ - proc/mutex.o + proc/mutex.o \ + proc/mem.o diff --git a/kernel/syscall/syscall.c b/kernel/syscall/syscall.c index 001e4fe..e6bd31e 100644 --- a/kernel/syscall/syscall.c +++ b/kernel/syscall/syscall.c @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -130,6 +131,7 @@ DEFINE_SYSCALL (sys_proc_mutex_lock) { return ST_OK; } +/* int proc_mutex_unlock (int mutex_rid) */ DEFINE_SYSCALL (sys_proc_mutex_unlock) { spin_lock_ctx_t ctxpr; int rid = (int)a1; @@ -200,6 +202,58 @@ DEFINE_SYSCALL (sys_proc_sched) { return ST_OK; } +DEFINE_SYSCALL (sys_proc_translate_v2p) { + struct limine_hhdm_response* hhdm = limine_hhdm_request.response; + spin_lock_ctx_t ctxprpd; + int result = ST_OK; + + uintptr_t vaddr = a1; + uintptr_t* out_paddr_buf = (uintptr_t*)a2; + + spin_lock (&proc->pd->lock, &ctxprpd); + + uintptr_t out_paddr_buf_paddr = mm_v2p (proc->pd, (uintptr_t)out_paddr_buf, 0); + + if (!mm_validate_buffer (proc->pd, (uintptr_t)out_paddr_buf, sizeof (uintptr_t), 0)) { + spin_unlock (&proc->pd->lock, &ctxprpd); + return -ST_BAD_ADDRESS_SPACE; + } + + uintptr_t* out_paddr_buf_vaddr = (uintptr_t*)((uintptr_t)hhdm->offset + out_paddr_buf_paddr); + + uintptr_t translated_addr = mm_v2p (proc->pd, vaddr, 0); + if (translated_addr == 0) { + result = -ST_BAD_ADDRESS_SPACE; + goto done; + } + + *out_paddr_buf_vaddr = translated_addr; + +done: + spin_unlock (&proc->pd->lock, &ctxprpd); + return result; +} + +/* int proc_resource_mem_unref (int mem_rid, size_t pages) */ +DEFINE_SYSCALL (sys_proc_mem_unref) { + spin_lock_ctx_t ctxpr; + int rid = (int)a1; + size_t pages = (size_t)a2; + + struct proc_resource* resource; + spin_lock (&proc->lock, &ctxpr); + rbtree_find (struct proc_resource, &proc->resource_tree, rid, resource, proc_resource_tree_link, + rid); + spin_unlock (&proc->lock, &ctxpr); + + if (resource == NULL) + return -ST_NOT_FOUND; + + proc_mem_unref (proc, &resource->u.mem, pages); + + return ST_OK; +} + static syscall_handler_func_t handler_table[] = { [SYS_PROC_QUIT] = &sys_proc_quit, [SYS_PROC_TEST] = &sys_proc_test, @@ -212,6 +266,8 @@ static syscall_handler_func_t handler_table[] = { [SYS_PROC_MUTEX_UNLOCK] = &sys_proc_mutex_unlock, [SYS_PROC_SPAWN_THREAD] = &sys_proc_spawn_thread, [SYS_PROC_SCHED] = &sys_proc_sched, + [SYS_PROC_TRANSLATE_V2P] = &sys_proc_translate_v2p, + [SYS_PROC_MEM_UNREF] = &sys_proc_mem_unref, }; syscall_handler_func_t syscall_find_handler (int syscall_num) { diff --git a/libmsl/alloc/liballoc.c b/libmsl/alloc/liballoc.c index eca0573..8425149 100644 --- a/libmsl/alloc/liballoc.c +++ b/libmsl/alloc/liballoc.c @@ -6,7 +6,7 @@ static int liballoc_mutex; static uintptr_t liballoc_map_base = PROC_MAP_BASE; -static int mem_rid_base = 10000; +static int mem_rid_base = 1000000; void liballoc_init (void) { liballoc_mutex = proc_create_resource_mutex (100, RV_PRIVATE); } @@ -36,7 +36,20 @@ void* liballoc_alloc (int pages) { return (void*)old_base; } -int liballoc_free (void* ptr, int pages) { return 0; } +int liballoc_free (void* ptr, int pages) { + int res; + uintptr_t out_paddr; + + res = proc_translate_v2p ((uintptr_t)ptr, &out_paddr); + if (res < 0) + return res; + + res = proc_unmap ((uintptr_t)ptr, pages); + if (res < 0) + return res; + + return proc_mem_unref (out_paddr, pages); +} /** Durand's Ridiculously Amazing Super Duper Memory functions. */ diff --git a/libmsl/m/proc.c b/libmsl/m/proc.c index 61c2ca0..e725b3d 100644 --- a/libmsl/m/proc.c +++ b/libmsl/m/proc.c @@ -41,4 +41,12 @@ int proc_spawn_thread (uintptr_t vstack_top, size_t stack_size, void* entry) { 0); } +int proc_translate_v2p (uintptr_t vaddr, uintptr_t* out_paddr) { + return syscall (SYS_PROC_TRANSLATE_V2P, vaddr, (uintptr_t)out_paddr, 0, 0, 0, 0); +} + +int proc_mem_unref (uintptr_t paddr, size_t pages) { + return syscall (SYS_PROC_MEM_UNREF, paddr, (uintptr_t)pages, 0, 0, 0, 0); +} + int proc_sched (void) { return syscall (SYS_PROC_SCHED, 0, 0, 0, 0, 0, 0); } diff --git a/libmsl/m/proc.h b/libmsl/m/proc.h index 307ca2e..e780ffd 100644 --- a/libmsl/m/proc.h +++ b/libmsl/m/proc.h @@ -27,6 +27,7 @@ int proc_mutex_lock (int mutex_rid); int proc_mutex_unlock (int mutex_rid); int proc_spawn_thread (uintptr_t vstack_top, size_t stack_size, void* entry); int proc_sched (void); -int proc_translate_resource_mem (uintptr_t vaddr); +int proc_translate_v2p (uintptr_t vaddr, uintptr_t* out_paddr); +int proc_mem_unref (uintptr_t paddr, size_t pages); #endif // _LIBMSL_M_PROC_H