From d7b734306f89266d3e1ea843e01b2666d0426f16 Mon Sep 17 00:00:00 2001 From: kamkow1 Date: Wed, 7 Jan 2026 22:47:30 +0100 Subject: [PATCH] Introduce concept of Process Resources (PR_MEM), implement necessary syscalls --- include/m/syscall_defs.h | 4 ++ init/init.c | 14 ++-- kernel/amd64/mm.c | 142 +++++++++++++++++++++++++++++++++++++++ kernel/amd64/proc.c | 37 ++++++---- kernel/libk/assert.h | 14 ++++ kernel/libk/rbtree.h | 2 +- kernel/proc/proc.c | 23 ++++--- kernel/proc/proc.h | 5 ++ kernel/proc/resource.c | 100 +++++++++++++++++++++++++++ kernel/proc/resource.h | 44 ++++++++++++ kernel/proc/src.mk | 2 + kernel/sys/mm.h | 4 ++ kernel/syscall/syscall.c | 68 +++++++++++++++++-- libmsl/m/mem.h | 13 ---- libmsl/m/proc.c | 13 +++- libmsl/m/proc.h | 16 ++++- 16 files changed, 451 insertions(+), 50 deletions(-) create mode 100644 kernel/libk/assert.h create mode 100644 kernel/proc/resource.c create mode 100644 kernel/proc/resource.h delete mode 100644 libmsl/m/mem.h diff --git a/include/m/syscall_defs.h b/include/m/syscall_defs.h index ee6949e..625bd51 100644 --- a/include/m/syscall_defs.h +++ b/include/m/syscall_defs.h @@ -5,10 +5,14 @@ #define SYS_PROC_TEST 2 #define SYS_PROC_MAP 3 #define SYS_PROC_UNMAP 4 +#define SYS_PROC_CREATE_RESOURCE_MEM 5 +#define SYS_PROC_DROP_RESOURCE 6 #define SR_OK 0 #define SR_SYSCALL_NOT_FOUND 1 #define SR_UNALIGNED 2 #define SR_OOM_ERROR 3 +#define SR_NOT_FOUND 4 +#define SR_BAD_ADDRESS_SPACE 5 #endif // _M_SYSCALL_DEFS_H diff --git a/init/init.c b/init/init.c index 2eed183..9e58855 100644 --- a/init/init.c +++ b/init/init.c @@ -1,12 +1,18 @@ #include -#include #include +#include +#include #include void app_main (void) { - m_proc_map (M_PROC_MAP_BASE, 1, PM_PRESENT | PM_RW | PM_USER); + uintptr_t out_paddr; + int mem_rid = m_proc_create_resource_mem (16, RV_PRIVATE, &out_paddr); - memset ((void*)M_PROC_MAP_BASE, 0, M_PAGE_SIZE); + m_proc_map (out_paddr, M_PROC_MAP_BASE, 16, PM_PRESENT | PM_RW | PM_USER); - m_proc_unmap (M_PROC_MAP_BASE, 1); + memset ((void*)M_PROC_MAP_BASE, 0, M_PAGE_SIZE * 16); + + m_proc_unmap (M_PROC_MAP_BASE, 16); + + m_proc_drop_resource (mem_rid); } diff --git a/kernel/amd64/mm.c b/kernel/amd64/mm.c index 938482f..0b186c2 100644 --- a/kernel/amd64/mm.c +++ b/kernel/amd64/mm.c @@ -251,6 +251,148 @@ void mm_reload (void) { spin_unlock (&mm_lock); } +bool mm_validate (struct pd* pd, uintptr_t vaddr, uint32_t flags) { + spin_lock (&mm_lock); + + struct limine_hhdm_response* hhdm = limine_hhdm_request.response; + bool ret = false; + + if (flags & MM_PD_LOCK) + spin_lock (&pd->lock); + + uint64_t* pml4 = (uint64_t*)(pd->cr3_paddr + (uintptr_t)hhdm->offset); + struct pg_index pg_index = amd64_mm_page_index (vaddr); + + uint64_t* pml3 = amd64_mm_next_table (pml4, pg_index.pml4, false); + if (pml3 == NULL) + goto done; + + uint64_t* pml2 = amd64_mm_next_table (pml3, pg_index.pml3, false); + if (pml2 == NULL) + goto done; + + uint64_t* pml1 = amd64_mm_next_table (pml2, pg_index.pml2, false); + if (pml1 == NULL) + goto done; + + uint64_t pte = pml1[pg_index.pml1]; + ret = (pte & AMD64_PG_PRESENT) != 0; + +done: + if (flags & MM_PD_LOCK) + spin_unlock (&pd->lock); + + spin_unlock (&mm_lock); + + return ret; +} + +bool mm_validate_buffer (struct pd* pd, uintptr_t vaddr, size_t size, uint32_t flags) { + bool ok = true; + + if (flags & MM_PD_LOCK) + spin_lock (&pd->lock); + + for (size_t i = 0; i < size; i++) { + ok = mm_validate (pd, vaddr + i, 0); + if (!ok) + goto done; + } + +done: + if (flags & MM_PD_LOCK) + spin_unlock (&pd->lock); + + return ok; +} + +uintptr_t mm_p2v (struct pd* pd, uintptr_t paddr, uint32_t flags) { + spin_lock (&mm_lock); + + struct limine_hhdm_response* hhdm = limine_hhdm_request.response; + uintptr_t ret = 0; + + if (flags & MM_PD_LOCK) + spin_lock (&pd->lock); + + uint64_t* pml4 = (uint64_t*)(pd->cr3_paddr + (uintptr_t)hhdm->offset); + + for (size_t i4 = 0; i4 < 512; i4++) { + if (!(pml4[i4] & AMD64_PG_PRESENT)) + continue; + + uint64_t* pml3 = (uint64_t*)((uintptr_t)hhdm->offset + (pml4[i4] & ~0xFFFULL)); + for (size_t i3 = 0; i3 < 512; i3++) { + if (!(pml3[i3] & AMD64_PG_PRESENT)) + continue; + + uint64_t* pml2 = (uint64_t*)((uintptr_t)hhdm->offset + (pml3[i3] & ~0xFFFULL)); + for (size_t i2 = 0; i2 < 512; i2++) { + if (!(pml2[i2] & AMD64_PG_PRESENT)) + continue; + + uint64_t* pml1 = (uint64_t*)((uintptr_t)hhdm->offset + (pml2[i2] & ~0xFFFULL)); + for (size_t i1 = 0; i1 < 512; i1++) { + if ((pml1[i1] & AMD64_PG_PRESENT) && ((pml1[i1] & ~0xFFFULL) == (paddr & ~0xFFFULL))) { + struct pg_index idx = {i4, i3, i2, i1}; + ret = (((uint64_t)idx.pml4 << 39) | ((uint64_t)idx.pml3 << 30) | + ((uint64_t)idx.pml2 << 21) | ((uint64_t)idx.pml1 << 12) | (paddr & 0xFFFULL)); + goto done; + } + } + } + } + } + +done: + if (flags & MM_PD_LOCK) + spin_unlock (&pd->lock); + + spin_unlock (&mm_lock); + + return ret; +} + +uintptr_t mm_v2p (struct pd* pd, uintptr_t vaddr, uint32_t flags) { + spin_lock (&mm_lock); + + struct limine_hhdm_response* hhdm = limine_hhdm_request.response; + uintptr_t ret = 0; + + if (flags & MM_PD_LOCK) + spin_lock (&pd->lock); + + uint64_t* pml4 = (uint64_t*)(pd->cr3_paddr + (uintptr_t)hhdm->offset); + struct pg_index pg_index = amd64_mm_page_index (vaddr); + + uint64_t* pml3 = amd64_mm_next_table (pml4, pg_index.pml4, false); + if (pml3 == NULL) + goto done; + + uint64_t* pml2 = amd64_mm_next_table (pml3, pg_index.pml3, false); + if (pml2 == NULL) + goto done; + + uint64_t* pml1 = amd64_mm_next_table (pml2, pg_index.pml2, false); + if (pml1 == NULL) + goto done; + + uint64_t pte = pml1[pg_index.pml1]; + + if (!(pte & AMD64_PG_PRESENT)) + goto done; + + ret = ((pte & ~0xFFFULL) | (vaddr & 0xFFFULL)); + +done: + if (flags & MM_PD_LOCK) + spin_unlock (&pd->lock); + + spin_unlock (&mm_lock); + + return ret; +} + /* TLB shootdown IRQ handler */ static void amd64_tlb_shootdown_irq (void* arg, void* regs) { (void)arg, (void)regs; diff --git a/kernel/amd64/proc.c b/kernel/amd64/proc.c index 7b199df..4ac570e 100644 --- a/kernel/amd64/proc.c +++ b/kernel/amd64/proc.c @@ -1,12 +1,14 @@ #include #include #include +#include #include #include #include #include #include #include +#include #include #include @@ -21,6 +23,10 @@ struct proc* proc_from_elf (uint8_t* elf_contents) { memset (proc, 0, sizeof (*proc)); + proc->lock = SPIN_LOCK_INIT; + atomic_store (&proc->state, PROC_READY); + proc->pid = atomic_fetch_add (&pids, 1); + proc->pd.lock = SPIN_LOCK_INIT; proc->pd.cr3_paddr = mm_alloc_user_pd_phys (); if (proc->pd.cr3_paddr == 0) { @@ -28,21 +34,30 @@ struct proc* proc_from_elf (uint8_t* elf_contents) { return NULL; } - proc->pdata.kernel_stack = pmm_alloc (KSTACK_SIZE / PAGE_SIZE); - if (proc->pdata.kernel_stack == PMM_ALLOC_ERR) { + int kstk_rid = atomic_fetch_add (&proc->rids, 1); + struct proc_resource_mem_init kstk_mem_init = {.pages = KSTACK_SIZE / PAGE_SIZE}; + struct proc_resource* kstk_r = + proc_create_resource (proc, kstk_rid, PR_MEM, RV_PRIVATE, (void*)&kstk_mem_init); + if (kstk_r == NULL) { free (proc); return NULL; } - uintptr_t kernel_stack = proc->pdata.kernel_stack; - proc->pdata.kernel_stack += (uintptr_t)hhdm->offset + KSTACK_SIZE; - proc->pdata.user_stack = pmm_alloc (USTACK_SIZE / PAGE_SIZE); - if (proc->pdata.user_stack == PMM_ALLOC_ERR) { + proc->pdata.kernel_stack = kstk_r->u.mem.paddr + (uintptr_t)hhdm->offset + KSTACK_SIZE; + + int ustk_rid = atomic_fetch_add (&proc->rids, 1); + struct proc_resource_mem_init ustk_mem_init = {.pages = USTACK_SIZE / PAGE_SIZE}; + struct proc_resource* ustk_r = + proc_create_resource (proc, ustk_rid, PR_MEM, RV_PRIVATE, (void*)&ustk_mem_init); + if (ustk_r == NULL) { + kstk_r->ops.cleanup (kstk_r); + free (kstk_r); free (proc); - pmm_free (kernel_stack, USTACK_SIZE / PAGE_SIZE); return NULL; } + proc->pdata.user_stack = ustk_r->u.mem.paddr; + proc_map (proc, proc->pdata.user_stack, PROC_USTACK_TOP - USTACK_SIZE, USTACK_SIZE / PAGE_SIZE, MM_PG_USER | MM_PG_PRESENT | MM_PG_RW); @@ -53,9 +68,6 @@ struct proc* proc_from_elf (uint8_t* elf_contents) { proc->pdata.regs.rflags = 0x202; proc->pdata.regs.cs = GDT_UCODE | 0x03; proc->pdata.regs.rip = aux.entry; - proc->lock = SPIN_LOCK_INIT; - atomic_store (&proc->state, PROC_READY); - proc->pid = atomic_fetch_add (&pids, 1); return proc; } @@ -63,6 +75,8 @@ struct proc* proc_from_elf (uint8_t* elf_contents) { void proc_cleanup (struct proc* proc) { struct limine_hhdm_response* hhdm = limine_hhdm_request.response; + proc_cleanup_resources (proc); + struct list_node_link *mapping_link, *mapping_link_tmp; spin_lock (&proc->pd.lock); @@ -70,9 +84,6 @@ void proc_cleanup (struct proc* proc) { struct proc_mapping* mapping = list_entry (mapping_link, struct proc_mapping, proc_mappings_link); - DEBUG ("mapping vaddr=%p, paddr=%p, size=%zu\n", mapping->vaddr, mapping->paddr, mapping->size); - - pmm_free (mapping->paddr, mapping->size / PAGE_SIZE); list_remove (proc->mappings, mapping_link); free (mapping); } diff --git a/kernel/libk/assert.h b/kernel/libk/assert.h new file mode 100644 index 0000000..94dc03c --- /dev/null +++ b/kernel/libk/assert.h @@ -0,0 +1,14 @@ +#ifndef _KERNEL_LIBK_ASSERT_H +#define _KERNEL_LIBK_ASSERT_H + +#include + +#define assert(x) \ + do { \ + if (!(x)) { \ + DEBUG ("%s ssertion failed\n", #x); \ + spin (); \ + } \ + } while (0) + +#endif // _KERNEL_LIBK_ASSERT_H diff --git a/kernel/libk/rbtree.h b/kernel/libk/rbtree.h index 46f0ac1..5d8e0ab 100644 --- a/kernel/libk/rbtree.h +++ b/kernel/libk/rbtree.h @@ -125,7 +125,7 @@ struct rb_node_link { while (__cur) { \ type* __obj = rbtree_entry (__cur, type, member); \ if ((keyval) == __obj->keyfield) { \ - (out) = __cur; \ + (out) = rbtree_entry (__cur, type, member); \ break; \ } else if ((keyval) < __obj->keyfield) \ __cur = __cur->left; \ diff --git a/kernel/proc/proc.c b/kernel/proc/proc.c index dce7d26..1c1c4c9 100644 --- a/kernel/proc/proc.c +++ b/kernel/proc/proc.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -40,9 +41,6 @@ static bool proc_check_elf (uint8_t* elf) { bool proc_map (struct proc* proc, uintptr_t start_paddr, uintptr_t start_vaddr, size_t pages, uint32_t flags) { - DEBUG ("start_vaddr=%p, start_paddr=%p, pages=%zu, flags=%x\n", start_vaddr, start_paddr, pages, - flags); - struct proc_mapping* mapping = malloc (sizeof (*mapping)); if (mapping == NULL) @@ -74,8 +72,6 @@ bool proc_unmap (struct proc* proc, uintptr_t start_vaddr, size_t pages) { struct list_node_link *mapping_link, *mapping_link_tmp; bool used_tail_mapping = false; - DEBUG ("start_vaddr=%p, pages=%zu\n", start_vaddr, pages); - struct proc_mapping* tail_mapping = malloc (sizeof (*tail_mapping)); if (tail_mapping == NULL) return false; @@ -154,9 +150,15 @@ struct elf_aux proc_load_segments (struct proc* proc, uint8_t* elf) { size_t blks = div_align_up (phdr->p_memsz + off, PAGE_SIZE); - uintptr_t p_addr = pmm_alloc (blks); - if (p_addr == PMM_ALLOC_ERR) + int rid = atomic_fetch_add (&proc->rids, 1); + struct proc_resource_mem_init mem_init = {.pages = blks}; + struct proc_resource* r = + proc_create_resource (proc, rid, PR_MEM, RV_PRIVATE, (void*)&mem_init); + if (r == NULL) { DEBUG ("pmm oom error while loading ELF segments! (tried to alloc %zu blks)\n", blks); + } + + uintptr_t p_addr = r->u.mem.paddr; memset ((void*)((uintptr_t)hhdm->offset + p_addr), 0, blks * PAGE_SIZE); memcpy ((void*)((uintptr_t)hhdm->offset + p_addr + off), @@ -213,8 +215,11 @@ static struct proc* proc_find_sched (void) { if (!node) rbtree_first (&thiscpu->proc_run_q, node); + if (!node) + return NULL; + struct rb_node_link* first = node; - while (node) { + do { proc = rbtree_entry (node, struct proc, cpu_run_q_link); if (atomic_load (&proc->state) == PROC_READY) @@ -228,7 +233,7 @@ static struct proc* proc_find_sched (void) { if (node == first) break; - } + } while (node != first); return NULL; } diff --git a/kernel/proc/proc.h b/kernel/proc/proc.h index c9eec43..0b74d98 100644 --- a/kernel/proc/proc.h +++ b/kernel/proc/proc.h @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -19,6 +20,8 @@ /// Process marked garbage collection #define PROC_DEAD 1 +#define PROC_RESOURCES_MAX 1024 + struct cpu; struct proc_mapping { @@ -40,6 +43,8 @@ struct proc { spin_lock_t lock; struct cpu* cpu; atomic_int state; + struct rb_node_link* resource_tree; + atomic_int rids; }; void proc_sched (void); diff --git a/kernel/proc/resource.c b/kernel/proc/resource.c new file mode 100644 index 0000000..2cb6a79 --- /dev/null +++ b/kernel/proc/resource.c @@ -0,0 +1,100 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void proc_cleanup_resources (struct proc* proc) { + struct proc_resource* resource = NULL; + + struct rb_node_link* rnode; + rbtree_first (&proc->resource_tree, rnode); + + while (rnode) { + struct rb_node_link* next; + rbtree_next (rnode, next); + resource = rbtree_entry (rnode, struct proc_resource, proc_resource_tree_link); + rbtree_delete (&proc->resource_tree, rnode); + resource->ops.cleanup (resource); + free (resource); + rnode = next; + } + + assert (proc->resource_tree == NULL); +} + +void proc_drop_resource (struct proc* proc, struct proc_resource* resource) { + if (atomic_fetch_sub (&resource->refs, 1) == 1) { + spin_lock (&proc->lock); + rbtree_delete (&proc->resource_tree, &resource->proc_resource_tree_link); + spin_unlock (&proc->lock); + + resource->ops.cleanup (resource); + free (resource); + } +} + +static bool proc_create_resource_mem (struct proc_resource_mem* mem, + struct proc_resource_mem_init* init) { + if (init->pages == 0) + return false; + + uintptr_t paddr = pmm_alloc (init->pages); + if (paddr == PMM_ALLOC_ERR) + return false; + + mem->paddr = paddr; + mem->pages = init->pages; + DEBUG ("paddr=%p, pages=%zu\n", mem->paddr, mem->pages); + + return true; +} + +static void proc_cleanup_resource_mem (struct proc_resource* resource) { + pmm_free (resource->u.mem.paddr, resource->u.mem.pages); +} + +struct proc_resource* proc_create_resource (struct proc* proc, int rid, int type, int vis, + void* data) { + /* Check if resource RID already exists */ + struct proc_resource* resource_check; + rbtree_find (struct proc_resource, &proc->resource_tree, rid, resource_check, + proc_resource_tree_link, rid); + if (resource_check != NULL) + return NULL; + + struct proc_resource* resource = malloc (sizeof (*resource)); + if (resource == NULL) + return NULL; + + memset (resource, 0, sizeof (*resource)); + + resource->lock = SPIN_LOCK_INIT; + resource->type = type; + resource->refs = 1; + resource->rid = rid; + resource->visibility = vis; + + switch (resource->type) { + case PR_MEM: { + struct proc_resource_mem_init* mem_init = data; + proc_create_resource_mem (&resource->u.mem, mem_init); + resource->ops.cleanup = &proc_cleanup_resource_mem; + } break; + default: { + free (resource); + return NULL; + } break; + } + + spin_lock (&proc->lock); + rbtree_insert (struct proc_resource, &proc->resource_tree, &resource->proc_resource_tree_link, + proc_resource_tree_link, rid); + spin_unlock (&proc->lock); + + return resource; +} diff --git a/kernel/proc/resource.h b/kernel/proc/resource.h new file mode 100644 index 0000000..678bdec --- /dev/null +++ b/kernel/proc/resource.h @@ -0,0 +1,44 @@ +#ifndef _KERNEL_PROC_RESOURCE_H +#define _KERNEL_PROC_RESOURCE_H + +#include +#include +#include + +#define PR_MEM 0 + +#define RV_PRIVATE 0 +#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 { + int type; + int rid; + int visibility; + spin_lock_t lock; + atomic_int refs; + struct rb_node_link proc_resource_tree_link; + union { + struct proc_resource_mem mem; + } u; + struct { + void (*cleanup) (struct proc_resource* resource); + } ops; +}; + +struct proc_resource* proc_create_resource (struct proc* proc, int rid, int type, int vis, + void* data); +void proc_drop_resource (struct proc* proc, struct proc_resource* resource); +void proc_cleanup_resources (struct proc* proc); + +#endif // _KERNEL_PROC_RESOURCE_H diff --git a/kernel/proc/src.mk b/kernel/proc/src.mk index 1c7a57b..156627c 100644 --- a/kernel/proc/src.mk +++ b/kernel/proc/src.mk @@ -1,3 +1,5 @@ c += proc/proc.c +c += proc/resource.c o += proc/proc.o +o += proc/resource.o diff --git a/kernel/sys/mm.h b/kernel/sys/mm.h index 96a2c27..87729fb 100644 --- a/kernel/sys/mm.h +++ b/kernel/sys/mm.h @@ -21,6 +21,10 @@ void mm_unmap_page (struct pd* pd, uintptr_t vaddr, uint32_t flags); void mm_unmap_kernel_page (uintptr_t vaddr, uint32_t flags); void mm_lock_kernel (void); void mm_unlock_kernel (void); +bool mm_validate (struct pd* pd, uintptr_t vaddr, uint32_t flags); +bool mm_validate_buffer (struct pd* pd, uintptr_t vaddr, size_t size, uint32_t flags); +uintptr_t mm_p2v (struct pd* pd, uintptr_t paddr, uint32_t flags); +uintptr_t mm_v2p (struct pd* pd, uintptr_t vaddr, uint32_t flags); void mm_init (void); #endif // _KERNEL_SYS_MM_H diff --git a/kernel/syscall/syscall.c b/kernel/syscall/syscall.c index 20634fa..993adce 100644 --- a/kernel/syscall/syscall.c +++ b/kernel/syscall/syscall.c @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -24,18 +25,18 @@ DEFINE_SYSCALL (sys_proc_test) { return SR_OK; } -/* int proc_map (uintptr_t vaddr, size_t pages, uint32_t flags) */ +/* int proc_map (uintptr_t paddr, uintptr_t vaddr, size_t pages, uint32_t flags) */ DEFINE_SYSCALL (sys_proc_map) { - uintptr_t vaddr = a1; - size_t pages = (size_t)a2; - uint32_t flags = (uint32_t)a3; + uintptr_t paddr = a1; + uintptr_t vaddr = a2; + size_t pages = (size_t)a3; + uint32_t flags = (uint32_t)a4; if (vaddr % PAGE_SIZE != 0) return -SR_UNALIGNED; - uintptr_t paddr = pmm_alloc (pages); - if (paddr == PMM_ALLOC_ERR) - return -SR_OOM_ERROR; + if (paddr % PAGE_SIZE != 0) + return -SR_UNALIGNED; bool ok = proc_map (proc, paddr, vaddr, pages, flags); return ok ? SR_OK : -SR_OOM_ERROR; @@ -53,11 +54,64 @@ DEFINE_SYSCALL (sys_proc_unmap) { return ok ? SR_OK : -SR_OOM_ERROR; } +/* int proc_create_resource_mem (size_t pages, int vis, uintptr_t* out_paddr) */ +DEFINE_SYSCALL (sys_proc_create_resource_mem) { + struct limine_hhdm_response* hhdm = limine_hhdm_request.response; + + size_t pages = (size_t)a1; + int vis = (int)a2; + uintptr_t* out_paddr_buf = (uintptr_t*)a3; + + spin_lock (&proc->pd.lock); + + 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); + return -SR_BAD_ADDRESS_SPACE; + } + + spin_unlock (&proc->pd.lock); + + uintptr_t* out_paddr_buf_vaddr = (uintptr_t*)((uintptr_t)hhdm->offset + out_paddr_buf_paddr); + + int rid = atomic_fetch_add (&proc->rids, 1); + struct proc_resource_mem_init mem_init = {.pages = pages}; + struct proc_resource* r = proc_create_resource (proc, rid, PR_MEM, vis, &mem_init); + + if (r != NULL) { + *out_paddr_buf_vaddr = r->u.mem.paddr; + return r->rid; + } else { + return -SR_OOM_ERROR; + } +} + +/* int proc_drop_resource (int rid) */ +DEFINE_SYSCALL (sys_proc_drop_resource) { + int rid = (int)a1; + + struct proc_resource* resource; + spin_lock (&proc->lock); + rbtree_find (struct proc_resource, &proc->resource_tree, rid, resource, proc_resource_tree_link, + rid); + spin_unlock (&proc->lock); + + if (resource == NULL) + return -SR_NOT_FOUND; + + proc_drop_resource (proc, resource); + + return SR_OK; +} + static syscall_handler_func_t handler_table[] = { [SYS_PROC_QUIT] = &sys_proc_quit, [SYS_PROC_TEST] = &sys_proc_test, [SYS_PROC_MAP] = &sys_proc_map, [SYS_PROC_UNMAP] = &sys_proc_unmap, + [SYS_PROC_CREATE_RESOURCE_MEM] = &sys_proc_create_resource_mem, + [SYS_PROC_DROP_RESOURCE] = &sys_proc_drop_resource, }; syscall_handler_func_t syscall_find_handler (int syscall_num) { diff --git a/libmsl/m/mem.h b/libmsl/m/mem.h deleted file mode 100644 index 252f25f..0000000 --- a/libmsl/m/mem.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef _LIBMSL_M_MEM_H -#define _LIBMSL_M_MEM_H - -#if defined(__x86_64__) -#define M_PROC_MAP_BASE 0x0000700000000000 -#define M_PAGE_SIZE 4096 -#endif - -#define PM_PRESENT (1 << 0) -#define PM_RW (1 << 1) -#define PM_USER (1 << 2) - -#endif // _LIBMSL_M_MEM_H diff --git a/libmsl/m/proc.c b/libmsl/m/proc.c index e5c5398..84dec6b 100644 --- a/libmsl/m/proc.c +++ b/libmsl/m/proc.c @@ -7,10 +7,19 @@ int m_proc_quit (void) { return m_syscall (SYS_PROC_QUIT, 0, 0, 0, 0, 0, 0); } int m_proc_test (void) { return m_syscall (SYS_PROC_TEST, 0, 0, 0, 0, 0, 0); } -int m_proc_map (uintptr_t vaddr, size_t pages, uint32_t flags) { - return m_syscall (SYS_PROC_MAP, vaddr, (uintptr_t)pages, (uintptr_t)flags, 0, 0, 0); +int m_proc_map (uintptr_t paddr, uintptr_t vaddr, size_t pages, uint32_t flags) { + return m_syscall (SYS_PROC_MAP, paddr, vaddr, (uintptr_t)pages, (uintptr_t)flags, 0, 0); } int m_proc_unmap (uintptr_t vaddr, size_t pages) { return m_syscall (SYS_PROC_UNMAP, vaddr, (uintptr_t)pages, 0, 0, 0, 0); } + +int m_proc_create_resource_mem (size_t pages, int vis, uintptr_t* out_paddr) { + return m_syscall (SYS_PROC_CREATE_RESOURCE_MEM, (uintptr_t)pages, (uintptr_t)vis, + (uintptr_t)out_paddr, 0, 0, 0); +} + +int m_proc_drop_resource (int rid) { + return m_syscall (SYS_PROC_DROP_RESOURCE, (uintptr_t)rid, 0, 0, 0, 0, 0); +} diff --git a/libmsl/m/proc.h b/libmsl/m/proc.h index e01c81b..476c9b8 100644 --- a/libmsl/m/proc.h +++ b/libmsl/m/proc.h @@ -1,12 +1,26 @@ #ifndef _LIBMSL_M_PROC_H #define _LIBMSL_M_PROC_H +#if defined(__x86_64__) +#define M_PROC_MAP_BASE 0x0000700000000000 +#define M_PAGE_SIZE 4096 +#endif + +#define PM_PRESENT (1 << 0) +#define PM_RW (1 << 1) +#define PM_USER (1 << 2) + +#define RV_PRIVATE 0 +#define RV_PUBLIC 1 + #include #include int m_proc_quit (void); int m_proc_test (void); -int m_proc_map (uintptr_t vaddr, size_t pages, uint32_t flags); +int m_proc_map (uintptr_t paddr, uintptr_t vaddr, size_t pages, uint32_t flags); int m_proc_unmap (uintptr_t vaddr, size_t pages); +int m_proc_create_resource_mem (size_t pages, int vis, uintptr_t* out_paddr); +int m_proc_drop_resource (int rid); #endif // _LIBMSL_M_PROC_H