aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKimplul <kimi.h.kuparinen@gmail.com>2024-08-22 13:19:50 +0300
committerKimplul <kimi.h.kuparinen@gmail.com>2024-08-22 13:19:50 +0300
commit66b39eb7ce9605cbb70defdca7f0eb144855ddcd (patch)
tree702bd65c46591052f40987c848b664a84057f7e7
parent4168cca8124acdbd1866eb87810efe1cfe16903c (diff)
downloadkmi-66b39eb7ce9605cbb70defdca7f0eb144855ddcd.tar.gz
kmi-66b39eb7ce9605cbb70defdca7f0eb144855ddcd.zip
change sys_ret handling to always include id
-rw-r--r--arch/riscv64/kernel/proc.c14
-rw-r--r--include/arch/proc.h6
-rw-r--r--include/kmi/syscalls.h6
-rw-r--r--include/kmi/uapi.h177
-rw-r--r--src/orphanage.c2
-rw-r--r--src/uapi/dispatch.c4
-rw-r--r--src/uapi/ipc.c11
-rw-r--r--src/uapi/proc.c4
-rw-r--r--tests/ipc-req/init.c10
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);