aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/riscv64/kernel/vmem.c6
-rw-r--r--src/proc.c2
-rw-r--r--src/uapi/ipc.c24
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)
diff --git a/src/proc.c b/src/proc.c
index b1682bf..920cab0 100644
--- a/src/proc.c
+++ b/src/proc.c
@@ -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. */