diff options
| author | Kimplul <kimi.h.kuparinen@gmail.com> | 2024-10-30 02:32:02 +0200 |
|---|---|---|
| committer | Kimplul <kimi.h.kuparinen@gmail.com> | 2024-10-30 02:32:02 +0200 |
| commit | 7a23d95b6e432170d6575f515616e5936d53c85e (patch) | |
| tree | afdc349124ca40c4903b534f750f18e8527bf7c5 | |
| parent | e7b5881903ad81efee63966e7d2c42524d465dfc (diff) | |
| download | kmi-7a23d95b6e432170d6575f515616e5936d53c85e.tar.gz kmi-7a23d95b6e432170d6575f515616e5936d53c85e.zip | |
bookkeeping
| -rw-r--r-- | arch/riscv64/kernel/vmem.c | 10 | ||||
| -rw-r--r-- | include/arch/proc.h | 7 | ||||
| -rw-r--r-- | include/arch/tcb.h | 6 | ||||
| -rw-r--r-- | include/arch/vmem.h | 12 | ||||
| -rw-r--r-- | include/kmi/bkl.h | 5 | ||||
| -rw-r--r-- | include/kmi/panic.h | 10 | ||||
| -rw-r--r-- | include/kmi/vmem.h | 8 | ||||
| -rw-r--r-- | src/panic.c | 5 | ||||
| -rw-r--r-- | src/tcb.c | 17 | ||||
| -rw-r--r-- | src/uapi/ipc.c | 2 | ||||
| -rw-r--r-- | src/vmem.c | 15 |
11 files changed, 87 insertions, 10 deletions
diff --git a/arch/riscv64/kernel/vmem.c b/arch/riscv64/kernel/vmem.c index 1648706..d66ddec 100644 --- a/arch/riscv64/kernel/vmem.c +++ b/arch/riscv64/kernel/vmem.c @@ -581,11 +581,13 @@ void copy_rpc_stack(struct tcb *t, struct tcb *c) * great. TODO: use the direct pointer to the rpc stack element? */ for (size_t i = 0; i < rpc_pages; ++i) { pm_t p1, p2; - stat_t ok1 = stat_vpage(t->rpc.vmem, RPC_STACK_BASE + BASE_PAGE_SIZE * i, - &p1, NULL, NULL); + stat_t ok1 = stat_vpage(t->rpc.vmem, + RPC_STACK_BASE + BASE_PAGE_SIZE * i, + &p1, NULL, NULL); - stat_t ok2 = stat_vpage(c->rpc.vmem, RPC_STACK_BASE + BASE_PAGE_SIZE * i, - &p2, NULL, NULL); + stat_t ok2 = stat_vpage(c->rpc.vmem, + RPC_STACK_BASE + BASE_PAGE_SIZE * i, + &p2, NULL, NULL); assert(ok1 == OK && ok2 == OK); memcpy((void *)p2, (void *)p1, BASE_PAGE_SIZE); diff --git a/include/arch/proc.h b/include/arch/proc.h index 7921e5c..b0f0944 100644 --- a/include/arch/proc.h +++ b/include/arch/proc.h @@ -127,6 +127,13 @@ __noreturn void run_init(struct tcb *t, vm_t fdt, vm_t initrd); * so I'm not too worried. */ __noreturn void ret_userspace_fast(); + +/** + * Return to userspace, restoring some registers. + * Mainly for returning from an ipc_resp, where the user is expected to save + * temporary registers on their own. + * Same as with \ref ret_userspace_fast(), skips canary checking. + */ __noreturn void ret_userspace_partial(); #endif /* KMI_ARCH_PROC_H */ diff --git a/include/arch/tcb.h b/include/arch/tcb.h index 8eddb07..18386d3 100644 --- a/include/arch/tcb.h +++ b/include/arch/tcb.h @@ -42,6 +42,12 @@ stat_t setup_rpc_stack(struct tcb *t); */ void destroy_rpc_stack(struct tcb *t); +/** + * Copy over contents in rpc stack from \p t to \p c. + * + * @param t 'Source'. + * @param c 'Destination'- + */ void copy_rpc_stack(struct tcb *t, struct tcb *c); /** diff --git a/include/arch/vmem.h b/include/arch/vmem.h index 0f06cc5..ad32519 100644 --- a/include/arch/vmem.h +++ b/include/arch/vmem.h @@ -167,11 +167,21 @@ struct vmem *create_vmem(); void use_vmem(struct vmem *b); /** - * Destroy virtual memory space. + * Completely destroy virtual memory space. + * Should only be called for ->proc.vmem, as it is the only one that is sure to + * own all nodes. * * @param b Virtual memory to destroy. */ void destroy_vmem(struct vmem *b); + +/** + * Destroy 'regular' virtual memory space. + * Should be called for ->rpc.vmem, as rpc can have some references that it + * doesn't own into ->proc.vmem, and this function is careful not to free those. + * + * @param b Virtual memory to destroy. + */ void destroy_rpcmem(struct vmem *b); /** diff --git a/include/kmi/bkl.h b/include/kmi/bkl.h index 8a56061..b77b08a 100644 --- a/include/kmi/bkl.h +++ b/include/kmi/bkl.h @@ -12,6 +12,11 @@ #include <kmi/lock.h> +/** + * Initialize Big Kernel Lock. + * In theory, the BKL being statically initialized to 0 should be enough, but + * this feels a bit safer. + */ void bkl_init(); /** Lock the Big Kernel Lock. */ diff --git a/include/kmi/panic.h b/include/kmi/panic.h index 121323c..0cfebc7 100644 --- a/include/kmi/panic.h +++ b/include/kmi/panic.h @@ -22,6 +22,16 @@ */ __noreturn void kernel_panic(void *pc, void *addr, long cause); +/** + * Call on some other, like userspace doing something that we currently can't + * deal with. Tries to reboot the system. Failing that, spin. + * Ideally registers and kernel state would be printed, but keep things simple + * for now. + * + * @param pc Address where fault occured. Should preferably be in the kernel. + * @param addr Possibly associated address. + * @param cause Possible error code associated with panic. Page fault, etc. + */ __noreturn void unhandled_panic(void *pc, void *addr, long cause); #endif /* KMI_PANIC_H */ diff --git a/include/kmi/vmem.h b/include/kmi/vmem.h index 9424e33..0f1832a 100644 --- a/include/kmi/vmem.h +++ b/include/kmi/vmem.h @@ -174,6 +174,14 @@ stat_t copy_uvmem(struct tcb *d, struct tcb *s); */ vmflags_t sanitize_uvflags(vmflags_t flags); +/** + * Handle page faults. + * If a page fault was to some legal address, the TLB is repopulated and the + * access is attempted again. Kind of like COW. + * Otherwise, the process gets killed (TODO) + * + * @param addr Address that caused a page fault. + */ void handle_pagefault(vm_t addr); #endif /* KMI_VMEM_H */ diff --git a/src/panic.c b/src/panic.c index afb598e..69247de 100644 --- a/src/panic.c +++ b/src/panic.c @@ -29,8 +29,9 @@ void kernel_panic(void *pc, void *addr, long cause) void unhandled_panic(void *pc, void *addr, long cause) { /* could be useful to print out register values as well? */ - error("thread %d unhandled panic at pc: %p with address %p and cause %lx\n", - cur_tcb()->cpu_id, pc, addr, cause); + error( + "thread %d unhandled panic at pc: %p with address %p and cause %lx\n", + cur_tcb()->cpu_id, pc, addr, cause); info("attempting to reboot\n"); @@ -90,6 +90,13 @@ static id_t __alloc_tid(struct tcb *t) return ERR_NF; } +/** + * Initialize thread that isn't bound to any parent process, i.e. it will become + * a process in itself. + * + * @param t Partially constructed tcb to construct further. + * @return OK/ERR_OOMEM. + */ static stat_t __init_free_thread(struct tcb *t) { if (!(t->proc.vmem = create_vmem())) @@ -102,7 +109,7 @@ static stat_t __init_free_thread(struct tcb *t) if (!(t->rpc.vmem = create_vmem())) { destroy_vmem(t->proc.vmem); - return NULL; + return ERR_OOMEM; } if (setup_rpc_stack(t)) { @@ -120,6 +127,13 @@ static stat_t __init_free_thread(struct tcb *t) return OK; } +/** + * Initialize thread that is bound to some parent process. + * + * @param p Parent tcb. + * @param t Partially constructed tcb to construct further. + * @return OK/ERR_OOMEM. + */ static stat_t __init_owned_thread(struct tcb *p, struct tcb *t) { t->eid = p->rid; @@ -220,7 +234,6 @@ struct tcb *create_proc(struct tcb *p) * Destroy data associated with thread. * * @param t Thread whose data to destroy. - * @return \ref OK. */ static void __destroy_thread_data(struct tcb *t) { diff --git a/src/uapi/ipc.c b/src/uapi/ipc.c index 6e33165..6f6862e 100644 --- a/src/uapi/ipc.c +++ b/src/uapi/ipc.c @@ -71,7 +71,7 @@ static inline vm_t enter_rpc(struct tcb *t, struct sys_ret a, { /* reuse current rpc stack location if we're being kicked */ vm_t rpc_stack = (is_set(flags, IPC_TAIL) && is_rpc(t)) - ? t->rpc_stack : rpc_position(t); + ? t->rpc_stack : rpc_position(t); struct call_ctx *ctx = (struct call_ctx *)(rpc_stack) - 1; t->regs = (vm_t)ctx; @@ -64,6 +64,14 @@ static stat_t __copy_mapped_region(struct tcb *d, struct tcb *s, return res; } +/** + * Reference shared memory, creating a link between the referrer and owner. + * + * @param d 'Owner' of \p orig. + * @param s Referrer of \p ref. + * @param ref Address of shared memory reference in \p s. + * @param orig Address of shared memory in \p d. + */ static void reference_mem(struct tcb *d, struct tcb *s, vm_t ref, vm_t orig) { struct mem_region *src = find_used_region(&s->uvmem.region, orig); @@ -81,6 +89,13 @@ static void reference_mem(struct tcb *d, struct tcb *s, vm_t ref, vm_t orig) static void __free_mapping(struct tcb *t, struct mem_region *m); +/** + * Unreference memory region at address \p addr. + * Also unreferences owning process. + * + * @param s Reference holder of \p addr. + * @param addr Address to unreference. Or would dereference be better? + */ static void unreference_mem(struct tcb *s, vm_t addr) { struct mem_region *src = find_used_region(&s->uvmem.region, addr); |
