diff options
| -rw-r--r-- | arch/riscv64/kernel/proc.c | 14 | ||||
| -rw-r--r-- | include/arch/proc.h | 6 | ||||
| -rw-r--r-- | include/kmi/syscalls.h | 6 | ||||
| -rw-r--r-- | include/kmi/uapi.h | 177 | ||||
| -rw-r--r-- | src/orphanage.c | 2 | ||||
| -rw-r--r-- | src/uapi/dispatch.c | 4 | ||||
| -rw-r--r-- | src/uapi/ipc.c | 11 | ||||
| -rw-r--r-- | src/uapi/proc.c | 4 | ||||
| -rw-r--r-- | tests/ipc-req/init.c | 10 |
9 files changed, 139 insertions, 95 deletions
diff --git a/arch/riscv64/kernel/proc.c b/arch/riscv64/kernel/proc.c index aa33ec7..d3896c1 100644 --- a/arch/riscv64/kernel/proc.c +++ b/arch/riscv64/kernel/proc.c @@ -58,18 +58,18 @@ void run_init(struct tcb *t, vm_t fdt, vm_t initrd) unreachable(); } -void set_args(struct tcb *t, size_t n, struct sys_ret a) +void set_ret(struct tcb *t, size_t n, struct sys_ret a) { struct riscv_regs *r = (struct riscv_regs *)(t->regs) - 1; if (n >= 1) r->a0 = a.s; - if (n >= 2) r->a1 = a.a0; - if (n >= 3) r->a2 = a.a1; - if (n >= 4) r->a3 = a.a2; - if (n >= 5) r->a4 = a.a3; - if (n >= 6) r->a5 = a.a4; + if (n >= 2) r->a1 = a.id; + if (n >= 3) r->a2 = a.a0; + if (n >= 4) r->a3 = a.a1; + if (n >= 5) r->a4 = a.a2; + if (n >= 6) r->a5 = a.a3; } -struct sys_ret get_args(struct tcb *t) +struct sys_ret get_ret(struct tcb *t) { struct riscv_regs *r = (struct riscv_regs *)(t->regs) - 1; return SYS_RET6(r->a0, r->a1, r->a2, r->a3, r->a4, r->a5); diff --git a/include/arch/proc.h b/include/arch/proc.h index e2fae03..4afd6a9 100644 --- a/include/arch/proc.h +++ b/include/arch/proc.h @@ -20,14 +20,14 @@ #include <kmi/uapi.h> /** - * Attach argument data to thread. + * Attach argument data to thread, to be returned to userspace. * * @param t Thread that will run after return. * @param n How many of the arguments to attach. Might micro-optimize some * stuff. * @param a Arguments to attach. */ -void set_args(struct tcb *t, size_t n, struct sys_ret a); +void set_ret(struct tcb *t, size_t n, struct sys_ret a); /** * Get argument data attached to thread. @@ -38,7 +38,7 @@ void set_args(struct tcb *t, size_t n, struct sys_ret a); * @param t Thread to read data from. * @return Args associated with thread. */ -struct sys_ret get_args(struct tcb *t); +struct sys_ret get_ret(struct tcb *t); /** \todo Should these be in arch/tcb.h or something? */ diff --git a/include/kmi/syscalls.h b/include/kmi/syscalls.h index 2701bbc..e3d5dad 100644 --- a/include/kmi/syscalls.h +++ b/include/kmi/syscalls.h @@ -341,6 +341,9 @@ struct sys_ret { /** Status. */ sys_arg_t s; + /** Who responded */ + sys_arg_t id; + /** First argument. */ sys_arg_t a0; @@ -352,9 +355,6 @@ struct sys_ret { /** Fourth argument. */ sys_arg_t a3; - - /** Fifth argument. */ - sys_arg_t a4; }; #endif /* KMI_SYSCALLS_H */ diff --git a/include/kmi/uapi.h b/include/kmi/uapi.h index fa4aeae..95c7000 100644 --- a/include/kmi/uapi.h +++ b/include/kmi/uapi.h @@ -898,139 +898,180 @@ void handle_syscall(sys_arg_t syscall, sys_arg_t a, sys_arg_t b, #include <arch/proc.h> /** - * Set one argument to pass to thread when returning to userspace. + * Set one sys_ret value to pass to thread when returning to userspace. * - * @param t Thread whose arguments to set. - * @param a First argument. + * @param t Thread whose values to set. + * @param a First value. */ -#define set_args1(t, a) set_args(t, 1, SYS_RET1(a)) +#define set_ret1(t, a) set_ret(t, 1, SYS_RET1(a)) /** - * Set two arguments to pass to thread when returning to userspace. + * Set two sys_ret values to pass to thread when returning to userspace. * - * @param t Thread whose arguments to set. - * @param a First argument. - * @param b Second argument. + * @param t Thread whose values to set. + * @param a First value. + * @param b Second value. + */ +#define set_ret2(t, a, b) set_ret(t, 2, SYS_RET2(a, b)) + +/** + * Set three sys_ret values to pass to thread when returning to userspace. + * + * @param t Thread whose values to set. + * @param a First value. + * @param b Second value. + * @param c Third value. + */ +#define set_ret3(t, a, b, c) set_ret(t, 3, SYS_RET3(a, b, c)) + +/** + * Set four sys_ret values to pass to thread when returning to userspace. + * + * @param t Thread whose values to set. + * @param a First value. + * @param b Second value. + * @param c Third value. + * @param d Fourth value. + */ +#define set_ret4(t, a, b, c, d) set_ret(t, 4, SYS_RET4(a, b, c, d)) + +/** + * Set five sys_ret values to pass to thread when returning to userspace. + * + * @param t Thread whose values to set. + * @param a First value. + * @param b Second value. + * @param c Third value. + * @param d Fourth value. + * @param e Fifth value. + */ +#define set_ret5(t, a, b, c, d, e) set_ret(t, 5, SYS_RET5(a, b, c, d, e)) + +/** + * Set six sys_ret values to pass to thread when returning to userspace. + * + * @param t Thread whose sys_ret values to set. + * @param a First value. + * @param b Second value. + * @param c Third value. + * @param d Fourth value. + * @param e Fifth value. + * @param f Sixth value. */ -#define set_args2(t, a, b) set_args(t, 2, SYS_RET2(a, b)) +#define set_ret6(t, a, b, c, d, e, f) \ + set_ret(t, 6, SYS_RET6(a, b, c, d, e, f)) /** - * Set three arguments to pass to thread when returning to userspace. + * Set one argument to pass to userspace. Sets the ID to be zero, i.e. kernel. * * @param t Thread whose arguments to set. - * @param a First argument. - * @param b Second argument. - * @param c Third argument. + * @param s Status argument. */ -#define set_args3(t, a, b, c) set_args(t, 3, SYS_RET3(a, b, c)) +#define set_args1(t, s) \ + set_ret2(t, s, 0) /** - * Set four arguments to pass to thread when returning to userspace. + * Set two arguments to pass to userspace. Sets the ID to be zero, i.e. kernel. * * @param t Thread whose arguments to set. - * @param a First argument. - * @param b Second argument. - * @param c Third argument. - * @param d Fourth argument. + * @param s Status argument. + * @param a First generic argument. */ -#define set_args4(t, a, b, c, d) set_args(t, 4, SYS_RET4(a, b, c, d)) +#define set_args2(t, s, a) \ + set_ret3(t, s, 0, a) /** - * Set five arguments to pass to thread when returning to userspace. + * Set three arguments to pass to userspace. Sets the ID to be zero, i.e. kernel. * * @param t Thread whose arguments to set. - * @param a First argument. - * @param b Second argument. - * @param c Third argument. - * @param d Fourth argument. - * @param e Fifth argument. + * @param s Status argument. + * @param a First generic argument. + * @param b Second generic argument. */ -#define set_args5(t, a, b, c, d, e) set_args(t, 5, SYS_RET5(a, b, c, d, e)) +#define set_args3(t, s, a, b) \ + set_ret4(t, s, 0, a, b) /** - * Set six arguments to pass to thread when returning to userspace. + * Set four arguments to pass to userspace. Sets the ID to be zero, i.e. kernel. * * @param t Thread whose arguments to set. - * @param a First argument. - * @param b Second argument. - * @param c Third argument. - * @param d Fourth argument. - * @param e Fifth argument. - * @param f Sixth argument. + * @param s Status argument. + * @param a First generic argument. + * @param b Second generic argument. + * @param c Third generic argument. */ -#define set_args6(t, a, b, c, d, e, f) \ - set_args(t, 6, SYS_RET6(a, b, c, d, e, f)) +#define set_args4(t, s, a, b, c) \ + set_ret5(t, s, 0, a, b, c) /** - * Set one argument and return from uapi function. - * Essentially a beauty macro and slight micro-optimization, avoiding setting - * registers to zero when not required. + * Set five arguments to pass to userspace. Sets the ID to be zero, i.e. kernel. * * @param t Thread whose arguments to set. - * @param a First argument. + * @param s Status argument. + * @param a First generic argument. + * @param b Second generic argument. + * @param c Third generic argument. + * @param d Fourth generic argument. */ -#define return_args1(t, a) \ - {set_args1(t, a); return;} +#define set_args5(t, s, a, b, c, d) \ + set_ret6(t, s, 0, a, b, c, d) /** - * Set two arguments and return from uapi function. + * Set status to return from uapi function. + * Essentially a beauty macro and slight micro-optimization, avoiding setting + * registers to zero when not required. * * @param t Thread whose arguments to set. - * @param a First argument. - * @param b Second argument. + * @param s Status. */ -#define return_args2(t, a, b) \ - {set_args2(t, a, b); return;} +#define return_args1(t, s) \ + {set_args1(t, s); return;} /** - * Set three arguments and return from uapi function. + * Set one argument and status to return from uapi function. * * @param t Thread whose arguments to set. + * @param s Status. * @param a First argument. - * @param b Second argument. - * @param c Third argument. */ -#define return_args3(t, a, b, c) \ - {set_args3(t, a, b, c); return;} +#define return_args2(t, s, a) \ + {set_args2(t, s, a); return;} /** - * Set four arguments and return from uapi function. + * Set two arguments and status to return from uapi function. * * @param t Thread whose arguments to set. + * @param s Status argument. * @param a First argument. * @param b Second argument. - * @param c Third argument. - * @param d Fourth argument. */ -#define return_args4(t, a, b, c, d) \ - {set_args4(t, a, b, c, d); return;} +#define return_args3(t, s, a, b) \ + {set_args3(t, s, a, b); return;} /** - * Set five arguments and return from uapi function. + * Set three arguments and status to return from uapi function. * * @param t Thread whose arguments to set. + * @param s Status argument. * @param a First argument. * @param b Second argument. * @param c Third argument. - * @param d Fourth argument. - * @param e Fifth argument. */ -#define return_args5(t, a, b, c, d, e) \ - {set_args5(t, a, b, c, d, e); return;} +#define return_args4(t, s, a, b, c) \ + {set_args4(t, s, a, b, c); return;} /** - * Set six arguments and return from uapi function. + * Set four arguments and status to return from uapi function. * * @param t Thread whose arguments to set. + * @param s Status argument. * @param a First argument. * @param b Second argument. * @param c Third argument. * @param d Fourth argument. - * @param e Fifth argument. - * @param f Sixth argument. */ -#define return_args6(t, a, b, c, d, e, f) \ - {set_args6(t, a, b, c, d, e, f); return;} +#define return_args5(t, s, a, b, c, d) \ + {set_args4(t, s, a, b, c, d); return;} /** * Set all arguments and return from uapi function. @@ -1038,6 +1079,6 @@ void handle_syscall(sys_arg_t syscall, sys_arg_t a, sys_arg_t b, * @param t Thread whose arguments to set. * @param x Arguments to set. */ -#define return_args(t, x) {set_args((t), 6, (x)); return;} +#define return_args(t, x) {set_ret((t), 6, (x)); return;} #endif /* KMI_UAPI_H */ diff --git a/src/orphanage.c b/src/orphanage.c index 3ca016e..526affc 100644 --- a/src/orphanage.c +++ b/src/orphanage.c @@ -44,7 +44,7 @@ void unorphanize(struct tcb *t) alloc_stack(t); assert(init->callback); - set_args4(t, 0, t->tid, SYS_USER_ORPHANED, old_rid); + set_ret4(t, 0, t->tid, SYS_USER_ORPHANED, old_rid); set_return(t, init->callback); t->callback = init->callback; diff --git a/src/uapi/dispatch.c b/src/uapi/dispatch.c index ad53536..399f02b 100644 --- a/src/uapi/dispatch.c +++ b/src/uapi/dispatch.c @@ -23,7 +23,7 @@ SYSCALL_DEFINE0(noop)(struct tcb *t) { info("sys_noop\n"); - set_args1(t, OK); + return_args1(t, OK); } /** @@ -37,7 +37,7 @@ SYSCALL_DEFINE0(noop)(struct tcb *t) SYSCALL_DEFINE1(putch)(struct tcb *t, sys_arg_t a) { dbg("%c", (char)a); - set_args1(t, OK); + return_args1(t, OK); } void handle_syscall(sys_arg_t syscall, sys_arg_t a, sys_arg_t b, diff --git a/src/uapi/ipc.c b/src/uapi/ipc.c index 4a5a6d9..3d77639 100644 --- a/src/uapi/ipc.c +++ b/src/uapi/ipc.c @@ -97,7 +97,7 @@ static inline vm_t enter_rpc(struct tcb *t, struct sys_ret a, /* try to get rid of args as fast as possible to free up registers for * later use */ - set_args(t, 6, a); + set_ret(t, 6, a); ctx->exec = t->exec; ctx->pid = t->pid; @@ -239,7 +239,7 @@ static void leave_rpc(struct tcb *t, struct sys_ret a) t->regs = ctx->regs; /* again, get rid of args as fast as possible */ - set_args(t, 6, a); + set_ret(t, 6, a); struct tcb *r = get_tcb(ctx->pid); while (!r || !is_proc(r) || zombie(r)) { @@ -254,7 +254,10 @@ static void leave_rpc(struct tcb *t, struct sys_ret a) ctx = (struct call_ctx *)(rpc_stack) - 1; r = get_tcb(ctx->pid); - set_args1(t, ERR_NF); + /* equivalent to return_args1 but without returning so we can + * handle other cases in the loop. */ + /** @todo is set_args useful? */ + set_ret2(t, 0, ERR_NF); } if (orphan(t) && !is_rpc(t)) @@ -450,7 +453,7 @@ SYSCALL_DEFINE0(ipc_ghost)(struct tcb *t) return_args1(t, ERR_MISC); enable_irqs(); - leave_rpc(t, get_args(t)); + leave_rpc(t, get_ret(t)); } /** diff --git a/src/uapi/proc.c b/src/uapi/proc.c index 74f211c..c0fe5f0 100644 --- a/src/uapi/proc.c +++ b/src/uapi/proc.c @@ -43,7 +43,7 @@ SYSCALL_DEFINE5(create)(struct tcb *t, sys_arg_t func, * function? */ alloc_stack(c); - set_args5(c, c->tid, d0, d1, d2, d3); + set_ret5(c, c->tid, d0, d1, d2, d3); set_return(c, func); c->notify_id = t->notify_id; @@ -227,7 +227,7 @@ static void swap(struct tcb *t, struct tcb *s) notify(s, 0); /* no notifications, so get register state for new thread */ - return_args(s, get_args(s)); + set_ret(s, 6, get_ret(s)); } /** diff --git a/tests/ipc-req/init.c b/tests/ipc-req/init.c index 7f1c6aa..3439335 100644 --- a/tests/ipc-req/init.c +++ b/tests/ipc-req/init.c @@ -9,11 +9,11 @@ START(pid, tid, d0, d1, d2, d3) struct sys_ret r = sys_ipc_req4(1, 1, 2, 3, 4); printf("returned ipc req to ourselves\n"); check(r.s == OK, "not OK return\n"); - check(r.a0 == 1, "not OK response ID\n"); - check(r.a1 == 1, "not OK d0 response\n"); - check(r.a2 == 2, "not OK d1 response\n"); - check(r.a3 == 3, "not OK d2 response\n"); - check(r.a4 == 4, "not OK d3 response\n"); + check(r.id == 1, "not OK response ID\n"); + check(r.a0 == 1, "not OK d0 response\n"); + check(r.a1 == 2, "not OK d1 response\n"); + check(r.a2 == 3, "not OK d2 response\n"); + check(r.a3 == 4, "not OK d3 response\n"); /* try to request to non-existing proc */ r = sys_ipc_req0(200); |
