diff options
| -rw-r--r-- | api/syscall.h | 3 | ||||
| -rw-r--r-- | arch/x86_64/hal/obj.c | 2 | ||||
| -rw-r--r-- | arch/x86_64/hal/paging.c | 36 | ||||
| -rw-r--r-- | arch/x86_64/proc/init.c | 2 | ||||
| -rw-r--r-- | arch/x86_64/proc/process.c | 39 | ||||
| -rw-r--r-- | arch/x86_64/proc/process.h | 7 | ||||
| -rw-r--r-- | arch/x86_64/sys/syscall.c | 2 | ||||
| -rw-r--r-- | doc/syscall.md | 7 | ||||
| -rw-r--r-- | hal/memory.h | 11 | ||||
| -rw-r--r-- | proc/process.c | 18 | ||||
| -rw-r--r-- | proc/process.h | 10 | ||||
| -rw-r--r-- | sys/message.c | 53 | ||||
| -rw-r--r-- | sys/message.h | 10 | ||||
| -rw-r--r-- | sys/syscall.c | 50 | ||||
| -rw-r--r-- | sys/syscall_initrd_file.c | 17 | ||||
| -rw-r--r-- | sys/syscall_message.c | 4 |
16 files changed, 182 insertions, 89 deletions
diff --git a/api/syscall.h b/api/syscall.h index 5658ac2..a116177 100644 --- a/api/syscall.h +++ b/api/syscall.h @@ -156,11 +156,8 @@ struct syscall_initrd_file_read enum { _SYSCALL_MESSAGE_NONE = 0, - SYSCALL_MESSAGE_SIZE }; -#define SYSCALL_PERM_MESSAGE_SIZE (JOVE_PERM_READ) - /**JOVE_OBJ_VIRTTERM syscalls.*/ enum diff --git a/arch/x86_64/hal/obj.c b/arch/x86_64/hal/obj.c index 103b53d..75cb0c0 100644 --- a/arch/x86_64/hal/obj.c +++ b/arch/x86_64/hal/obj.c @@ -41,7 +41,7 @@ obj_release(jove_owned_obj_t *obj) void* obj_deref(jove_owned_obj_t *obj) { - return (void*)(((uintptr_t)obj_getvalue(obj)) | 0xFFFF800000000000ULL); + return (void*)(((uintptr_t)obj_getvalue(obj)) | IDENT_VIRT_BASE); } uint8_t diff --git a/arch/x86_64/hal/paging.c b/arch/x86_64/hal/paging.c index 770cdff..408b5d5 100644 --- a/arch/x86_64/hal/paging.c +++ b/arch/x86_64/hal/paging.c @@ -42,6 +42,11 @@ paging_pml4_switch(uintptr_t pml4) __asm__ volatile("movq %0, %%cr3":: "r"(pml4): "memory"); } +void pagedir_invlpg(uintptr_t vptr) +{ + __asm__ volatile("invlpg (%0)":: "r"(vptr)); +} + static struct int_stackframe* s_int_handle_pf_early(struct int_stackframe *frame) { @@ -101,6 +106,29 @@ s_pagedir_get_pml1(page_t *pml4, uintptr_t vptr) return PML_TBL(pml2, pml2i); } +uintptr_t *pagedir_get_mapping(jove_owned_obj_t *pagedir, uintptr_t vptr) +{ + page_t *pml4 = obj_deref(pagedir); + page_t *pml1 = s_pagedir_get_pml1(pml4, vptr); + if(!pml1) return 0; + + size_t pml1i = PML1I(vptr); + page_t *mapping = &pml1[pml1i]; + return (uintptr_t*)mapping; +} + +uintptr_t +pagedir_ident_from_mapping(uintptr_t *mapping) +{ + return (((page_t*)mapping)->paddr << 12) | IDENT_VIRT_BASE; +} + +void +pagedir_mapping_set_present(uintptr_t *mapping, bool present) +{ + ((page_t*)mapping)->p = present; +} + int pagedir_map_frame(page_t *pml4, uintptr_t pptr, uintptr_t vptr, uintmax_t flg) @@ -113,7 +141,7 @@ int pagedir_map_frame(page_t *pml4, if(pml1[pml1i].p) return EEXIST; pml1[pml1i].value = pptr | PAGE_PRESENT | flg; - __asm__ volatile("invlpg (%0)":: "r"(vptr): "memory"); + pagedir_invlpg(vptr); return 0; } @@ -184,7 +212,7 @@ map_table: PAGE_PRESENT | (pptr > IDENT_VIRT_BASE ? 0 : PAGE_USER) | PAGE_WRITEABLE; - __asm__ volatile("invlpg (%0)":: "r"(vptr): "memory"); + pagedir_invlpg(vptr); return 0; } @@ -241,7 +269,7 @@ int pagedir_unmap_untyped_frame( jove_untyped_t *untyped_data = obj_deref(dst); untyped_data->limit = 0x1000; - __asm__ volatile("invlpg (%0)":: "r"(vptr): "memory"); + pagedir_invlpg(vptr); return 0; } @@ -295,7 +323,7 @@ unmap_table: jove_untyped_t *untyped = obj_deref(dst); untyped->limit = 0x1000; - __asm__ volatile("invlpg (%0)":: "r"(vptr): "memory"); + pagedir_invlpg(vptr); return 0; } } diff --git a/arch/x86_64/proc/init.c b/arch/x86_64/proc/init.c index 4c86038..be1d556 100644 --- a/arch/x86_64/proc/init.c +++ b/arch/x86_64/proc/init.c @@ -144,7 +144,7 @@ init_setup(void) jove_owned_obj_t *message_obj = objdir_getlocal(_rootdir_obj, ROOTDIR_MESSAGE_I); obj_settype(message_obj, JOVE_OBJ_MESSAGE); - obj_setvalue(message_obj, (message_pptr & ~0xFFF) | 1); + obj_setvalue(message_obj, last_base | 1); obj_release(message_obj); obj_release(init_pagedir); diff --git a/arch/x86_64/proc/process.c b/arch/x86_64/proc/process.c index 0c5c282..6165585 100644 --- a/arch/x86_64/proc/process.c +++ b/arch/x86_64/proc/process.c @@ -11,55 +11,46 @@ PAGEALIGN uint8_t s_init_iopb[0x2000]; PAGEALIGN char _init_pcb_bytes[0x1000] = { 0 }; -pcb_t *_init_pcb = (pcb_t*)&_init_pcb_bytes; - -pid_t -pcb_pid(pcb_t *pcb) -{ - return pcb->pid; -} - -jove_obj_t* -pcb_rootdir(pcb_t *pcb) -{ - return pcb->rootdir; -} +pcb_t *pcb_tree; void processing_setup(void (*process_main)) { + pcb_t *init_pcb = (pcb_t*)&_init_pcb_bytes; + pcb_tree = init_pcb; + memset(s_init_iopb, 0xFF, 0x2000); uintptr_t ksp = ((uintptr_t)&_init_pcb_bytes) + 0xFF8; - _init_pcb->tree_node.get_key = (void*)pcb_pid; - _init_pcb->tree_node.color = 1; + init_pcb->header.tree_node.get_key = (void*)pcb_getpid; + init_pcb->header.tree_node.color = 1; + init_pcb->header.rootdir = _rootdir_obj; + init_pcb->header.pagedir = obj_release(objdir_getlocal(_rootdir_obj, ROOTDIR_PAGEDIR_I)); - _init_pcb->pid = 1; - _init_pcb->ksp = (void*)ksp; - _init_pcb->pml4 = paging_get_pml4(); - _init_pcb->rootdir = _rootdir_obj; + init_pcb->header.pid = 1; + init_pcb->ksp = (void*)ksp; jove_owned_obj_t *iopb_obj = objdir_getlocal(_rootdir_obj, ROOTDIR_IOPB_I); obj_settype(iopb_obj, JOVE_OBJ_IOPB); obj_setvalue(iopb_obj, (uintptr_t)s_init_iopb); - _init_pcb->iopb = iopb_obj; + init_pcb->iopb = obj_release(iopb_obj); processor_t *proc = processor_current(); - proc->tss.rsp[0] = (uintptr_t)_init_pcb->ksp; + proc->tss.rsp[0] = (uintptr_t)init_pcb->ksp; memcpy(proc->iopb, s_init_iopb, 0x2000); { jove_owned_obj_t *process_obj = objdir_getlocal(_rootdir_obj, ROOTDIR_PCB_I); obj_settype(process_obj, JOVE_OBJ_PCB); - obj_setvalue(process_obj, (uintptr_t)_init_pcb); + obj_setvalue(process_obj, (uintptr_t)init_pcb); proc->pcb_obj = process_obj; - proc->pcb = _init_pcb; + proc->pcb = init_pcb; } __asm__ volatile("\ movq %0, %%rsp; \ xorq %%rbp, %%rbp; \ jmpq %1":: - "r"(_init_pcb->ksp), "r"(process_main)); + "r"(init_pcb->ksp), "r"(process_main)); } diff --git a/arch/x86_64/proc/process.h b/arch/x86_64/proc/process.h index cf4d8a8..534c8d5 100644 --- a/arch/x86_64/proc/process.h +++ b/arch/x86_64/proc/process.h @@ -7,13 +7,10 @@ typedef struct process_control_block { - struct rbtree_node tree_node; + struct pcb_expected_header header; struct process_control_block *sched_next; - pid_t pid; - jove_obj_t *rootdir; - jove_owned_obj_t *iopb; - uintptr_t pml4; + jove_obj_t *iopb; enum pcb_state state; int killed; diff --git a/arch/x86_64/sys/syscall.c b/arch/x86_64/sys/syscall.c index e3fa81b..b584756 100644 --- a/arch/x86_64/sys/syscall.c +++ b/arch/x86_64/sys/syscall.c @@ -16,7 +16,7 @@ _syscall_handle_arch(syscall_context_t *ctx) syscall_handle_t call_handle = s_arch_handles[target_type]; if(call_handle == NULL) { kprintf("syscall: Process %i tried to call syscall on object %P which doesn't support syscalls!\n", - pcb_pid(obj_deref(ctx->pcb)), ctx->header->path, ctx->header->pathlen); + pcb_getpid(obj_deref(ctx->pcb)), ctx->header->path, ctx->header->pathlen); return -EBADOBJ; } diff --git a/doc/syscall.md b/doc/syscall.md index 5a3d1e7..4fd55ad 100644 --- a/doc/syscall.md +++ b/doc/syscall.md @@ -318,10 +318,3 @@ Successful reading returns `0`. ### JOVE_OBJ_MESSAGE -| Syscall | Target Permissions | -|----------------------|--------------------| -| SYSCALL_MESSAGE_SIZE | JOVE_PERM_READ | - -#### SYSCALL_MESSAGE_SIZE - -Returns the size of the message object in bytes. diff --git a/hal/memory.h b/hal/memory.h index 6e685d6..ab5f6ad 100644 --- a/hal/memory.h +++ b/hal/memory.h @@ -1,9 +1,10 @@ -#include "sys/syscall.h" #ifndef _JOVE_HAL_MEMORY_H #define _JOVE_HAL_MEMORY_H 1 #include "hal/obj.h" #include "api/syscall.h" +#include "sys/syscall.h" +#include <stdbool.h> typedef struct jove_obj_untyped { @@ -23,6 +24,14 @@ int untyped_split(jove_owned_obj_t *tgt, jove_owned_obj_t *dst, size_t bytes); int untyped_merge(jove_owned_obj_t *a, jove_owned_obj_t *b); int untyped_retype(jove_owned_obj_t *tgt, uint8_t newtype); +void pagedir_invlpg(uintptr_t vptr); + +uintptr_t *pagedir_get_mapping( + jove_owned_obj_t *pagedir, uintptr_t vptr); + +uintptr_t pagedir_ident_from_mapping(uintptr_t *mapping); +void pagedir_mapping_set_present(uintptr_t *mapping, bool present); + int pagedir_map_untyped_frame( jove_owned_obj_t *tgt, jove_perm_obj_t *untyped_obj, uintptr_t vptr, struct syscall_pagedir_flags flg); diff --git a/proc/process.c b/proc/process.c index 3687c8a..55737f6 100644 --- a/proc/process.c +++ b/proc/process.c @@ -6,3 +6,21 @@ process_current(void) { return processor_pcb(((processor_t*)processor_current())); } + +pid_t +pcb_getpid(pcb_t *pcb) +{ + return ((struct pcb_expected_header*)pcb)->pid; +} + +jove_obj_t* +pcb_rootdir(pcb_t *pcb) +{ + return ((struct pcb_expected_header*)pcb)->rootdir; +} + +jove_obj_t* +pcb_pagedir(pcb_t *pcb) +{ + return ((struct pcb_expected_header*)pcb)->pagedir; +} diff --git a/proc/process.h b/proc/process.h index 5099476..2757f6f 100644 --- a/proc/process.h +++ b/proc/process.h @@ -21,6 +21,10 @@ struct pcb_expected_header { struct rbtree_node tree_node; struct process_control_block *sched_next; + + pid_t pid; + jove_obj_t *rootdir; + jove_obj_t *pagedir; }; typedef struct process_control_block pcb_t; @@ -29,10 +33,12 @@ jove_owned_obj_t *process_current(void); void pcb_new(pcb_t *pcb); /*Returns the process ID of the passed PCB. */ -pid_t pcb_pid(pcb_t *pcb); +pid_t pcb_getpid(pcb_t *pcb); /*Returns the root kernel object directory of this PCB. */ jove_obj_t *pcb_rootdir(pcb_t *pcb); -extern pcb_t *_init_pcb; +jove_obj_t *pcb_pagedir(pcb_t *pcb); + +extern pcb_t *pcb_tree; #endif diff --git a/sys/message.c b/sys/message.c index 7c871ce..c87487b 100644 --- a/sys/message.c +++ b/sys/message.c @@ -1,15 +1,54 @@ #include "message.h" +#include "api/error.h" +#include "errno.h" +#include "hal/memory.h" #include "hal/obj.h" +#include "lib/printf.h" -void * -message_data(jove_owned_obj_t *obj) +int +message_hasmap(jove_owned_obj_t *obj) { - uintptr_t objptr = (uintptr_t)obj_deref(obj); - return (void*)(objptr & ~0xFFF); + return obj_getvalue(obj) & 1; } -size_t -message_len(jove_owned_obj_t *obj) +uintptr_t +message_unmap(jove_owned_obj_t *obj, jove_owned_obj_t *pagedir) { - return (obj_getvalue(obj) & 0xFFF) << 12; + if(message_hasmap(obj) == 0) { + kprintf("Message %p doesn't have a map\n", obj_getvalue(obj)); + return -ENOMAP; + } + uintptr_t vptr = obj->locked.value & ~0xFFFULL; + uintptr_t *mapping = pagedir_get_mapping(pagedir, vptr); + + pagedir_mapping_set_present(mapping, false); + pagedir_invlpg(vptr); + + obj_setvalue(obj, *mapping); + return vptr; +} + +void +message_remap(jove_owned_obj_t *message, jove_owned_obj_t *pagedir, uintptr_t vptr) +{ + if(message_hasmap(message)) { + errno = -EHASMAP; + return; + } + + uintmax_t *mapping = pagedir_get_mapping(pagedir, vptr); + + *mapping = obj_getvalue(message) | 1; + pagedir_invlpg(vptr); + + obj_setvalue(message, vptr | 1); +} + +uintptr_t message_getdata(jove_owned_obj_t *message) +{ + if(message_hasmap(message)) + return obj_getvalue(message) & ~0xFFFULL; + + uintptr_t message_val = obj_getvalue(message); + return pagedir_ident_from_mapping(&message_val); } diff --git a/sys/message.h b/sys/message.h index 2ae6e03..97d0f71 100644 --- a/sys/message.h +++ b/sys/message.h @@ -3,11 +3,13 @@ #include "hal/obj.h" -#define MESSAGE_MAX_PAGES (1<<12) -#define MESSAGE_MAX_BYTES (MESSAGE_MAX_PAGES * 0x1000) + #define MESSAGE_ALIGN 0x1000 -void *message_data(jove_owned_obj_t *obj); -size_t message_len(jove_owned_obj_t *obj); +int message_hasmap(jove_owned_obj_t *message); +uintptr_t message_unmap(jove_owned_obj_t *message, jove_owned_obj_t *pagedir); +void message_remap(jove_owned_obj_t *message, jove_owned_obj_t *pagedir, uintptr_t vptr); + +uintptr_t message_getdata(jove_owned_obj_t *message); #endif diff --git a/sys/syscall.c b/sys/syscall.c index 1c9af45..7207708 100644 --- a/sys/syscall.c +++ b/sys/syscall.c @@ -1,5 +1,6 @@ #include "sys/syscall.h" #include "arch/x86_64/hal/obj.h" +#include "hal/memory.h" #include "hal/smp.h" #include "proc/process.h" #include "jove.h" @@ -27,7 +28,7 @@ int _syscall_handle_generic(syscall_context_t *ctx) { pcb_t *pcb = obj_deref(ctx->pcb); - klogf("Process %i encountered stub syscall on object %P\n", pcb_pid(pcb), ctx->header->path, ctx->header->pathlen); + klogf("Process %i encountered stub syscall on object %P\n", pcb_getpid(pcb), ctx->header->path, ctx->header->pathlen); return -EBADOBJ; } @@ -92,35 +93,38 @@ syscall_handler(uintmax_t message_path_raw, uint16_t message_pathlen) if(ctx.message.obj == NULL) { klogf("Process %i failed to get message %P : %s\n", - pcb_pid(pcb), message_path, message_pathlen, errstr(errno)); + pcb_getpid(pcb), message_path, message_pathlen, errstr(errno)); sysret = -errno; goto release_return; } if(obj_gettype(ctx.message.obj) != JOVE_OBJ_MESSAGE) { klogf("Process %i tried to call syscall with invalid object %P\n", - pcb_pid(pcb), message_path, message_pathlen); + pcb_getpid(pcb), message_path, message_pathlen); sysret = -EBADOBJ; goto release_return; } if((ctx.message.permissions & JOVE_PERM_READ) == 0) { klogf("Process %i tried to call syscall with message object %P without read permissions\n", - pcb_pid(pcb), message_path, message_pathlen); + pcb_getpid(pcb), message_path, message_pathlen); sysret = -EPERM; goto release_return; } - size_t messagelen = message_len(ctx.message.obj); - void *messagedata = message_data(ctx.message.obj); + uintptr_t message_vptr = message_unmap(ctx.message.obj, + (jove_owned_obj_t*)pcb_pagedir(pcb)); + + size_t messagelen = 0x1000; + void *messagedata = (void*)message_getdata(ctx.message.obj); struct syscall_header *header = messagedata; size_t bytes_needed = sizeof(struct syscall_header) + header->pathlen * 2; if(bytes_needed > messagelen) { //Target path exceeds message length. - klogf("Process %i tried to call syscall with target path too big for message.\n", pcb_pid(pcb)); + klogf("Process %i tried to call syscall with target path too big for message.\n", pcb_getpid(pcb)); sysret = -ETOOSMALL; - goto release_return; + goto remap_return; } ctx.header = header; @@ -128,17 +132,29 @@ syscall_handler(uintmax_t message_path_raw, uint16_t message_pathlen) ctx.payload = (void*)((uintptr_t)header + bytes_needed); ctx.target = link_try_traverse_objdir( - ctx.objdir, &ctx.lockstack, ctx.header->pathlen, ctx.header->path); - - if(ctx.target.obj == 0) { - //Could not find payload target in pcb rootdir. - klogf("Process %i tried to call syscall with bad target path %P : %s\n", - pcb_pid(pcb), header->path, header->pathlen, errstr(errno)); - sysret = -errno; - goto release_return; + ctx.objdir, &ctx.lockstack, ctx.header->pathlen, ctx.header->path); + + if(ctx.target.obj != 0) { + sysret = _syscall_handle_switch(&ctx); + }else{ + //Check if we're trying to reference the PCB. If we are, we should set it as the target + //regardless of lock. + if(ctx.header->pathlen == 1 && + objdir_peeklocal(ctx.objdir, ctx.header->path[0]).data == ctx.pcb->locked.data) + { + ctx.target = (jove_perm_obj_t) { .permissions = 0xFF, .obj = ctx.pcb }; + sysret = _syscall_handle_switch(&ctx); + + }else{ + //Could not find payload target in pcb rootdir. + klogf("Process %i tried to call syscall with bad target path %P : %s\n", + pcb_getpid(pcb), header->path, header->pathlen, errstr(errno)); + sysret = -errno; + } } - sysret = _syscall_handle_switch(&ctx); +remap_return: + message_remap(ctx.message.obj, (jove_owned_obj_t*)pcb_pagedir(pcb), message_vptr); release_return: lockstack_popall(&ctx.lockstack); diff --git a/sys/syscall_initrd_file.c b/sys/syscall_initrd_file.c index 8e34488..904039d 100644 --- a/sys/syscall_initrd_file.c +++ b/sys/syscall_initrd_file.c @@ -8,16 +8,17 @@ int s_syscall_initrd_file_name( jove_owned_obj_t *initrd_file, - jove_owned_obj_t *message) + jove_owned_obj_t *message, + void *message_data) { const char *filename = initrd_file_name(initrd_file); size_t filename_len = strlen(filename); - size_t bytes_left = message_len(message); + size_t bytes_left = 0x1000; size_t bytes_needed = filename_len + sizeof(struct syscall_initrd_file_name_ret); CHECK_TOOSMALL(bytes_needed, bytes_left, "Message is too small for file name."); - struct syscall_initrd_file_name_ret *payload = message_data(message); + struct syscall_initrd_file_name_ret *payload = message_data; payload->len = filename_len; memcpy(payload->c_str, filename, filename_len); @@ -34,6 +35,7 @@ int s_syscall_initrd_file_read( jove_owned_obj_t *initrd_file, jove_owned_obj_t *message, + void *message_data, size_t bytes_left, void *payload_data) { @@ -44,7 +46,7 @@ s_syscall_initrd_file_read( struct syscall_initrd_file_read *payload = payload_data; bytes_needed = payload->read_size; - bytes_left = message_len(message); + bytes_left = 0x1000; //Ensure that the message is big enough to hold the read file data. CHECK_TOOSMALL(bytes_needed, bytes_left, @@ -67,8 +69,7 @@ s_syscall_initrd_file_read( return -ETOOBIG; } - void *read_data = message_data(message); - memcpy(read_data, file_data + payload->start_index, payload->read_size); + memcpy(message_data, file_data + payload->start_index, payload->read_size); return 0; } @@ -79,7 +80,7 @@ _syscall_handle_initrd_file(syscall_context_t *ctx) case SYSCALL_INITRD_FILE_NAME: if(ctx->target.permissions & SYSCALL_PERM_INITRD_FILE_NAME) return s_syscall_initrd_file_name( - ctx->target.obj, ctx->message.obj); + ctx->target.obj, ctx->message.obj, (void*)ctx->header); return -EPERM; case SYSCALL_INITRD_FILE_SIZE: @@ -90,7 +91,7 @@ _syscall_handle_initrd_file(syscall_context_t *ctx) case SYSCALL_INITRD_FILE_READ: if(ctx->target.permissions & SYSCALL_PERM_INITRD_FILE_READ) return s_syscall_initrd_file_read( - ctx->target.obj, ctx->message.obj, ctx->bytes_left, ctx->payload); + ctx->target.obj, ctx->message.obj, (void*)ctx->header, ctx->bytes_left, ctx->payload); return -EPERM; default: return -EBADCALL; diff --git a/sys/syscall_message.c b/sys/syscall_message.c index 5edf33f..6c5fb8f 100644 --- a/sys/syscall_message.c +++ b/sys/syscall_message.c @@ -6,10 +6,6 @@ int _syscall_handle_message(syscall_context_t *ctx) { switch(ctx->header->callid) { - case SYSCALL_OBJDIR_OBJTYPE: - if(ctx->target.permissions & SYSCALL_PERM_OBJDIR_OBJTYPE) - return message_len(ctx->message.obj); - return -EPERM; default: return -EBADCALL; } |
