diff options
| author | Kimplul <kimi.h.kuparinen@gmail.com> | 2024-11-01 11:43:14 +0200 |
|---|---|---|
| committer | Kimplul <kimi.h.kuparinen@gmail.com> | 2024-11-01 12:47:57 +0200 |
| commit | 83ec75327c1ec35f25b6aee24f616a41858be539 (patch) | |
| tree | bd5c74baf3286beee930c7ba4b767c712b6afe6b | |
| parent | 8100eef0826e7fb182434979a9b139716b3637e1 (diff) | |
| download | kmi-83ec75327c1ec35f25b6aee24f616a41858be539.tar.gz kmi-83ec75327c1ec35f25b6aee24f616a41858be539.zip | |
move stack modifications to be earlier in rpc
| -rw-r--r-- | arch/riscv64/kernel/vmem.c | 6 | ||||
| -rw-r--r-- | src/proc.c | 2 | ||||
| -rw-r--r-- | src/uapi/ipc.c | 24 |
3 files changed, 16 insertions, 16 deletions
diff --git a/arch/riscv64/kernel/vmem.c b/arch/riscv64/kernel/vmem.c index bd7906b..4556593 100644 --- a/arch/riscv64/kernel/vmem.c +++ b/arch/riscv64/kernel/vmem.c @@ -605,6 +605,10 @@ stat_t setup_rpc_stack(struct tcb *t) vmflags_t flags = VM_V | VM_R | VM_W; /* note how VM_U is missing, userspace messing about will be done later */ + /* don't generate interrupt on first access, since it'll come from + * inside the kernel and we can't handle that */ + flags |= VM_A | VM_D; + pm_t page = alloc_page(MM_O1); if (!page) return ERR_OOMEM; @@ -751,7 +755,7 @@ void destroy_rpc(struct tcb *t) set_bits(*pte, vp_flags(VM_U)); } - t->arch.rpc_idx = ctx - 1; + t->arch.rpc_idx = ctx - 2; } void grow_rpc(struct tcb *t, vm_t top) @@ -58,8 +58,6 @@ stat_t init_proc(void *fdt, vm_t *proc_fdt, vm_t *proc_initrd) set_stack(t, t->rpc_stack - BASE_PAGE_SIZE); - /* allocate stacks etc after ELF file to make sure nothing of importance - * clashes */ stat_t ret = prepare_proc(t, get_init_base(fdt), 0); assert(ret == OK); diff --git a/src/uapi/ipc.c b/src/uapi/ipc.c index e380e1f..644abc2 100644 --- a/src/uapi/ipc.c +++ b/src/uapi/ipc.c @@ -43,23 +43,17 @@ enum ipc_flags { * * @param t Thread to migrate. * @param r Process to migrate to. - * @param s RPC stack regions to mark inaccessible. * @param flags What kind of IPC we're doing. */ -static inline void finalize_rpc(struct tcb *t, struct tcb *r, vm_t s, - enum ipc_flags flags) +static inline void finalize_rpc(struct tcb *t, struct tcb *r, vm_t s) { clone_uvmem(r->proc.vmem, t->rpc.vmem); + flush_tlb_all(); + set_return(t, r->callback); reference_thread(r); t->pid = r->rid; - if (is_set(flags, IPC_TAIL)) - reuse_rpc(t); - else - new_rpc(t); - - flush_tlb_all(); set_stack(t, s); } @@ -90,14 +84,18 @@ static inline vm_t enter_rpc(struct tcb *t, struct sys_ret a, set_ret(t, 6, a); if (!is_set(flags, IPC_TAIL)) { - /* if we're doing a tail call, we don't need to update any of - * these things */ ctx->rpc_stack = t->rpc_stack; t->rpc_stack = rpc_stack; ctx->exec = t->exec; ctx->pid = t->pid; ctx->eid = t->eid; ctx->notify = flags & IPC_NOTIFY; + new_rpc(t); + } + else { + /* if we're doing a tail call, we don't need to update any of + * the above things */ + reuse_rpc(t); } return rpc_stack - BASE_PAGE_SIZE; @@ -154,7 +152,7 @@ static __noreturn void __run_notify(struct tcb *t, struct tcb *r) SYS_RET5(0, t->tid, code, flags, t->eid), IPC_NOTIFY); - finalize_rpc(t, r, s, 0); + finalize_rpc(t, r, s); clear_bits(t->notify_flags, flags); @@ -319,7 +317,7 @@ static void do_ipc(struct tcb *t, if (!is_set(flags, IPC_FORWARD)) t->eid = t->pid; - finalize_rpc(t, r, s, flags); + finalize_rpc(t, r, s); /* I tested out passing the return values as arguments to * ret_userspace_fast, but apparently that causes enough stack shuffling * to be slower overall. */ |
